Skip to content

USB command with more than 512 bytes fails #580

Description

@ll-rh

Problem

The USB control fails with PyVISA when the command is > 512 bytes.
The default versions of Debian 13 have been used.

    Python          3.13.5
    PyVISA          1.14.1
    PyVISA-py       0.7.2

The current versions have also been tested and also fail.


    PyVISA          1.16.2
    PyVISA-py       0.8.1

A test code opens the device. Firstly, a command with < 512 bytes is sent to prove proper operation.
Secondly, a command with > 512 bytes is sent which fails.

    import pyvisa

    rm = pyvisa.ResourceManager()
    USBID = "::2391::7937::"    # Keysight RF generator
    resource = rm.list_resources(f"?*{USBID}?*::INSTR")
    my_instrument = rm.open_resource(resource[0])

    # 1. test cmd with < 512 bytes is valid
    cmd_str = "LIST:FREQ 1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000"
    print(f"len(cmd_str) = {len(cmd_str)}")
    my_instrument.write(cmd_str)
    print(f"error: {my_instrument.query('SYST:ERR?')}")
    my_instrument.query('SYST:ERR?')

    # 2. test cmd with > 512 bytes fails
    cmd_str = "LIST:FREQ 1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000,1000000000"
    print(f"len(cmd_str) = {len(cmd_str)}")
    my_instrument.write(cmd_str)        # fails with "pipe error" and final code is not reached
    print(f"error: {my_instrument.query('SYST:ERR?')}")

    my_instrument.close()

The test fails with a "ValueError: [Errno 32] Pipe error".

len(cmd_str) = 504
error: +0,"No error"

len(cmd_str) = 515
Traceback (most recent call last):
  File "/usr/local/lib/python3.13/dist-packages/pyvisa_py/protocols/usbtmc.py", line 281, in write
    return self.usb_send_ep.write(data)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/usr/lib/python3/dist-packages/usb/core.py", line 408, in write
    return self.device.write(self, data, timeout)
           ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/usb/core.py", line 989, in write
    return fn(
            self._ctx.handle,
    ...<3 lines>...
            self.__get_timeout(timeout)
        )
  File "/usr/lib/python3/dist-packages/usb/backend/libusb1.py", line 837, in bulk_write
    return self.__write(self.lib.libusb_bulk_transfer,
           ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                        dev_handle,
                        ^^^^^^^^^^^
    ...<2 lines>...
                        data,
                        ^^^^^
                        timeout)
                        ^^^^^^^^
  File "/usr/lib/python3/dist-packages/usb/backend/libusb1.py", line 938, in __write
    _check(retval)
    ~~~~~~^^^^^^^^
  File "/usr/lib/python3/dist-packages/usb/backend/libusb1.py", line 604, in _check
    raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 32] Pipe error

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/me/n51xxx-usb-512-bytes-fail.py", line 18, in <module>
    my_instrument.write(cmd_str)        # fails with "pipe error" and final code is not reached
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/usr/local/lib/python3.13/dist-packages/pyvisa/resources/messagebased.py", line 213, in write
    count = self.write_raw(message.encode(enco))
  File "/usr/local/lib/python3.13/dist-packages/pyvisa/resources/messagebased.py", line 173, in write_raw
    return self.visalib.write(self.session, message)[0]
           ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/dist-packages/pyvisa_py/highlevel.py", line 574, in write
    written, status_code = self.sessions[session].write(data)
                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/usr/local/lib/python3.13/dist-packages/pyvisa_py/usb.py", line 210, in write
    count = self.interface.write(data)
  File "/usr/local/lib/python3.13/dist-packages/pyvisa_py/protocols/usbtmc.py", line 454, in write
    bytes_sent += raw_write(chunk)
                  ~~~~~~~~~^^^^^^^
  File "/usr/local/lib/python3.13/dist-packages/pyvisa_py/protocols/usbtmc.py", line 283, in write
    raise ValueError(str(e))
ValueError: [Errno 32] Pipe error

Possible solution

Testing showed that other PCs with older versions (PyVISA 1.11.3, PyVISA-py 0.5.1) didn't fail and so, I also excluded the target device as the reason. But an update of my PC to the current versions also failed. Finally, in a debugging session I found the following line in version 0.8.2.

    /pyvisa_py/protocols/usbtmc.py:447

            begin, end = end, begin + self.usb_send_ep.wMaxPacketSize

In the 1st run of the while loop with this line it becomes "begin, end = 0, 512". In the 2nd run, the new value for "end" becomes equal to the new value for "begin" - "begin, end = 512, 512". I suppose, that this should be "begin, end = 512, 1024" and changed the line to

            begin, end = end, end + self.usb_send_ep.wMaxPacketSize

The program runs properly with this. But I don't know if this breaks something else. This is your task.

Output of pyvisa-info

Machine Details:
   Platform ID:    Linux-6.12.85+deb13-amd64-x86_64-with-glibc2.41
   Processor:      

Python:
   Implementation: CPython
   Executable:     /usr/bin/python3
   Version:        3.13.5
   Compiler:       GCC 14.2.0
   Architecture:   ('x86', 64)
   Build:          Jun 25 2025 18:55:22 (#main)
   Unicode:        UCS4

PyVISA Version: 1.16.2

Backends:
   ivi:
      Version: 1.16.2 (bundled with PyVISA)
      Binary library: Not found
   py:
      Version: 0.8.1
      ASRL INSTR: Available via PySerial (3.5)
      USB INSTR: Available via PyUSB (1.2.1-2). Backend: libusb1
      USB RAW: Available via PyUSB (1.2.1-2). Backend: libusb1
      TCPIP INSTR: Available 
         Resource discovery:
         - VXI-11: ok
         - hislip: ok
      TCPIP SOCKET: Available 
      PRLGX_TCPIP INTFC: Available 
      PRLGX_ASRL INTFC: Available via PySerial (3.5)
      GPIB INSTR: Available 
      VICP INSTR:
         Please install PyVICP to use this resource type.
      GPIB INTFC:
         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 functionalities.
         No module named 'gpib'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions