pyvisa / pyvisa-py

A pure python PyVISA backend
https://pyvisa-py.readthedocs.io
MIT License
282 stars 120 forks source link

USBTMC instrument does not recover from timeout; all subsequent commands also time out #177

Closed ghost closed 5 years ago

ghost commented 5 years ago

I am using pyvisa-py to connect to a Tektronix FCA3000 via USBTMC. When a read from my instrument hits the timeout, my session with that instrument does not recover. All subsequent commands and reads also result in timeout.

For example:

>>> import pyvisa
>>> rm = pyvisa.ResourceManager("@py")
>>> instr = rm.open_resource("USB::0x0699::0x3000::379751::INSTR")
>>> instr.query("*IDN?")
'TEKTRONIX, FCA3000, 379751, V1.28 25 Aug 2010 11:52\n'
>>> instr.query("MEAS:FREQ?")  # instrument responds too slow
...
pyvisa.errors.VisaIOError: VI_ERROR_TMO (-1073807339): Timeout expired before operation completed.
>>> instr.query("*IDN?")  # instrument should respond immediately
...
pyvisa.errors.VisaIOError: VI_ERROR_TMO (-1073807339): Timeout expired before operation completed.

I'm using the latest version of pyvisa-py from Github. Debian 9.6 - Python 3.5.3 - pyvisa 1.8 - PyUSB 1.0.0 - libusb 1.0.21 - Linux 4.9.110

When I try the same test with NI-VISA, the instrument recovers after timeout and responds quickly and correctly to subsequent commands. (I.e., the first timeout still occurs, but the subsequent IDN command answers quickly.)

Looking at USB traces with Wireshark, I notice that NI-VISA sends an explicit abort sequence after a read timeout, while pyvisa-py does not. The USBTMC spec requires that the host sends this abort sequence when it fails to complete a read operation.

I modified pyvisa-py to add the USBTMC abort sequence, partly based on a similar implementation from python-usbtmc. With that change, my instrument recovers from timeout and answers quickly to subsequent commands. I will submit a pull request with my changes ...