python-ivi / python-usbtmc

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

unpack_from requires a buffer of at least 4 bytes #37

Open mcgdb opened 7 years ago

mcgdb commented 7 years ago

Hello,

On a fresh install and with running ipython in Arch Linux with sudo, I get the following output with a DS1104Z scope:

Python 3.6.2 (default, Jul 20 2017, 03:52:27) Type "copyright", "credits" or "license" for more information.

IPython 5.3.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import usbtmc

In [2]: instr = usbtmc.Instrument("USB::6833::1230::DS1ZA153401099::INSTR")

In [3]: print(instr.ask(b"*IDN?"))
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-3-9a8437ac9ff7> in <module>()
----> 1 print(instr.ask(b"*IDN?"))

/usr/lib/python3.6/site-packages/python_usbtmc-0.8-py3.6.egg/usbtmc/usbtmc.py in ask(self, message, num, encoding)
    752                 self.lock()
    753             self.write(message, encoding)
--> 754             return self.read(num, encoding)
    755         finally:
    756             if self.advantest_quirk and not was_locked:

/usr/lib/python3.6/site-packages/python_usbtmc-0.8-py3.6.egg/usbtmc/usbtmc.py in read(self, num, encoding)
    735     def read(self, num=-1, encoding='utf-8'):
    736         "Read string from instrument"
--> 737         return self.read_raw(num).decode(encoding).rstrip('\r\n')
    738 
    739     def ask(self, message, num=-1, encoding='utf-8'):

/usr/lib/python3.6/site-packages/python_usbtmc-0.8-py3.6.egg/usbtmc/usbtmc.py in read_raw(self, num)
    664                     pass # do nothing, the packet has no header if it isn't the first
    665                 else:
--> 666                     msgid, btag, btaginverse, transfer_size, transfer_attributes, data = self.unpack_dev_dep_resp_header(resp)
    667 
    668 

/usr/lib/python3.6/site-packages/python_usbtmc-0.8-py3.6.egg/usbtmc/usbtmc.py in unpack_dev_dep_resp_header(self, data)
    588 
    589     def unpack_dev_dep_resp_header(self, data):
--> 590         msgid, btag, btaginverse = self.unpack_bulk_in_header(data)
    591         transfer_size, transfer_attributes = struct.unpack_from('<LBxxx', data, 4)
    592         data = data[USBTMC_HEADER_SIZE:transfer_size+USBTMC_HEADER_SIZE]

/usr/lib/python3.6/site-packages/python_usbtmc-0.8-py3.6.egg/usbtmc/usbtmc.py in unpack_bulk_in_header(self, data)
    584 
    585     def unpack_bulk_in_header(self, data):
--> 586         msgid, btag, btaginverse = struct.unpack_from('BBBx', data)
    587         return (msgid, btag, btaginverse)
    588 

error: unpack_from requires a buffer of at least 4 bytes

In [4]: 

I've tried adding a b to the argument to pass it in as a byte data, but this is of no help. Have you seen this issue before? Any help would be greatly appreciated.

Thanks!

alexforencich commented 7 years ago

The USBTMC implementation on that entire scope series is broken and a such is currently not supported until rigol fixes it with a firmware update.

fridrikfreyr commented 7 years ago

Interestingly I see the same error on Siglent SDG 1032x series function generator. Running:

import usbtmc generator = usbtmc.Instrument(0xf4ed,0xee3a) generator.write("*IDN?") generator.read_raw()

Returns the expected response exactly half of the time. First I usually get an error:

Traceback (most recent call last): File "", line 1, in File "/home/ffg/Downloads/justincase/python-usbtmc-master/usbtmc/usbtmc.py", line 666, in read_raw msgid, btag, btaginverse, transfer_size, transfer_attributes, data = self.unpack_dev_dep_resp_header(resp) File "/home/ffg/Downloads/justincase/python-usbtmc-master/usbtmc/usbtmc.py", line 591, in unpack_dev_dep_resp_header transfer_size, transfer_attributes = struct.unpack_from('<LBxxx', data, 4) struct.error: unpack_from requires a buffer of at least 8 bytes

But the second time I run (without writing anything else in between)

generator.read_raw()

I get the expected response.

b'Siglent Technologies,SDG1032X,SDG1XCAXXXXXXX,1.01.01'

Even more interestingly, this error does not occur with all commands, only *IDN? as far as I can tell. So I decided to just ignore this issue as it seems to be some bug in the firmeware.

My other devices, Rigol DS1052E and Rigol DM3051 work perfectly.