Automating Test-Equipment with Python

Updated 24 September 2021

The full example-code is reproduced at the bottom of this article.

Performing manual measurements (in bulk) is for suckers and undergraduate students. Thankfully, most lab gear comes with a digital interface like USB or Serial and you can issue commands through these interfaces to control your equipment - the same as if you were pushing buttons on the front panel. Take a power supply for example - you could issue a sequence of commands to:

  • set the output voltage to 5V
  • set the current limit to 1 Amp
  • Enable the output
  • read-back the actual current being supplied

Every action that we, the operator, can perform could also be performed by a command. Write a script that sequences these commands in the right order and you have an automated test procedure. Now we're talking! Better still, a script can co-ordinate a test across multiple devices; you can drive a power supply and read an oscilloscope in the same script. 

In this article, I'll demonstrate an automated test with a power supply and multimeter. We'll connect the equipment, set voltages, perform measurements and even do some datalogging. You may not have the same gear, but the commands we'll be using are an industry standard - across different brands, the commands are the same or very similar.

Of course, we'll be writing a bit of Python code - If you're unfamiliar with Python, Tim has created loads of tutorials to get you started.

lab-gear-physical-interface

Interfacing options on the rear-panel of a Rigol DP832 Power Supply. It is common for lab-gear to provision physical interfaces which require a license-purchase to unlock. It seems that with Rigol gear, the USB functionality is always included - Nice! In this case to use the LAN port would require purchasing the more feature-rich DP832A model, or individually purchasing a LAN-connectivity license from Rigol.

Contents


Preparation

Install Packages

PyVISA is a Python package that enables you to control your lab-gear independently of the physical interface (e.g. GPIB, RS232, USB, Ethernet).

To install PyVISA for Python 3.6+ run this command:

pip3 install -U pyvisa

We also have to install the NI-VISA backend which the PyVISA package depends on.

Get programming manuals

We need to know what commands our instruments accept. You can generally find the programming manual for a device on the manufacturer's website - look for a documentation section on an item's product page. For example, here's how I found our multimeter's programming manual on Rigol's website

find-a-progamming-manual


Hello, World

Power your equipment and connect to your computer via USB. 

connect-power-supply-to-computer-hello-world

For a quick example, to query the self-identification of a Rigol DP832 power supply connected via USB is as simple as 3 lines of code. Run the Python shell and enter the following:

>>> import pyvisa
>>> rm = pyvisa.ResourceManager()
>>> rm.list_resources()
('USB0::0x1AB1::0x0E11::DP8C1234567890::INSTR', 'ASRL1::INSTR', 'ASRL10::INSTR')
>>> psu = rm.open_resource('USB0::0x1AB1::0x0E11::DP8C1234567890::INSTR')
>>> print(psu.query("*IDN?"))
RIGOL TECHNOLOGIES,DP832,DP8C1234567890,00.01.16

Line-by-line, we:

  • import the package
  • create a resource manager
  • list the available VISA resources - yours will look different here
  • copy the resource ID and open it,
  • and finally, query the ID - which returns a string

the list_resources() function is useful for acquiring the USB device ID - we need that for open_resource()


Example Experiment: Automating a Power Supply and Multimeter

Let's create an automated test. In this experiment I'll be driving the output of a Rigol DP832 power supply, (programming manual) and performing measurements with a Rigol DM-3058E bench multimeter (programming manual): It's worth reiterating - while you may have different gear, the philosophy and command structure will be the same.

We'll step through the code section-by-section here, or; skip ahead to the final code.

experiment-illustration

Step 1: Initialise Multimeter

It's important to set your gear to a known state during initialisation. The following script performs the setup we've already seen for both multimeter and power supply, and includes imports for sleep and os - these will be useful later. All we'll do so far is set the multimeter function to measure DC voltage.

import pyvisa
from time import sleep # for delays
import os # for datalogging rm = pyvisa.ResourceManager() # List all connected resources print("Resources detected\n{}\n".format(rm.list_resources())) supply = rm.open_resource('USB0::0x1AB1::0x0E11::DP1234567890::INSTR') # Put your device IDs here dmm = rm.open_resource('USB0::0x1AB1::0x09C4::DM1234567890::INSTR') # Setup Digital MultiMeter in DC Voltage mode dmm.write(':FUNCtion:VOLTage:DC')

Finding the right command to issue is just a matter of diving into the multimeter's programming manual. The layout and naming is reasonably intuitive with descriptive commands.

I test this script by manually setting my meter to another mode (eg. current) and running the script. If everything is successful the meter should switch back to DC-Voltage mode.

Step 2: Initialise Power Supply

Add the following two lines to initialise the power supply to a known state: APPLy at Channel 1: 0 Volts, 0.2 Amps with the OUTPut off. (from the power supply's programming manual)

# Setup the power supply 0V, 200mA
supply.write(':OUTP CH1,OFF')   # start OFF - safe :)
supply.write(':APPL CH1,0,0.2') # apply 0V, 0.2A

We can test the power supply code by setting setting Channel 1 to some other setpoint and making sure our script updates the setpoint as expected.

Step 3: Increase Voltage, Collect Data

Let's step the output-voltage from 0 to 10V in 0.5V steps. First, we need to enable the Channel 1 output. Then, create a loop to step from 0 to 10. The loop variable will be our voltage setpoint. 

We'll use the loop variable inside the supply's APPLy command - since the variable is a number, we pass it through str() to convert it to a string, and concatenate that with the rest of the command.

Measuring voltage with the multimeter is as simple as issuing a query. Notice how query commands end with a question mark. Queries also return strings, so we pass the result through float() to convert to a number - useful if we want to do math with the data later.

The print() command logs the test results to the console.

Once the test is complete (the loop has finished), we reset the power supply to a safe off-state.

Add the following to your script:

# Run the test
supply.write(':OUTP CH1,ON')
v = 0
while v <= 10.0: # sweep voltage up to 10V
    supply.write(':APPL CH1,' + str(v) + ',0.2')            # Set the voltage
    sleep(0.5)
    vMeasured = float( dmm.query(':MEASure:VOLTage:DC?') )  # measure the voltage

    # Write results to console
    print("{}  {}".format(v, vMeasured))

    v += 0.5

# Test complete. Turn supply off and zero the setpoints
supply.write(':OUTP CH1,OFF')
supply.write(':APPL CH1,0,0')

If everything goes well, your console should log the power-supply setpoint on the left, and the multimeter's measurement on the right.

datalogging-to-console

Nice! We just did an experiment! We have a power supply stepping through some voltage range, and we're using a 5 1/2 digit multimeter to measure the output accuracy. You could copy this raw data into a spreadsheet and plot to your heart's content.

It makes sense to have Python do the work in saving our results to a file though - let's have our script log the results to a file.

Step 4: Datalogging

I've added a time-stamped filepath variable. This will be used to create a file with the current date and time in the format "YYYY-MM-DD_hhmm.csv"

I've added a section in the loop that opens the file and appends measurements. The first time the file is opened, it doesn't exist yet - we can check for this case by checking if the file-size is zero. If so, we can write in a nicely formatted header row to give our data columns some context.

This is the final version of the code

import pyvisa
import time
from time import sleep
import os

# Datalogging: create a time-stamped file
dateString = time.strftime("%Y-%m-%d_%H%M")
filepath = "./" + dateString + ".csv"

rm = pyvisa.ResourceManager()
# List all connected resources
print("Resources detected\n{}\n".format(rm.list_resources()))

supply = rm.open_resource('USB0::0x1AB1::0x0E11::DP1234567890::INSTR') # Put your device IDs here
dmm = rm.open_resource('USB0::0x1AB1::0x09C4::DM1234567890::INSTR')


# Setup Digital MultiMeter in DC Voltage mode
dmm.write(':FUNCtion:VOLTage:DC')

# Setup the power supply 0V, 200mA
supply.write(':OUTP CH1,OFF')   # start OFF - safe :)
supply.write(':APPL CH1,0,0.2') # apply 0V, 0.2A

# Run the test
supply.write(':OUTP CH1,ON')
v = 0
while v <= 10.0: # sweep voltage up to 10V
    supply.write(':APPL CH1,' + str(v) + ',0.2')            # Set the voltage
    sleep(0.5)
    vMeasured = float( dmm.query(':MEASure:VOLTage:DC?') )  # measure the voltage

    # Write results to console
    print("{}  {}".format(v, vMeasured))

    # Write results to a file
    with open(filepath, "a") as file:
        if os.stat(filepath).st_size == 0: #if empty file, write a nice header
            file.write("Setpoint [V], Measured [V]\n")
        file.write("{:12.2f},{:13.5f}\n".format(v, vMeasured)) # log the data
    file.close()

    v += 0.5


# Test complete. Turn supply off and zero the setpoints
supply.write(':OUTP CH1,OFF')
supply.write(':APPL CH1,0,0')

I've skipped ahead a bit with the nuances of handling files and using the time package. If you're curious, read the docs for os and time.

When you run the script, you'll see a .csv file appear in the same directory. After running the experiment, the contents of the file will look something like this:

datalogging-data-file

How nice! We have a data file with column headers, and constant-width rows make it easy to read. Make the rows constant width by playing with the file.write() formatting. For example: Setpoint [V] is 12 characters long, so to match the data to this width (with two decimal places) the format string is {12.2f}.


Conclusion

testing-a-power-supply

It's pretty unlikely that you will have the same instruments to follow this guide exactly - but that's ok. Regardless of what instruments you are working with, the process will be the same: First, establish a connection with some kind of Hello, World; then, grow your script - testing each new function as you go.

This example isn't too long, but it sure covers a lot of ideas: driving test-gear, printing formatted strings, run loops, and perform file operations. While the experiment we performed was rather simple, it doesn't take too much imagination to see how this can scale. There could be a Device Under Test connected between the power supply and multimeter. What's more, you could include more of test equipment; I recently tested a power-supply module with this tower of test gear: two multimeters, a power supply, an electronic load and an oscilloscope - all controlled by a single script! Magic!

In this example, we've been directly writing the low-level commands. If you find yourself doing this a lot, you may want to write a Python class for your instrument, to make coding faster. 

As always, if you found this tutorial interesting or helpful, we'd love to hear from you! If you have any questions or uncertainties, start the conversation below! We're full time makers, and here to help.

Happy coding!

Have a question? Ask the Author of this guide today!

Please enter minimum 20 characters

Your comment will be posted (automatically) on our Support Forum which is publicly accessible. Don't enter private information, such as your phone number.

Expect a quick reply during business hours, many of us check-in over the weekend as well.

Comments


Loading...
Feedback

Please continue if you would like to leave feedback for any of these topics:

  • Website features/issues
  • Content errors/improvements
  • Missing products/categories
  • Product assignments to categories
  • Search results relevance

For all other inquiries (orders status, stock levels, etc), please contact our support team for quick assistance.

Note: click continue and a draft email will be opened to edit. If you don't have an email client on your device, then send a message via the chat icon on the bottom left of our website.

Makers love reviews as much as you do, please follow this link to review the products you have purchased.