PORTS Forum
Ports and Interfaces => USB => Topic started by: tlauwers 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!
-
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
-
The error occurs with both the April 2010 and new versions.
-
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:
Private currentAsyncResult As IAsyncResult
In Private Sub ExchangeInputAndOutputReports(), to get the returned value (currentAsyncResult), change this:
fileStreamdevicedata.BeginRead(inputReportBuffer, 0, inputReportBuffer.Length, New AsyncCallback(AddressOf GetInputReportData), inputReportBuffer)
to this:
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:
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:
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