Hi Roman,
I've run into a problem when sending multiple reports to a device in fast succession. If you remember, I am writing to a printer and I need to send the data in 256byte reports.
I have found a problem when sending reports (The test I'm doing requires 4 reports of the same reportId) with no delay between them causes the printed output
to be corrupted. When I put a 100m/s pause between the reports the printing works fine.
I repeatedly check to see if the device is busy / cannot recieve data as I am writing the reports and I am 100% confident that the device is not going into a busy state.
I sent a demo app to the manufacturer and they were able to perform a USB trace to debug the problem. It seems that bytes are being lost when sending reports without a pause . My best guess is nrHID has not completed when it is called upon to transmit again and some of the bytes are not reaching the printer.
I don't want to have to use 100m/s delay between each report as this will badly effect print performance. Is there any way of determining if nrHID has written all the data and can send more? I presume this is / should be handled internally by the component
Thanks for your help
Chris Hedges
Hello Chris
I remember that you are using TnrHid.SendData() method for send reports. This function is asynchronous.
You can try to replace it by TnrHid.WriteReport() call.
Roman Novgorodov
DeepSoftware.Com
Hi Roman,
I used to use the WriteReport method but when I upgraded to the 8.21 version it stopped working for me, hence the switch to SendData.
I've tried using HidD_SetOutputReport and that doesn't seem to work either. What changed in the upgrade that stopped the WriteReport working?
thanks
Chris
Hello
Yes you are right.
The WriteReport() method was changed.
It uses HidD_SetOutputReport() API call now.
But your device works strange: it works good with HidD_GetInputReport() and it should support HidD_SetOutputReport() correctly too.
I will think more.
Do you remember, you showed me a VB sample that is read a HID report?
Do you have such sample from printer manufacturer that writes report?
Please try it to test device and be sure that device is working properly.
Roman Novgorodov
DeepSoftware.Com
Hi Roman,
Here is the VB code used to write to the printer. This works ok.
Public Sub Transmit(text_data As String)
Dim NumberOfBytesWritten As Long
Dim SendBuffer() As Byte
Dim i, Count As Integer
Dim pData As Long
ReDim SendBuffer(0 To (Capabilities.OutputReportByteLength - 1)) As Byte
' Check the USB pointer for readiness
If WriteHandle = 0 Then
Display_Text ("Unable to write to Boca Systems USB Printer. Invalid write handle.")
Else
'Display_Text ("A Boca Systems USB Printer has been located")
'This string needs to be converted into a byte array of ascii
'integers to send to the printer. Convert will also initilize
'ptr_buffer and Str_Size.
Count = Len(text_data)
Call Convert(text_data)
'For i = 1 To Count
' SendBuffer(i) = Asc(Mid(text_data, i, 1))
'Next i
'The first byte is the Report ID
For i = 0 To Capabilities.OutputReportByteLength - 1
SendBuffer(i) = 0
Next i
For i = 1 To Capabilities.OutputReportByteLength - 1
SendBuffer(i) = text(i - 1) 'text_data(i - 1)
Next i
'SendBuffer(0) = 0
'For i = 1 To Count
' SendBuffer(i) = text(i - 1)
'Next i
'Display_Text ("string size = " + str(Str_Size))
'Write converted text string and read for status response
'Need to convert these to functions to receive return values as Longs???
NumberOfBytesWritten = 0
Result = WriteFile _
(WriteHandle, _
SendBuffer(0), _
CLng(Capabilities.OutputReportByteLength), _
NumberOfBytesWritten, _
0)
End If
End Sub
Hello Chris
The old version of TnrHid.WriteReport() used WriteFile call :-).
Now this method uses HidD_SetOutputReport() function.
Your device is real strange.
It uses HidD_GetInputReport() for read HID reports (and does not work with ReadFile())
At same time your printer wants WriteFile() for send report and does not support HidD_SetFeature() function.
OK.
We will think something more and will add new methods into TnrHid component.
Whilst I recommend you to call WriteFile like in your VB sample with TnrHid.Handle parameter.
Roman Novgorodov
DeepSofware.Com
Thanks for you help again Roman,
You have to love a challenge, especially when it's your first HID project ;)
Nothing is ever easy!
Hi Roman,
I'm getting a wierd Error 87 (Parameter is incorrect) when using the WriteFile method.
Have you seen this error before as the method itself looks pretty straightforward?
procedure TForm6.NewHIDWrite(Data : String);
var
ToWrite, NumberOfBytesWritten: Cardinal;
cnt : integer;
Report : Array of Byte;
begin
ToWrite := nrHid1.HidDevice.OutputReportLength;
SetLength(Report, ToWrite);
//init the buffer
for cnt := 0 to ToWrite - 1 do
Report[cnt] := 0;
//fill it!
for cnt := 1 to Length(Data) do
Report[cnt] := Ord(Data[cnt]);
NumberOfBytesWritten := 0;
if not WriteFile(nrHID1.Handle, Report, ToWrite, NumberOfBytesWritten, 0) then
ShowMessage(SysErrorMessage(GetLastError));
end;
Hello Chris
You can try the following:
WriteFile(nrHID1.Handle, Report[0], ToWrite, NumberOfBytesWritten, 0)
But usual we are using Pointer or PChar variable for second parameter of this function.
By the way the new version of nrComm Lib is released.
It has some changes - new methods:
function ReadReport(const pcReport:pointer; const ReportSize:cardinal):boolean;
function WriteReport(const pcReport: pointer; const ReportSize:cardinal):boolean;
function GetInputReport(const pcReport:pointer; const ReportSize:cardinal):boolean;
function SetOutputReport(const pcReport: pointer; const ReportSize:cardinal):boolean;
Please ask me over email and you will receive latest release.
Roman Novgorodov
DeepSoftware.Com
Thanks Roman,
The new version of WriteReport seems to be working perfectly
Thanks again for helping me out :)
Chris.