You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keithley SourceMeter测量电流值无法传输至电脑问题咨询及代码排查求助

问题原因分析

你碰到的这个问题其实很常见——ser.write()方法的返回值并不是设备的响应数据,而是你发送出去的字节数。这就是为什么你得到的总是:READ?\r\n这条命令的字符数,完全和电流值没关系。

要获取Keithley返回的电流数据,你需要在发送查询命令后,主动去读取串口缓冲区里设备发回来的响应内容,而不是直接拿write的返回值。

代码修正方案

我给你调整了关键部分的代码,同时补充了一些必要的设置,确保能稳定读取到正确的电流值:

1. 先完善串口初始化(增加超时设置)

在打开串口之前,加上超时配置,避免读取操作一直卡住:

ser = serial.Serial()
ser.port = 'COM3'
ser.baudrate = 9600
ser.timeout = 2  # 设置2秒超时,可根据实际情况调整
ser.open()

2. 修正电流读取的核心逻辑

把原来错误的一行拆成几步,先发送命令,再读取响应,最后转换成数值:

# 原来的错误代码
# current = ser.write(str.encode(':READ?'+'\r\n')) #measure current

# 修正后的代码
# 发送电流查询命令
ser.write(str.encode(':READ?'+'\r\n'))
# 读取设备返回的响应(Keithley通常用\r\n作为终止符)
response_bytes = ser.read_until(b'\r\n')
# 把字节数据转成字符串,同时去掉首尾的空白字符(比如换行符)
response_str = response_bytes.decode('utf-8').strip()
# 转换成浮点数类型的电流值
current = float(response_str)
currents.append(current) #record current

3. 可选优化:合并重复的SCPI命令

你在循环里反复发送:SOUR:FUNC VOLT、:SOUR:VOLT:MODE FIX这些配置命令,其实这些只需要在循环前执行一次就够了,没必要每次循环都发,这样能提高测试效率:

# 把这些配置命令移到循环外面
ser.write(str.encode(':SOUR:FUNC VOLT'+'\r\n'))
ser.write(str.encode(':SOUR:VOLT:MODE FIX'+'\r\n'))
ser.write(str.encode(':SOUR:VOLT:RANG 20'+'\r\n'))
ser.write(str.encode(':SENS:FUNC "CURR"'+'\r\n'))
ser.write(str.encode(':SENS:CURR:PROT 10e-1'+'\r\n'))
ser.write(str.encode(':SENS:CURR:RANG 10e-1'+'\r\n'))
ser.write(str.encode(':SENS:CURR:RANG:AUTO ON'+'\r\n'))

for iterations in range(numberofiterations):
    #record voltage
    voltages.append(round(voltage,5))
    #supply voltage
    ser.write(str.encode(':SOUR:VOLT:LEV '+str(voltage)+'\r\n'))
    #wait
    time.sleep(1)
    #measure current(用上面修正后的代码)
    ...
完整修正后的代码
import pyvisa
import time
import serial

# configure the serial connections (the parameters differs on the device you are connecting to)
ser = serial.Serial()
ser.port = 'COM3'
ser.baudrate = 9600
ser.timeout = 2  # 添加超时设置
ser.open()
print(f"串口是否打开: {ser.isOpen()}") # 打印确认串口状态

###Sweep
numberofiterations = 10
stepsize = 0.05
voltage = 0
currents = []
voltages = []

ser.write(str.encode('*RST' + '\r\n'))
ser.write(str.encode(':OUTP ON'+'\r\n'))

# 提前发送所有固定配置命令,避免循环内重复发送
ser.write(str.encode(':SOUR:FUNC VOLT'+'\r\n'))
ser.write(str.encode(':SOUR:VOLT:MODE FIX'+'\r\n'))
ser.write(str.encode(':SOUR:VOLT:RANG 20'+'\r\n'))
ser.write(str.encode(':SENS:FUNC "CURR"'+'\r\n'))
ser.write(str.encode(':SENS:CURR:PROT 10e-1'+'\r\n'))
ser.write(str.encode(':SENS:CURR:RANG 10e-1'+'\r\n'))
ser.write(str.encode(':SENS:CURR:RANG:AUTO ON'+'\r\n'))

for iterations in range(numberofiterations):
    #record voltage
    voltages.append(round(voltage,5))
    #supply voltage
    ser.write(str.encode(':SOUR:VOLT:LEV '+str(voltage)+'\r\n'))
    #wait
    time.sleep(1)
    #measure current
    ser.write(str.encode(':READ?'+'\r\n'))
    response_bytes = ser.read_until(b'\r\n')
    response_str = response_bytes.decode('utf-8').strip()
    current = float(response_str)
    currents.append(current) #record current
    #increase voltage
    voltage += stepsize

#Print out values
print("读取到的电流值:")
for curr in currents:
    print(curr)
print("\n设置的电压值:")
for volt in voltages:
    print(volt)

# 测试结束后关闭串口
ser.close()
额外注意事项
  • 如果发现读取到的响应是空的或者不完整,可以适当调整ser.timeout的数值,或者在发送命令后加个短暂的time.sleep(0.5)给设备足够的响应时间(不过超时机制更可靠)。
  • 可以查看Keithley的官方手册,确认:READ?命令的返回格式——有些型号可能返回多个值(比如电压+电流),这时候你需要把字符串按逗号分割再转换数值。不过根据你的描述,设备屏幕显示正确的电流值,所以应该是单个数值返回。

内容的提问来源于stack exchange,提问作者Stella

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 21:57:48