1

I am very new to USB. I need to communicate with a laser controller and I want to use Python for this. I am now working in an Ubuntu 20.04 machine. I have this code:

import usb.core
import usb.util

device = usb.core.find(idVendor=0xC251, idProduct=0x2201)
if device is None:
    raise RuntimeError('Device not found')
interface = device[0].interfaces()[0]
if device.is_kernel_driver_active(interface.bInterfaceNumber):
    device.detach_kernel_driver(interface.bInterfaceNumber)

endpoint = device[0].interfaces()[0].endpoints()[0]
endpoint.write(b'\x00\x90\x04')

but I always get usb.core.USBError: [Errno 75] Overflow when trying to write. However, I am able to read data from the device using endpoint.read(64) and this seems to be working fine. I cannot find information about this overflow error.

In case it is of any help, this is what print(device) shows:

DEVICE ID c251:2201 on Bus 002 Address 010 =================
 bLength                :   0x12 (18 bytes)
 bDescriptorType        :    0x1 Device
 bcdUSB                 :  0x200 USB 2.0
 bDeviceClass           :    0x0 Specified at interface
 bDeviceSubClass        :    0x0
 bDeviceProtocol        :    0x0
 bMaxPacketSize0        :   0x40 (64 bytes)
 idVendor               : 0xc251
 idProduct              : 0x2201
 bcdDevice              :  0x100 Device 1.0
 iManufacturer          :    0x1 LASER Driver 
 iProduct               :    0x2 LASER Driver IJS
 iSerialNumber          :    0x3 0001A0000000
 bNumConfigurations     :    0x1
  CONFIGURATION 1: 100 mA ==================================
   bLength              :    0x9 (9 bytes)
   bDescriptorType      :    0x2 Configuration
   wTotalLength         :   0x22 (34 bytes)
   bNumInterfaces       :    0x1
   bConfigurationValue  :    0x1
   iConfiguration       :    0x0 
   bmAttributes         :   0xc0 Self Powered
   bMaxPower            :   0x32 (100 mA)
    INTERFACE 0: Human Interface Device ====================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x0
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x1
     bInterfaceClass    :    0x3 Human Interface Device
     bInterfaceSubClass :    0x0
     bInterfaceProtocol :    0x0
     iInterface         :    0x4 HID
      ENDPOINT 0x81: Interrupt IN ==========================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x81 IN
       bmAttributes     :    0x3 Interrupt
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x1
user171780
  • 2,243
  • 1
  • 20
  • 43

1 Answers1

2

I have exactly the same problem, but with other USB device, not the laser controller. What helped in my case, is writing exactly 64-byte long data packets to the endpoint, with the appropriate amount of zeros appended.

What I mean -- in your write code, instead of sending three bytes:

endpoint.write(b'\x00\x90\x04')

try out sending 64-byte long packet:

cmd = b'\x00\x90\x04'
packet_to_send = cmd + b'\x00' * (64 - len(cmd))
endpoint.write(packet_to_send)
selyunin
  • 1,530
  • 2
  • 23
  • 30
  • 1
    Thank you for your answer. The laser still is still ignoring me but at least I don't get the error, and `print(endpoint.write(packet_to_send))` displays `64` so I assume the message is being sent. I don't know how was I supposed to know this, the documentation about all these topics is very diffuse and disperse. – user171780 Dec 15 '21 at 12:45
  • what you can try as well, is to add the `device.set_configuration()` in your initialization part, as in the [pyusb tutorial](https://github.com/pyusb/pyusb/blob/master/docs/tutorial.rst): as the method suggests, it does some initialization, maybe this is missing in your case – selyunin Dec 16 '21 at 05:52
  • I have tried `device.set_configuration()` and `device.reset()` in all combinations (i.e. the two of them, none, and only one of them) and does not work. I think this laser controller has to be controlled through the "control endpoint", as it was suggested [here](https://unix.stackexchange.com/questions/681481/missing-usb-out-endpoint/682662#682662) and also I found in some old source code of another controller. The thing now is that [I don't know how to send the `packet` to the "control endpoint"](https://stackoverflow.com/questions/70371707/how-to-write-to-control-endpoint-with-pyusb). – user171780 Dec 16 '21 at 08:38
  • Also, I have checked my code, one **writes** to the OUT endpoint, and **reads** from the IN endpoint (if you write to IN, you get no error, but nothing happens). So I think this is definitely you can check, as you are **writing** to the IN endpoint. – selyunin Dec 16 '21 at 13:22
  • Yes, indeed. My device has no OUT endpoint which looked strange to me but seems that it is normal and I have to write in a special way into the "control endpoint". In case someone runs into the same issue, see [here](https://stackoverflow.com/questions/70371707/how-to-write-to-control-endpoint-with-pyusb/70377109#70377109). – user171780 Dec 16 '21 at 13:24