使用 Python 实现自动化测试设备
手动(批量)测量是新手和本科生的专利。好在大多数实验室设备都配备了 USB 或串口等数字接口,您可以通过这些接口发出命令来控制设备——就像按前面板上的按钮一样。以电源为例,您可以发出一系列命令来执行以下操作:
- 将输出电压设置为5V
- 将电流限制设置为 1 安培
- 启用输出
- 读回 实际供应的电流
我们操作员能够执行的每个操作,都可以由命令执行。 编写一个脚本,将这些命令按正确的顺序排列,您就拥有了一个自动化测试程序。现在我们开始讨论!更棒的是,一个脚本可以协调跨多个设备的测试;您可以在同一个脚本中驱动电源并读取示波器的数据。
在本文中,我将演示如何使用电源和万用表进行自动化测试。我们将连接设备、设置电压、进行测量,甚至进行一些数据记录。您可能没有相同的设备,但我们使用的命令是行业标准——不同品牌的命令相同或非常相似。
当然,我们会编写一些 Python 代码 -如果您不熟悉 Python,Tim 已经创建了大量教程来帮助您入门。

Rigol DP832 电源后面板上的接口选项。实验室设备通常会提供物理接口,但需要购买许可证才能解锁。Rigol 设备似乎始终包含 USB 功能——太棒了!在这种情况下,要使用 LAN 端口,需要购买功能更丰富的 DP832A 型号,或者单独从 Rigol 购买 LAN 连接许可证。
内容
准备
安装软件包
PyVISA是一个 Python 包,使您能够独立于物理接口(例如 GPIB、RS232、USB、以太网)控制实验室设备。
要安装适用于 Python 3.6+ 的 PyVISA,请运行以下命令:
pip3 install -U pyvisa
我们还必须安装 PyVISA 包所依赖的NI-VISA 后端。
获取编程手册
我们需要知道我们的仪器接受哪些命令。通常,您可以在制造商的网站上找到设备的编程手册——请在产品页面上查找文档部分。例如,我在Rigol 网站上找到了我们万用表的编程手册,如下所示

你好世界
为您的设备供电并通过 USB 连接到您的计算机。

举个简单的例子,查询通过 USB 连接的Rigol DP832 电源的自我识别信息只需 3 行代码。运行 Python shell 并输入以下内容:
>>> 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
我们逐行进行如下操作:
- 导入包
- 创建资源管理器
- 列出可用的 VISA 资源 - 您的资源在这里看起来会有所不同
- 复制资源ID并打开,
- 最后,查询 ID - 返回一个字符串
list_resources ()函数对于获取 USB 设备 ID 很有用 - 我们需要它来执行open_resource()
示例实验:自动化电源和万用表
让我们创建一个自动化测试。在这个实验中,我将驱动Rigol DP832 电源(编程手册)的输出,并使用Rigol DM-3058E 台式万用表 (编程手册)进行测量:值得重申的是——虽然你的设备可能不同,但原理和命令结构是相同的。
我们将在这里逐段地介绍代码,或者直接跳到最终的代码。

步骤 1:初始化万用表
在初始化期间,务必将设备设置为已知状态。以下脚本执行我们已经见过的万用表和电源的设置,并包含睡眠和操作系统的导入——这些导入稍后会用到。目前为止,我们只需将万用表功能设置为测量直流电压即可。
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')
只需深入研究万用表的编程手册,即可找到要发出的正确命令。其布局和命名相当直观,并带有描述性命令。
我手动将电表设置为其他模式(例如电流模式)并运行脚本来测试此脚本。如果一切顺利,电表应该会切换回直流电压模式。
步骤2:初始化电源
添加以下两行将电源初始化为已知状态:通道 1 处的APPLy :0 伏,0.2 安培,OUTPut关闭 。(来自 电源的编程手册)
# 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
我们可以通过将通道 1 设置为其他设定点并确保我们的脚本按预期更新设定点来测试电源代码。
步骤3:增加电压,收集数据
让我们将输出电压从 0V 步进到 10V,步长为 0.5V。首先,我们需要启用通道 1 的输出。然后,创建一个循环,将输出电压从 0 步进到 10。循环变量将是我们的电压设定值。
我们将在供应的APPLy命令中使用循环变量 - 因为该变量是一个数字,我们通过 str() 将其转换为字符串,然后将其与命令的其余部分连接起来。
使用万用表测量电压非常简单,只需发出查询即可。请注意,查询命令以问号结尾。查询也返回字符串,因此我们将结果传递给float()函数,转换为数字——如果我们稍后想对数据进行数学运算,这将非常有用。
print()命令将测试结果记录到控制台。
测试完成后(循环结束),我们将电源重置为安全关闭状态。
将以下内容添加到您的脚本中:
# 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')
如果一切顺利,您的控制台应该在左侧记录电源设定点,在右侧记录万用表的测量值。

太棒了!我们刚刚做了个实验!我们有一个电源,电压范围在某个范围内,我们正在用一个五位半万用表测量输出精度。你可以把这些原始数据复制到电子表格里,然后根据自己的喜好绘制图表。
让 Python 将我们的结果保存到文件中是有意义的 - 让我们的脚本将结果记录到文件中。
步骤4:数据记录
我添加了一个带时间戳的文件路径变量。它将用于创建一个包含当前日期和时间的文件,格式为“YYYY-MM-DD_hhmm.csv”。
我在循环中添加了一个部分,用于打开文件并附加测量值。第一次打开文件时,文件尚不存在——我们可以通过检查文件大小是否为零来检查。如果是,我们可以写入一个格式良好的标题行,为数据列提供一些上下文信息。
这是代码的最终版本
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')
我略过了处理文件和使用 time 包的细微差别。如果你感兴趣,可以阅读os和time的文档。
运行脚本时,您将看到同一目录中出现一个 .csv 文件。运行实验后,文件的内容将如下所示:

太棒了!我们有一个带有列标题的数据文件,等宽的行使其易于阅读。通过调整 file.write() 格式,使行宽保持恒定。例如:设定点 [V]的长度为 12 个字符,因此为了将数据匹配到这个宽度(保留两位小数),格式字符串应为 {12.2f}。
结论
您不太可能拥有完全相同的工具来完全按照本指南操作——但这没关系。无论您使用哪种工具,流程都是相同的:首先,通过某种Hello, World建立连接;然后,扩展您的脚本——在开发过程中测试每个新功能。
这个例子不算长,但确实涵盖了很多概念:驱动测试设备、打印格式化字符串、运行循环以及执行文件操作。虽然我们进行的实验相当简单,但无需太多想象力就能看出它如何扩展。电源和万用表之间可以连接一个被测设备。此外,你还可以包含更多测试设备;我最近用这套测试设备测试了一个电源模块:两个万用表、一个电源、一个电子负载 和一个示波器——所有这些都由一个脚本控制!真是太神奇了!
在这个例子中,我们直接编写了底层命令。如果您经常这样做,建议您为仪器 编写一个Python 类,以加快编码速度。
与往常一样,如果您觉得本教程有趣或有用,我们很乐意听取您的意见!如果您有任何疑问或疑惑,请在下方留言!我们是全职创客,随时为您提供帮助。
编码愉快!
更多推荐


所有评论(0)