Python通过TCP/IP连接Keysight E4980A LCR表发送SCPI指令异常
问题根因
- 5025端口连接超时:设备端默认未开启Raw SCPI Socket服务,E4980A的LAN服务默认仅启用Telnet(5024端口),需要手动在前面板系统设置中开启5025对应的SCPI Socket服务,同时确认本地防火墙未拦截对应端口,直连场景下确认电脑和设备同属169.254网段、无IP冲突。
- 5024端口仅返回欢迎信息:两个细节错误导致:
- 发送的SCPI指令未带标准终止符,所有标准SCPI设备要求指令必须以
\r\n(Telnet端口)或\n(Raw Socket端口)作为结尾,无终止符的情况下设备会判定指令未输入完成,不会执行也不会返回结果。 - 代码逻辑时序错误:5024端口建立TCP连接后会主动推送欢迎banner和
SCPI>提示符,你在发送指令前就调用了一次recv,读到的只是这串主动推送的欢迎信息,后续既没有等指令响应,也没有循环读取缓冲区内容,自然拿不到指令返回结果。
- 发送的SCPI指令未带标准终止符,所有标准SCPI设备要求指令必须以
- 原生
socket库完全适配该控制场景,不存在协议不兼容问题,不需要强制依赖pyvisa库,只要对齐SCPI通信的细节要求即可。
可直接运行的实现代码
5024 Telnet端口版本(无需修改设备配置,直接可用)
import socket import time DEVICE_IP = "169.254.215.142" TELNET_PORT = 5024 BUFFER_SIZE = 1024 # 建立连接 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(5) s.connect((DEVICE_IP, TELNET_PORT)) # 等待设备推送完欢迎banner,读空缓冲区残留的欢迎信息 time.sleep(0.2) while True: try: s.setblocking(False) banner = s.recv(BUFFER_SIZE) if not banner: break except BlockingIOError: break s.setblocking(True) # 发送带终止符的*IDN?指令 s.send(b"*IDN?\r\n") # 循环读取直到拿到完整响应(响应以换行为结束标记) resp = b"" while b"\n" not in resp: chunk = s.recv(BUFFER_SIZE) if not chunk: break resp += chunk s.close() print("设备IDN响应:", resp.decode().strip())
5025 Raw SCPI端口版本(需先修改设备配置)
使用前先在设备前面板操作开启服务:按System按键进入系统菜单 -> 选择LAN Setup -> 进入Services配置项 -> 将SCPI Socket状态改为On,保存配置后重启LAN模块即可连通5025端口。
import socket DEVICE_IP = "169.254.215.142" SOCKET_PORT = 5025 BUFFER_SIZE = 1024 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(5) s.connect((DEVICE_IP, SOCKET_PORT)) # Raw端口无欢迎banner,直接发送带\n终止符的指令即可 s.send(b"*IDN?\n") resp = b"" while b"\n" not in resp: chunk = s.recv(BUFFER_SIZE) if not chunk: break resp += chunk s.close() print("设备IDN响应:", resp.decode().strip())
注意事项
- 不要使用
ansi编码做字符串转字节,SCPI协议原生使用ASCII编码,直接构造b前缀的字节串最稳妥,避免编码兼容问题。 - 所有SCPI指令必须带对应终止符,这是绝大多数LAN口控制仪器失败的核心原因。
- 直连场景下建议给电脑和设备设置静态同网段IP,不要依赖169.254自动分配地址,稳定性会差很多。
- pyvisa本质是对socket、VXI-11等底层通信逻辑的封装,不想手动处理socket读写逻辑可以直接用,不存在特殊私有协议要求。
内容的提问来源于stack exchange,提问作者theozh
相关产品推荐
相关产品推荐

