Question

I'm trying to use pywinusb to send output report to a pic18f4550. The device can receive data, and I've tested it with a C# application, which worked fine. Also, I can read data from the device with pywinusb just fine, but I have a problem trying to send data.

Here's the code I'm running:

from pywinusb import hid

filter = hid.HidDeviceFilter(vendor_id = 0x0777, product_id = 0x0077)
devices = filter.get_devices()

if devices:
    device = devices[0]
    print "success"

device.open()
out_report = device.find_output_reports()[0]

buffer= [0x00]*65
buffer[0]=0x0
buffer[1]=0x01
buffer[2]=0x00
buffer[3]=0x01

out_report.set_raw_data(buffer)
out_report.send()
dev.close()

It produces this error:

success
Traceback (most recent call last):
  File "C:\Users\7User\Desktop\USB PIC18\out.py", line 24, in <module>
    out_report.send()
  File "build\bdist.win32\egg\pywinusb\hid\core.py", line 1451, in send
    self.__prepare_raw_data()
  File "build\bdist.win32\egg\pywinusb\hid\core.py", line 1406, in __prepare_raw_data
    byref(self.__raw_data), self.__raw_report_size) )
  File "build\bdist.win32\egg\pywinusb\hid\winapi.py", line 382, in __init__
    raise helpers.HIDError("hidP error: %s" % self.error_message_dict[error_code])
HIDError: hidP error: data index not found
Was it helpful?

Solution

Here is my code and it works with an MSP430F chip running TI's datapipe USB stack. This is basically hid input and output endpoints that act as a custom data pipe allowing me to send 64 bytes in any format I want with the exception of the first byte being an ID number (defined by TI) decimal 63 and the second byte being the number of pertinent or useful bytes in the packet (64 byte max packet) with the first two bytes described above. It took me a while to figure this out mostly because of the lack of documentation. The few examples that come with pywinusb are hard to learn from at best. Anyways here is my code. It is working with my micro so this should help you.

        filter = hid.HidDeviceFilter(vendor_id = 0x2048, product_id = 0x0302)
    hid_device = filter.get_devices()
    device = hid_device[0]
    device.open()
    print(hid_device)


    target_usage = hid.get_full_usage_id(0x00, 0x3f)
    device.set_raw_data_handler(sample_handler)
    print(target_usage)


    report = device.find_output_reports()

    print(report)
    print(report[0])

    buffer = [0xFF]*64
    buffer[0] = 63

    print(buffer)

    report[0].set_raw_data(buffer)
    report[0].send()

One area that may be screwing you up is here:

out_report = device.find_output_reports()[0]

Try using "out_report = device.find_output_reports()" without the "[0]" at the end. Then use

out_report[0].set_raw_data(buffer)

and finally

out_report[0].send()

Hope this helps you out.

OTHER TIPS

HID is really powerful but nobody is using proper HID enumeration, HID provides a very flexible (not easy though) schema for describing the format on its reports.

For a simple device I'd recommend using a simple byte array usage to get started, this will give host applications to give context for your data items.

Anyway, raw reports here we go again...

Use starting_data = output_report.get_raw_data()[:] for any given output report, then change any 'raw' element directly.

Of course, ideally you'd have properly defined usage and you'd be able to change report items independently, without guessing bit widths and positions :-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top