python-ivi / python-usbtmc

Provides a USBTMC driver for controlling instruments over USB
MIT License
162 stars 70 forks source link

Instrument does not recover after timeout; all subsequent commands also time out #49

Open ghost opened 5 years ago

ghost commented 5 years ago

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 usbtmc
>>> instr = usbtmc.Instrument(0x0699, 0x3000)
>>> instr.ask('*IDN?')
'TEKTRONIX, FCA3000, 379751, V1.28 25 Aug 2010 11:52'
>>> instr.ask('MEAS:FREQ?')  # instrument responds too slow
...
usb.core.USBError: [Errno 110] Operation timed out
>>> instr.ask('*IDN?')  # insrument should reply quickly
...
usb.core.USBError: [Errno 110] Operation timed out

I have seen this behaviour with a Tektronix FCA3000 and Thorlabs PM100D. I'm using the latest version of python-usbtmc from Github. Debian 9.6 - Python 3.5.3 - PyUSB 1.0.0 - libusb 1.0.21 - Linux 4.9.110

Looking at USB traces with Wireshark, I notice that after a timeout, python-usbtmc automatically sends an ABORT_BULK_IN sequence to the device. However the USBTMC specification requires that the host reads from the Bulk-IN endpoint as part of this sequence but python-usbtmc seems to skip that step.

I modified python-usbtmc to read the Bulk-IN endpoint during the ABORT_BULK_IN sequence. With this change, my instrument recovers from timeout and answers quickly to subsequent commands. I will submit a pull request ...