Author Topic: Generic HID in VB with time-out errors?  (Read 14126 times)

tlauwers

  • Member
  • ***
  • Posts: 2
Generic HID in VB with time-out errors?
« on: May 20, 2011, 12:26:43 pm »
I'm trying to use the generichid_vb code as a starting point to develop a Visual BASIC .NET class for a robot I sell called the Finch (www.finchrobot.com). I'm having some trouble getting the unaltered generichid_vb program to work with my hardware.

The Finch is a USB HID device which sends and receives 8 byte reports. The full protocol is available online at http://www.finchrobot.com/usb-protocol, but essentially you send a report which includes a command followed, optionally, by configuration parameters - for example, to get the value of the accelerometer, you'd send 'A', followed by 7 zeros to pad the report. To set the motors, you'd send 'M', followed by four bytes that configure motor speed and direction. If you sent an 'A', you should expect to read a report with 4 useful bytes.

I've been using the compiled generichid program to send a command to read the light sensors ('L'), and sometimes I get the light sensor values back in a returned report. However, roughly every third time the program returns "The Attempt to read a report timed out", and then if I try sending another command, sometimes I get an error about the IASyncResult object not coming from the corresponding method, or EndRead being called multiple times.

I'm not sure what's going on, but I suspect it may have to do with the asynchronous read (fileStreamDeviceData.BeginRead). For what it's worth, though I wouldn't totally rule out hardware, we do have the robot working robustly in Java with JNA using the libhidapi library.

One other thing - the buffer size seems to default to 32 once it finds my device, but manually changing this to 8 (which is the correct size of the report) or leaving it at 32 seems to have no impact on whether the program fails.

I have "Exchange Input and Output reports" on and "Use control transfers" unchecked. I get the error regardless of whether I click send and receive data once or continuously, though I do get successful exchanges about 60% of the time.

Any help is much appreciated!

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Generic HID in VB with time-out errors?
« Reply #1 on: May 20, 2011, 12:41:13 pm »
It sounds like my code isn't handling the canceling of the read operation on timeout quite right.

Are you using ReadFile or the new version of the code that uses FileStreams?

Jan

tlauwers

  • Member
  • ***
  • Posts: 2
Re: Generic HID in VB with time-out errors?
« Reply #2 on: May 20, 2011, 02:50:34 pm »
The error occurs with both the April 2010 and new versions.

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Generic HID in VB with time-out errors?
« Reply #3 on: May 25, 2011, 03:32:09 pm »
I haven't tested this, but see:

http://rajputyh.blogspot.com/2010/04/solve-exception-message-iasyncresult.html

In FrmMain.vb, add this class variable:

Code: [Select]
Private currentAsyncResult As IAsyncResult

In Private Sub ExchangeInputAndOutputReports(), to get the returned value (currentAsyncResult), change this:

Code: [Select]
fileStreamdevicedata.BeginRead(inputReportBuffer, 0, inputReportBuffer.Length, New AsyncCallback(AddressOf GetInputReportData), inputReportBuffer)
to this:

Code: [Select]
currentAsyncResult = fileStreamdevicedata.BeginRead(inputReportBuffer, 0, inputReportBuffer.Length, New AsyncCallback(AddressOf GetInputReportData), inputReportBuffer)
In Private Sub GetInputReportData(ByVal ar As IAsyncResult), to test for the current result, change this:

Code: [Select]

fileStreamdevicedata.EndRead(ar)

tmrReadTimeout.Stop()

' Display the received report data in the form's list box.

If (ar.IsCompleted) Then

MyMarshalToForm("AddItemToListBox", "An Input report has been read.")

MyMarshalToForm("AddItemToListBox", " Input Report ID: " & String.Format("{0:X2} ", inputReportBuffer(0)))

MyMarshalToForm("AddItemToListBox", " Input Report Data:")

For count = 1 To UBound(inputReportBuffer)

' Display bytes as 2-character Hex strings.

byteValue = String.Format("{0:X2} ", inputReportBuffer(count))

MyMarshalToForm("AddItemToListBox", " " & byteValue)
MyMarshalToForm("TextBoxSelectionStart", txtBytesReceived.Text)
MyMarshalToForm("AddItemToTextBox", byteValue)

Next count

Else
MyMarshalToForm("AddItemToListBox", "The attempt to read an Input report has failed.")
Debug.Write("The attempt to read an Input report has failed")
End If



to this:
Code: [Select]
If (ar Is currentAsyncResult) Then

fileStreamdevicedata.EndRead(ar)

tmrReadTimeout.Stop()

' Display the received report data in the form's list box.

If (ar.IsCompleted) Then

MyMarshalToForm("AddItemToListBox", "An Input report has been read.")

MyMarshalToForm("AddItemToListBox", " Input Report ID: " & String.Format("{0:X2} ", inputReportBuffer(0)))

MyMarshalToForm("AddItemToListBox", " Input Report Data:")

For count = 1 To UBound(inputReportBuffer)

' Display bytes as 2-character Hex strings.

byteValue = String.Format("{0:X2} ", inputReportBuffer(count))

MyMarshalToForm("AddItemToListBox", " " & byteValue)
MyMarshalToForm("TextBoxSelectionStart", txtBytesReceived.Text)
MyMarshalToForm("AddItemToTextBox", byteValue)

Next count

Else
MyMarshalToForm("AddItemToListBox", "The attempt to read an Input report has failed.")
Debug.Write("The attempt to read an Input report has failed")
End If
End If

« Last Edit: May 25, 2011, 08:27:21 pm by Jan Axelson »