PyVisa-USB超时错误无法清除,必须重启?求调试建议
USB超时错误处理建议(Anritsu仪器USB-GPIB通信场景)
问题描述
应用通过USB-GPIB端口与Anritsu仪器通信,固定周期读取结果。偶尔会在仪器读取数据时误调用Read_data函数,触发Timeout错误导致应用停止。重启应用后,pyvisa能找到并连接仪器,但发送第一条命令*IDN?时出现超时错误,且该问题会持续到系统完全重启。
错误日志
('USB0::1003::8293::ANRITSU_0_0000::0::INSTR',) Found VNA USB0::1003::8293::ANRITSU_0_0000::0::INSTR Attached [2022-09-17 23:14:31,349] ERROR in app: Exception on / [GET] Traceback (most recent call last): File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pyvisa_py/protocols/usbtmc.py", line 256, in write return self.usb_send_ep.write(data) File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/usb/core.py", line 408, in write return self.device.write(self, data, timeout) File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/usb/core.py", line 989, in write return fn( File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/usb/backend/libusb1.py", line 837, in bulk_write return self.__write(self.lib.libusb_bulk_transfer, File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/usb/backend/libusb1.py", line 938, in __write _check(retval) File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/usb/backend/libusb1.py", line 602, in _check raise USBTimeoutError(_strerror(ret), ret, _libusb_errno[ret]) usb.core.USBTimeoutError: [Errno 110] Operation timed out During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/flask/app.py", line 2070, in wsgi_app response = self.full_dispatch_request() File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/flask/app.py", line 1508, in full_dispatch_request self.try_trigger_before_first_request_functions() File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/flask/app.py", line 1560, in try_trigger_before_first_request_functions self.ensure_sync(func)() File "/home/xilinx/Anritsu_GPIB/VNA/routes.py", line 44, in intialize_VNA print(anritsu.VNA.query('*IDN?')) File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pyvisa/resources/messagebased.py", line 642, in query self.write(message) File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pyvisa/resources/messagebased.py", line 197, in write count = self.write_raw(message.encode(enco)) File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pyvisa/resources/messagebased.py", line 157, in write_raw return self.visalib.write(self.session, message)[0] File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pyvisa_py/highlevel.py", line 543, in write written, status_code = self.sessions[session].write(data) File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pyvisa_py/usb.py", line 179, in write count = self.interface.write(data) File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pyvisa_py/protocols/usbtmc.py", line 436, in write bytes_sent += raw_write(data) File "/usr/local/share/pynq-venv/lib/python3.8/site-packages/pyvisa_py/protocols/usbtmc.py", line 258, in write raise ValueError(str(e)) ValueError: [Errno 110] Operation timed out
调试与解决建议
- 添加操作互斥锁:在调用
Read_data或其他仪器操作函数前,使用threading.Lock实现互斥,确保同一时间只有一个操作请求发送给仪器,避免并发调用导致的设备状态异常。 - 强制重置USB设备:应用重启时,不依赖pyvisa的自动连接,直接用
pyusb重置目标USB设备,清除异常状态:
执行完重置后再用pyvisa重新连接,无需重启系统即可恢复通信。import usb.core import usb.util # 替换为仪器的USB VID和PID(从设备地址中提取:1003是VID,8293是PID) VID = 0x1003 PID = 0x8293 device = usb.core.find(idVendor=VID, idProduct=PID) if device: # 分离内核驱动(如果存在) if device.is_kernel_driver_active(0): device.detach_kernel_driver(0) # 释放资源并重置设备 usb.util.dispose_resources(device) device.reset() - 实现超时重试机制:对仪器命令添加重试逻辑,捕获超时异常后重试2-3次,同时适当延长超时时间:
def safe_instr_query(instrument, command, timeout=5000, max_retries=3): for _ in range(max_retries): try: instrument.timeout = timeout return instrument.query(command) except Exception as e: if "timeout" in str(e).lower(): continue raise raise TimeoutError(f"Command '{command}' failed after {max_retries} retries") - 发送仪器状态恢复命令:在重置USB设备后,立即发送
*CLS(清除状态寄存器)或*RST(重置仪器到默认状态)命令,帮助仪器回到可正常响应的状态。 - 排查适配器兼容性:部分廉价USB-GPIB适配器在超时后容易锁死,尝试更换官方认证的适配器,或更新适配器固件。
- 启用pyvisa调试日志:开启pyvisa的详细日志,查看通信过程中的数据包交互细节,定位问题根源:
import pyvisa pyvisa.log_to_screen()
内容的提问来源于stack exchange,提问作者bierkof
相关产品推荐
相关产品推荐

