Automating Test Equipment (lab gear) with Python

I’ve just shared a new tutorial: Automating Test Equipment with Python.” Forget manual experiments - Now you can script your experiment and have it run while you’re out to lunch!

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.

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.

Read more


I saw the YouTube video and was quite impressed as I have been looking for a similar thing. I have a question. Using this Programmable Power Source, can we vary the current using the python script? Like if we operate the power supply in Constant Current mode, and in a for loop we increment the current each time, will it also increase in real time in the circuit? I am absolutely new to this stuff so please give your answer in very very simple terms.


Absolutely! Check out the Programming Manual.

On page 2-53 is the command to set CC mode, and from page 2-82 are the SOURce commands to control the setpoints.


Hi Michael,

I saw your video and I wanted to thank you for your work.

I am also trying to automate some instruments with python via TCP IP using python Socket Library.
Now, I am trying to send commands to a Downconverter (from NARDA Miteq, 9800series with ethernet port). I have the Manual and Documentation but I am not able to make the connection with Python. When I try to ping the IP, the connection is successful.

Can you please give me any idea?

Best Regards,


Hi @Loren208431 - welcome to the forums!
Can you share your code and some screenshots of what the results are?
Links to any documentation will help too


Hi Michael, thank you for your reply.

Please find attached a short code example of how I am trying to connect and send commands and the manual.

I am trying this method with Keysight equipment and it’s working fine.

9800SERIESM.pdf (2.6 MB)


What about the output of your program? At what line is it failing?
Line 5 on connection?
Line 11 on the first command issued?

Looking at the command code summary, it looks like you may be issuing an invalid command: *IDN.
In the tutorial we issue this command because it is documented in the manual for the equipment being used.

From the document you attached, here’s the command summary for your device:

As a “Hello World,” you ought to be able to query ?EAD and have the unit respond with its ethernet parameters, which I assume should look just like the IP address of the unit.

Alternatively, you could query ?NAM and have the unit respond with it’s device name

Be sure to only issue commands that are valid for your specific device - not necessarily a direct copy-paste from the tutorial article. This tutorial is a bit more esoteric that most of our articles, and lots of manufacturers implement a different command set. You will have to identify where your device is different and modify the code to suit.

Let us know how you go after modifying the script! :smiley:


Hi Michael,

Thank you for your reply!

I am getting an error at line 5 on connection. ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it.

The device ip address is :
I can access the web interface of the device but maybe the port that I provide is wrong.
(instrument is on remote mode)

1 Like

Hi sir,
I am trying to write a program to automate the testing process using an ATE to test various radiosets. Can you tell me if you have any other posts regarding controlling ATEs. It would be great help.

I am trying to replicate your exercise but I am using different instruments than yours.
My power supply is a kikusui and the multimeter is an Agilent 34401A.
The problem I’m having is in the line
‘’‘vMeasured = float ( dmm . query ( ‘:MEASure:VOLTage:DC?’ ) )’‘’
the console returns me this message
‘’‘pyvisa.errors.VisaIOError: VI_ERROR_TMO (-1073807339): Timeout expired before operation completed’‘’
Could you help me? I think that the problem is in query order, but before , when i do a ‘’‘DMM.query(“*IDN?”)’‘’ it returns a correct string.

Hey @Roberto240446 - welcome to the forums :smiley:
It looks like your instrument may use a different syntax. Remember that the guide can only demonstrate commands on a specific device, and you should refer to the manufacturer’s documentation for your own instrument.

Referring to page 118 of the programming manual for your instrument:

Perhaps you should try removing the leading colon from the command string, eg. this

vMeasured = float ( dmm.query ( ':MEASure:VOLTage:DC?' ) )

should be changed to this

vMeasured = dmm.query('MEASure:VOLTage:DC?')

I removed the float() to just simplify things for sanity checking.

I hope its as simple as that! Let us know how you travel with your project :slight_smile:

1 Like

Thank you very much Michael, I tried but got the same result. I forgot to tell you when I send the command on the multimeter screen display an error message.

1 Like

@Roberto240446 what message is shown on the DMM screen?

When troubleshooting problems like this I like to reduce the complexity. I only increase the complexity once I have a basic functionality. It helps to be systematic in our approach.

Try reducing the script’s complexity - there are two instruments and multiple commands. What happens if you:

  • remove the power supply and only issue commands to the DMM?
  • Query the ID multiple times? This will prove the interface is set up correctly.
  • insert a short delay between each command?
  • attempt some other command like the :FUNCtion command? Can you change the multimeter between two different measurement functions eg. VDC and Resistance? Can you set a manual range?

It looks like you attempt to measure DC voltage before setting the measurement function. The DMM probably defaults to the DC voltage function on startup - though it might be best practice to always set DC voltage mode explicitly in code before attempting any measurements.


Hello Micheal,

Thank you for the process of automating test equipment with python.
I am working on the same but controlling a RIGOL DL3021A programmable DC load. I want to pass a list of power values in the POWER MODE but it seems I cant proceed with the while loop. If you could help me with this I would be grateful since in the conclusion, you highlighted testing the same equipment I have. Below is my script;

Thank you.

Kind regards;

hi @Jacob265487 - it looks like your comment Write results to console is not actually commented and will throw an error
what output do you see in the shell?

1 Like

Hello Michael;

Thanks for the reply. I made an error earlier. Anyway I commented that part so there is no error. However, in the while loop, I create 30 steps in the list function. I intend to pass a single value for each step. For instance, I create numbers from 1 to 20 and step 1 is to be assigned 1, step 2 a 2, step 3 a 3… until step 20 with a 20. When I execute the code, the instrument assigns the same value 2 for all steps. Unless there is another function I can use instead of the LIST function for the device. Therefore am kindly seeking your guidance in rectifying the problem.

Attached is the rectified code;

Shell output;

Device display;

Thank you.


@Jacob265487 the .write() method is expecting a string, so you should be formatting your string just like you do for your print statement.
ie. you are actually passing the characters for “P[i]” instead of the numeric value.

dl.write(":SOUR:LIST:LEV i,P[i]") # looks invalid to me

# try this instead
setpoint_string = f":SOUR:LIST:LEV {i}, {P[i]:.2f}"

Hello Michael;

Thank you for the reply and guidance. I included your line of code and it is actually working perfectly.
Let me continue making some tests. Incase of any anomaly, I will request for your expertise.

I am sincerely grateful, thanks again.

Kind regards;


Great to hear @Jacob265487 :slight_smile:
I’m stoked for you, and stoked I also got to sneak in a Python “F-string” example, which is my preferred, compact way of formatting strings.

1 Like