pythonhidpyusbhardware

Read and Write HID device with PyUSB (not HIDAPI)


I would like to implement the read and write calls of the python hidapi, in pysub.

An example code using the python hidapi, looks like this:

import hid

hdev = hid.device()
h = hdev.open_path( path )

h.write( send_buffer )

res = h.read( 64 )    
receive_buffer = bytearray( res )

The main problem that I have with this is that the python hidapi read() returns a list of ints (one python int for each byte in the buffer received from the hardware), and I need the buffer as bytes and faithful to what was received.(*)

A secondary issue is that open, read and write are the only things I need and I need to keep the system as light as possible. Therefore I want to avoid the extra dependencies.

(*) bytearray() is not a good solution in this case, for reasons beyond the scope of this question.


Solution

  • Here is a minimum code example that seems to work. The HID device is a Teensy board that uses its RAWHID.recv() and RAWHID.send() to exchange text and binary with the host computer.

    #!/usr/bin/python
    
    import usb.core
    import usb.util
    
    dev = usb.core.find(idVendor=0x16C0, idProduct=0x0486)
        
    try:
        dev.reset()
    except Exception as e:
        print( 'reset', e)
    
    if dev.is_kernel_driver_active(0):
        print( 'detaching kernel driver')
        dev.detach_kernel_driver(0)
    
    endpoint_in = dev[0][(0,0)][0]
    endpoint_out = dev[0][(0,0)][1]
    
    # Send a command to the Teensy
    endpoint_out.write( "version".encode() + bytes([0]) )
    
    # Read the response, an array of byte, .tobytes() gives us a bytearray.
    buffer = dev.read(endpoint_in.bEndpointAddress, 64, 1000).tobytes()
    
    # Decode and print the zero terminated string response
    n = buffer.index(0)
    print( buffer[:n].decode() )