cancel
Showing results for 
Search instead for 
Did you mean: 

HID Software for PC, How do i receive data?

darkfirefighter
Associate III
Posted on October 07, 2010 at 10:46

HID Software for PC, How do i receive data?

7 REPLIES 7
darkfirefighter
Associate III
Posted on May 17, 2011 at 14:10

Hi,

thanks for the advice! Is it better to write async? Writing async works already, but i am still not sure about reading. Do i wait with an while loop till GetOverlappedResult returns something and call then ReadFile?

regards

Posted on May 17, 2011 at 14:10

The interrupt sets an event, you wait on the event (WaitSingleObject) or use GetOverlappedResult.

http://msdn.microsoft.com/en-us/library/ms683209%28VS.85%29.aspx

For writing it's done in this fashion, reading would be similar

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>

BOOLEAN WriteFileAsync(HANDLE hFile, HANDLE hEvent, BYTE *Buffer, DWORD Length, DWORD *dwWrite, DWORD *dwError)

{

  BOOLEAN Status;

  DWORD Error;

  OVERLAPPED Overlapped;

  Overlapped.Offset = 0;

  Overlapped.OffsetHigh = 0;

  Overlapped.hEvent = hEvent;

  Status = WriteFile(hFile, Buffer, Length, dwWrite, &Overlapped);

if (Status == 0)

{

Error = GetLastError();

if (Error == ERROR_IO_PENDING)

{

Status = GetOverlappedResult(hFile, &Overlapped, dwWrite, TRUE);

if (Status == 0)

Error = GetLastError();

}

}

  if ((Status == 0) && (dwError != NULL))

    *dwError = Error;

  return(Status);

}

int main(int argc, char **argv)

{

  HANDLE hFile;

  HANDLE hEvent;

  DWORD dwWrite;

  DWORD dwError;

  BYTE Buffer[123];

  hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

hFile = CreateFile(

''FOO.BAR'',

GENERIC_WRITE, 0,

NULL, CREATE_ALWAYS,

FILE_FLAG_OVERLAPPED, NULL);

  if ((hEvent != INVALID_HANDLE_VALUE) && (hFile != INVALID_HANDLE_VALUE))

  {

    if (WriteFileAsync(hFile, hEvent, (BYTE *)&Buffer, sizeof(Buffer), &dwWrite, &dwError) == 0) // Failed

    {

      printf(''Failed, error %d\n'', dwError);

    }

    else

    {

      printf(''Success, wrote %d bytes\n'', dwWrite);

    }

  }

  if (hEvent != INVALID_HANDLE_VALUE)

CloseHandle(hEvent);

  if (hFile != INVALID_HANDLE_VALUE)

CloseHandle(hFile);

  return(0);

}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 17, 2011 at 14:10

No you would do the ReadFile(), and if it errors with ERROR_IO_PENDING you do the GetOverlappedResult() to wait for it to complete. The forth parameter TRUE, means it does the WaitForSingleObject() for you, you could do that yourself if it were FALSE. You never need to loop/poll as waiting for the event blocks your thread until it occurs or times out.

Note, it is possible that ReadFile() and WriteFile() will complete immediately. It is also possible for them not to read/write the complete amount requested, so it is important to check that dwRead/dwWrite reflect the totals you want, and retry the remainder when required (ie advance the buffer pointer, and write the remaining data)

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
darkfirefighter
Associate III
Posted on May 17, 2011 at 14:10

Ok, i have now this code:

BOOLEAN HID_ReadAsync(HANDLE hFile, HANDLE hEvent, BYTE *in_buffer, DWORD Length, DWORD *dwRead, DWORD *dwError){

    BOOLEAN         stat;

    DWORD            Error;

    OVERLAPPED  Overlapped;

    Overlapped.Offset = 0;

    Overlapped.OffsetHigh = 0;

    Overlapped.hEvent = hEvent;

    stat = ReadFile(hFile, in_buffer, Length, dwRead, &Overlapped);

    if (stat == 0){

        Error = GetLastError();

        if (Error == ERROR_IO_PENDING){

            stat = GetOverlappedResult(hFile, &Overlapped, dwRead, TRUE);

            if (stat == 0){

                Error = GetLastError();

            }

        }

    }

    if ((stat == 0) && (dwError != NULL))

        *dwError = Error;

   

    return(stat);

}

int main(){

    DWORD dwRead;

    DWORD dwError;

    BYTE    InReport[2];   

    int    stat;

    InReport[0] = 0;

    InReport[1] = 0;

    if(!(stat = HID_ReadAsync(h_device, h_event, InReport, sizeof(InReport), &dwRead, &dwError))){

        GetLastErrorTextEx(dwError);

    }

    printf(''\nInRep: %i\n\n'', InReport[1]);

    getchar();

    return stat;

}

It works, but not like i hoped.

I receive a hex code from my board, when a button is pressed.

When i call now HID_ReadAsync i only receive the code if the button is already pressed.

But i wanted, that the programm waits until the button is pressed and the continue.

Like this:

HID_ReadAsync(...)

...wait...

...button on board is pressed...

...in InReport contains now the hex code of the button...

...programm continues...

An other method would be that my programm is doing something an when a button is pressed on the board my programm is interruped and reads the hex code.

Hope you can understand what i mean.

Thanks for your great help!

regards

Mathias

Posted on May 17, 2011 at 14:10

An other method would be that my program is doing something an when a button is pressed on the board my program is interrupted and reads the hex code.

 

Windows isn't going to give you interrupts, you get Events and Messages. Consider using threads.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
picguy2
Associate II
Posted on May 17, 2011 at 14:10

After a ton of work I managed to get this kind of thing working in C#.  But the basic idea works generally.  Your USB read loop runs in a separate thread.  It makes received data available to other parts of your program via call backs, queues or whatever works the best for you and your host software tools.

darkfirefighter
Associate III
Posted on May 17, 2011 at 14:10

Working with Threads i think is to much now ^^

I solved it now that i send my board the command that i wait for data and then i allways called ReadFile till i got some data.

Thank you verry much for your great help!