Write a Control Program
Hardware Control supplies a collection of widgets and instrument drivers for controlling instruments. This guide will walk you through setting up a simple control program using Hardware Control.
1. Import Hardware Control
Once installed (see installation instructions if you need help), you can import Hardware Control with the following statement:
import hardware_control as hc
Now you can access any instrument with hc.instruments.<instrument_class_name> and all other
classes, including the user interfaces, with hc.gui.<class_name>.
2. Create an App Class
Hardware Control uses Qt to create windows and graphics. Qt applications expect the user to create a class that inherits from QMainWindow. To create your Hardware Control program, you must also create a class and inherit from HCMainWindow, Hardware Control’s main window class which inherits from QMainWindow. The class would start off looking like:
class DemoProgram(hc.HCMainWindow):
def __init__(self, app):
super().__init__(app)
# code to define the GUI
A MainWindow requires a QT-app class object as an argument. HCMainWindow will automatically create an QT-app class object, but you can also define it explicitly as we will do below.
3. Create and Add Instruments
Your program will focus on three main objectives: using instrument drivers to communicate with instruments, using frontend GUI interfaces that contain widgets and GUI elements to let you interact with your instrument, and adding these widgets and GUI elements to the main window.
Create an instrument driver
To create an instrument driver, find the appropriate instrument class and initialize it with an instrument name and the physical instrument’s connection address. The type of address will change depending on the instrument class. Most instrument drivers accept IP addresses, but others use alternative protocols such as USB, MODBUS or GPIB. You will need to check your instrument’s documentation to make sure you configure it correctly. We then connect the instrument to the main app via the add_instrument function.
self.app.add_instrument(hc.instruments.Keysight_4000X("scope", "192.168.0.2"))
Create a Control Widget
The control widget or frontend will show the data of the instrument to the user and provide controls to change values in the instrument. To create the control widget, create an class instance of the control widget class and pass the app and the name of the instrument to it.
self.scope_wdgt = hc.gui.Oscilloscope(app, "scope")
Add Widget to Layout
Finally, you must add the control widget to a layout. Qt offers multiple ways for arranging layouts, but in this example we will be using QGridLayout. To add your widget to a layout, you must create the layout object, then use
addWidget()to add your control widget to the layout at the specified position.# Create layout, add oscilloscope to row=0, column=0 self.main_layout = QGridLayout() self.main_layout.addWidget(self.scope_wdgt, 0, 0)
Putting together all three steps is how you add an instrument to your control program. By repeating these steps, you can add multiple instruments and build complicated control programs with minimal code.
4. Prepare your Window to Display
You need to tell your window what to display and when. An easy way to do this is
to create a new QWidget, Qt’s base widget class, and set it to use the layout
that contains your control widgets. You can then set this new QWidget to be the
central widget for your main window. The last thing you need to do is add a call to
self.show() at the end of your __init__() function to tell Qt to display the
window.
self.main_widget = QWidget(self)
self.main_widget.setLayout(self.main_layout)
self.setCentralWidget(self.main_widget)
self.show()
5. Create Instance of Your Class and App
The next step is to create an instance of your class. To do this, you
can pass in an App object. Hardware Control provides it’s own version
of an App class which facilitates communication between instruments,
along with a number of other features such as centralized data
collection and menu bars. Create an instance of App and pass it to the
class you defined for your program. Alternatively, the app instance
can also be created automatically if you set app to None.
app = hc.App()
demo_prog = DemoProgram(app)
6. Execute Program
To run your program, just call sys.exit(app.exec_())!
A complete sample program could look like this:
# Import required modules
from PyQt6.QtWidgets import QGridLayout, QWidget
import sys
import hardware_control as hc
# Create class for program
class DemoProgram(hc.HCMainWindow):
def __init__(self, app):
super().__init__(app)
# Create an oscilloscope instrument driver
self.app.add_instrument(hc.instruments.Keysight_4000X("scope", "192.168.0.2"))
# Create an oscilloscope control widget for the instrument
self.scope_wdgt = hc.gui.Oscilloscope(self.app, "scope")
# Create layout and add oscilloscope widget to row=0, column=0
self.main_layout = QGridLayout()
self.main_layout.addWidget(self.scope_wdgt, 0, 0)
# Set 'main_layout' to be displayed
self.main_widget = QWidget(self)
self.main_widget.setLayout(self.main_layout)
self.setCentralWidget(self.main_widget)
# Indicate that the window is ready to show
self.show()
# This function will create and run the program class
if __name__ == "__main__":
# Create a Hardware Control App
app = hc.App(dummy=True) # will always run in dummy mode and not connect to any instrument
# Create an instance of my class using 'App'
demo_prog = DemoProgram(app)
# Execute the program
sys.exit(app.exec_())
Note that we enforce dummy mode in this program, which enables you to run and test the program without having the instrument hardware actually connected to your computer.
You can find more examples on how to use hardware control in the
example directory.