pyvisa / pyvisa-py

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

Can't open an USBTMC device which has a serial number with zero length. #280

Closed vDorst closed 11 months ago

vDorst commented 3 years ago

I have a cheap Siglent Technologies SDG1032X clone aka ALP1005

But pyvisa connect string looks like USB0::62701::60986::::0::INSTR

Python code and backtrace.

Python 3.8.5 (default, Aug 12 2020, 00:00:00)
[GCC 10.2.1 20200723 (Red Hat 10.2.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyvisa
>>> rm = pyvisa.ResourceManager()
>>> rm.list_resources()
('ASRL/dev/ttyS0::INSTR', 'ASRL/dev/ttyUSB1::INSTR', 'USB0::62701::60986::::0::INSTR')
>>> inst = rm.open_resource('USB0::62701::60986::::0::INSTR')
Traceback (most recent call last):
  File "/usr/local/lib64/python3.8/site-packages/pyvisa/rname.py", line 237, in from_string
    rn = subclass.from_parts(*parts)
  File "/usr/local/lib64/python3.8/site-packages/pyvisa/rname.py", line 315, in from_parts
    return cls(**kwargs)
  File "<string>", line 8, in __init__
  File "/usr/local/lib64/python3.8/site-packages/pyvisa/rname.py", line 173, in __post_init__
    raise TypeError(f.name + " is a required parameter")
TypeError: serial_number is a required parameter

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib64/python3.8/site-packages/pyvisa_py/highlevel.py", line 156, in open
    parsed = rname.parse_resource_name(resource_name)
  File "/usr/local/lib64/python3.8/site-packages/pyvisa/rname.py", line 241, in from_string
    raise InvalidResourceName.bad_syntax(
pyvisa.rname.InvalidResourceName: Could not parse 'USB0::62701::60986::::0::INSTR'. The syntax is 'USB[board]::manufacturer id::model code::serial number[::usb interface number][::INSTR]' (serial_number is a required parameter).

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib64/python3.8/site-packages/pyvisa/highlevel.py", line 3304, in open_resource
    res.open(access_mode, open_timeout)
  File "/usr/local/lib64/python3.8/site-packages/pyvisa/resources/resource.py", line 297, in open
    self.session, status = self._resource_manager.open_bare_resource(
  File "/usr/local/lib64/python3.8/site-packages/pyvisa/highlevel.py", line 3232, in open_bare_resource
    return self.visalib.open(self.session, resource_name, access_mode, open_timeout)
  File "/usr/local/lib64/python3.8/site-packages/pyvisa_py/highlevel.py", line 160, in open
    self.handle_return_value(None, StatusCode.error_invalid_resource_name),
  File "/usr/local/lib64/python3.8/site-packages/pyvisa/highlevel.py", line 251, in handle_return_value
    raise errors.VisaIOError(rv)
pyvisa.errors.VisaIOError: VI_ERROR_INV_RSRC_NAME (-1073807342): Invalid resource reference specified. Parsing error.

lsusb output:

Bus 005 Device 004: ID f4ed:ee3a Shenzhen Siglent Co., Ltd. SDG1010 Waveform Generator (TMC mode)
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0xf4ed Shenzhen Siglent Co., Ltd.
  idProduct          0xee3a SDG1010 Waveform Generator (TMC mode)
  bcdDevice            2.00
  iManufacturer           1 SIGLENT Technologies Co,. Ltd.
  iProduct                2
  iSerial                 3
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0027
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xc0
      Self Powered
    MaxPower                2mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass       254 Application Specific Interface
      bInterfaceSubClass      3 Test and Measurement
      bInterfaceProtocol      1 TMC
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0002  1x 2 bytes
        bInterval               1
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  bNumConfigurations      1
can't get debug descriptor: Resource temporarily unavailable
Device Status:     0x0001
  Self Powered

Instrument details

Output of pyvisa-info

Machine Details:
   Platform ID:    Linux-5.8.9-200.fc32.x86_64-x86_64-with-glibc2.2.5
   Processor:      x86_64

Python:
   Implementation: CPython
   Executable:     /usr/bin/python3
   Version:        3.8.5
   Compiler:       GCC 10.2.1 20200723 (Red Hat 10.2.1-1)
   Bits:           64bit
   Build:          Aug 12 2020 00:00:00 (#default)
   Unicode:        UCS4

PyVISA Version: 1.11.1

Backends:
   ivi:
      Version: 1.11.1 (bundled with PyVISA)
      Binary library: Not found
   py:
      Version: 0.5.1
      ASRL INSTR: Available via PySerial (3.4)
      USB INSTR: Available via PyUSB (1.1.0). Backend: libusb1
      USB RAW: Available via PyUSB (1.1.0). Backend: libusb1
      TCPIP INSTR: Available
      TCPIP SOCKET: Available
      GPIB INSTR:
         Please install linux-gpib (Linux) or gpib-ctypes (Windows, Linux) to use this resource type. Note that installing gpib-ctypes will give you access to a broader range of funcionality.
         No module named 'gpib'

I patched the code to make it work. Is is not an elegant solution but it works.

python script

import pyvisa
rm = pyvisa.ResourceManager()
l = rm.list_resources()
print(l)
inst = rm.open_resource(l[2])
print(inst.query("*IDN?"))

output

('ASRL/dev/ttyS0::INSTR', 'ASRL/dev/ttyUSB1::INSTR', 'USB0::62701::60986::N/A::0::INSTR')
*IDN SDG,1.01.01.27,02-00-00-21-24
MatthieuDartiailh commented 3 years ago

That's an odd one indeed. Ideally I would like to see how commercial VISA implementation handle the issue. Keysight offers VISA for Linux but only for specific kernel versions. Otherwise if you have access to a Windows machine you can go with whatever implementation you like. I would really like this data point because according to the VISA specification the serial number is a mandatory field of the address. Maybe we are just reading the serial wrong, your lsusb seem to think the serial number is 3.

vDorst commented 3 years ago

It is a cheap clone. Even info screen shows that the serial number has no value. So I think they forgot it to program it!

We also have a real SIGLENT Technologies function generator which works fine because it reports an serial number.

lsusb

Bus 005 Device 006: ID f4ed:ee3a Shenzhen Siglent Co., Ltd. SDG1010 Waveform Generator (TMC mode)
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0xf4ed Shenzhen Siglent Co., Ltd.
  idProduct          0xee3a SDG1010 Waveform Generator (TMC mode)
  bcdDevice            2.00
  iManufacturer           1 SIGLENT Technologies Co,. Ltd.
  iProduct                2 SDG1010
  iSerial                 3 SDG100E<snip; 5 numbers>
  bNumConfigurations      1

Resouce list: ('ASRL/dev/ttyS0::INSTR', 'ASRL/dev/ttyUSB1::INSTR', 'USB0::62701::60986::SDG100E<snip; 5 numbers>::0::INSTR') IDN request: *IDN SDG,SDG1010,SDG100E<snip; 5 numbers>,1.01.01.37R3,02-00-00-23-26

I there an other way to open a device just based on USBID? Otherwise I have to stick to older https://github.com/python-ivi/python-usbtmc library.\

In python-usbtmc I use it like this:

import usbtmc
instr =  usbtmc.Instrument(2391, 5973)

I was exploring your library because it is maintained. I also don't need the features of VISA. I currently send raw command already.

Sorry but I currently haven't the time to testing the Keysight VISA software in Windows.

It is fine to close this issue. I understand that you not going to chang the code for just one faulty device.

MatthieuDartiailh commented 3 years ago

The USBTMC norm requires the instrument to report a serial number. However RAW USB instrument that are technically supported only by NI can omit it. And NI VISA will report something similar to N/A but it does not appear to be normalized.

As a consequence I would likely accept a PR doing the following:

However note that if you do not need any VISA functionality you could also consider simply using libusb directly. Sorry for the delay I started answering on my phone but lost the message and though I had commented.