通信方式用USB数据线进行串口通信,用到了pyvisa库,是一个仪器开发领域应用较为广泛的通信协议库。也看到过有人用pyserial库进行通讯的。控制功能则是通过SCPI指令集实现,通过数据通信,将SCPI指令以字符串的形式发送给仪器即可,B2961A的SCPI指令集参考可以在官网下载;用户手册里写的那个IVI编程规范我是真看不来,很多代码不清楚含义。
先用数据线连接电脑和B2961A电源,然后用visa库的ResourceManager()函数获取到当前已连接的资源列表。
import pyvisa as visa
import time
import math
rm = visa.ResourceManager()
print(rm.list_resources())
得到结果如下(已隐去特别信息):
('USB0::0x????::0x????::MY????????::INSTR', 'ASRL1::INSTR')
取前一段字符串作为资源名称,打开电源与电脑的连接,并写两行配置代码(有一位博主说可以避免一些可能出现的问题):
keysight1 = 'USB0:-----------------'
my_source = rm.open_resource(keysight1)
my_source.read_termination = '\n' # 两行配置代码
my_source.write_termination = '\n'
my_source.query('*IDN?') # 请问仪器的IDN?返回字符串
query()函数是发送请求,并得到仪器的回复。这里顺便问一下该仪器的IDN是什么,这里的IDN包括Keysight公司名+型号+序列号+版本。结果如下(已隐去特别信息):
'Keysight Technologies,B2961A,MY????????,2.1.????.????'
然后用write()函数单向对仪器写入命令,开启输出,并测试改变电压的反应时间,这里循环五百次测试,查看每次耗时。
测试时,如果不在改变电压值后加查询电压值的代码,会出现程序跑完了但是电源并未运行完毕的现象,应该是电源内有指令缓存。加这行代码不太影响速度,因为不加的时候时间也是差不多的,但是我并没有计时。
# 打开电源输出
my_source.write(':OUTPut ON')
# 获取每次所耗时间
time_list = []
for i in range(500):
start = time.time() # 标记开始时间
my_source.write(':VOLT:LEV:IMM:AMPL '+str(math.sin(i))+'e-3;:PROTect 1')
buffer_measure.append(my_source.query(':MEASure:VOLTage:DC?'))
end = time.time() # 标记结束时间
time_list.append(end-start)
# 将每次所耗时间绘制如图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] # 图表内显示中文
plt.figure(figsize=(10,8))
plt.plot(time_list)
plt.xlabel('次数')
plt.ylabel('时间/s')
plt.show()
# 看看直方图
plt.figure(figsize=(10,8))
plt.hist(time_list, bins=100)
plt.xlabel('时间/s')
plt.ylabel('数据个数/个')
plt.show()
可以看到时间基本都在0.045s到0.048s之间,平均值可以算得是0.0472s,时有大值,最大不超过0.07s。
最后记得关输出,不用电源了就断开与上位机的连接(我也曾不断连接直接拔USB,貌似没什么影响。。。):
# 关闭电源输出
my_source.write(':OUTPut OFF')
# 断开上位机与仪器的连接
my_source.close()
其他通信方式也是完全一样,只需要通过数据通信将SCPI指令以字符串形式发送给仪器即可,在官网看到一篇LAN通信的简例。