VB.net

iHID

iHID

Postby Graham » Wed Nov 04, 2009 12:43 am

A handy little program that allows you to connect to the desired USB HID device and view incoming reports, state changes and send reports.

Either download the source code or compiled program for the USB HID program to have a look how it can be used. The program itself (iHID) is a handy tool for sending/receiving report packets to your micro controller. It will auto update to any future updates should they arise;
Image

Download the VB2008 project files (source code) here - need to be logged in to download. There are two folders in the archive, Swordfish Code and VB.net Code.

To use either the compiled/source code you will need to Extract mcHID.dll to C:\Windows\System32 (mcHID.dll is located in the root directory of the source code files linked above).

To create a HID compatible program in SF, simply click Plugin > Swordfish > EasyHID and setup the options. Be sure to record the VendorID, ProductID, BufferIn/BufferOut sizes - you will need them for the PC HID program. The above source code has a working model ready to use. More below;
User avatar
Graham
Moderator
Moderator
 
Posts: 618
Joined: Wed Apr 01, 2009 10:34 pm

Re: iHID

Postby Graham » Wed Nov 04, 2009 10:01 pm

Some more info on USB as the above post was a little short 8-)

USB works quite differently to your conventional serial data. Information is sent in packets known as 'Reports'. You can't send half a report, the whole report is sent/received regardless of what parts you have populated. Each report is made up of X bytes. The above program is set to 32 Bytes per report.

VB.net Application Notes:
While this post just covers the basic use, a full working model can be downloaded from the first post.

mcHID.dll provides a number of useful events such as;
Code: Select all
Public Sub OnPlugged(ByVal pHandle As Integer)
Public Sub OnUnplugged(ByVal pHandle As Integer)
Public Sub OnRead(ByVal pHandle As Integer)

Download the source code to see how to use each in more detail. The basic guide for connecting to a device;
a) Copy the form "mcHIDInterface.vb" from the example project to your application.
b) Configure the default parameters (VendorID, ProductID, BufferInSize, BufferOutSize)
c) Call "ConnectToHID(Me.Handle)" to catch all messages/events for the desired device.
d) Wait for "OnPlugged" event to trigger. This means the selected device is physically connected and ready.
e) Handle "OnRead" events to parse new reports, and send reports as desired.

Of note there is that OnRead will only trigger when a complete report has been received. The first element of a report is BufferIn(0), it should always = 0, and there for can be omitted when parsing the report data. For example, the first element is skipped and parsing begins from BufferIn(1) in the following code;
Code: Select all
    For i = 1 To BufferInSize
        tmpByte = BufferIn(i)
        ' Do something with the byte...
        '
    Next

Transmitting reports is a little different, though quite simple. The BufferOut must first be filled and then you can evoke the transmission of the report. For example;
Code: Select all
BufferOut(0) = 0
For i = 1 To BufferOutSize
    BufferOut(i) = CByte(lstReport.Items(i - 1))
Next

' Get the handle and send report
Dim pHandle As Integer
pHandle = hidGetHandle(VendorID, ProductID)
hidWriteEx(VendorID, ProductID, BufferOut(0))

You probably missed it, but to evoke a report transmission you call "hidWriteEx(VendorID, ProductID, BufferOut(0))" after the buffer is populated with data. Note that Buffer(0) will always = 0. The next 32 elements are the report bytes that can be anything.

Once again, a working VB.net solution can be found in the source code.

Swordfish Application Notes:
To create a HID compatible program in SF, simply click Plugin > Swordfish > EasyHID and setup the options. By default, there are quite a few different examples of how to use the USB library. Download the pre-made SF iHID program to view a working model.

The first agenda is to setup the in/out buffers. There are two methods of doing this, one is using Arrays and the other is by using the default report buffer RAM allocation. This project focuses on the use of Array type buffers. Consider the setup for BufferOut;
Code: Select all
Dim BufferOut(32) As Byte Absolute TXReportRAM

Notice the Absolute keyword followed by TXReportRAM. This will force the compiler to overlay the array at the reports TX report buffer location. Now we can access the report like any other variable

Now ensure the PIC is connected to the USB network;
Code: Select all
Repeat
Until Attached

The output report buffer is referred to how it was declared (in this case "Dim BufferOut(32) as Byte"). Here's an example of filling the report Buffer and transmitting it;
Code: Select all
// connect to USB...
Repeat
Until Attached

While True
   For i = 0 To 31   
        BufferOut(i) = i
   Next
   
   WriteArray(BufferOut,32)
   
   DelayMS(1000)
Wend

The input report buffer is declared in the following format;
Code: Select all
Dim BufferIn(32) As Byte Absolute RXReportRAM

Once again, notice the Absolute keyword followed by RXReportRAM. This will force the compiler to overlay the array at the reports RX report buffer location. Now we can access the report like any other variable, for example;
Code: Select all
Dim BufferIn(32) As Byte Absolute RXReportRAM
.
.
// check for new report
If DataAvailable Then
  ReadReport
  // send each byte of the report via USART
  For i = 0 To 31
    DisableISR      // disable USB interrupt handling for timing critical events
                    //  note: if more than 1mS elapses then USB will be disconnected.
                    //        call Service() to refresh USB connection before that happens.
    USART.Write(DecToStr(BufferIn(i)),13,10)
    EnableISR       // enable USB interrupt handling
  Next
EndIf

The above code brings another very important concept to play. USB is a polled protocol which needs to be serviced every 1 millisecond or so. This is to ensure the connection between the microcontroller and PC is maintained and any transactions are handled.

If the USB_SERVICE is enabled (which it is by default) then the module will service the USB connection using interrupts. However, you may have a critical section of code that should not be disturbed. For example, a software based serial read or write may will have exact timing requirements. You don't want an interrupt firing during this time, else these timing will be disturbed and the routines may fail. You can temporarily disable interrupt servicing by calling DisableISR(). When you have finished, enable the interrupt by calling EnableISR().

USART is very timing specific, especially at 115200 baud, hence the USB interrupt handle was disabled during the above code.
User avatar
Graham
Moderator
Moderator
 
Posts: 618
Joined: Wed Apr 01, 2009 10:34 pm

Re: iHID

Postby Graham » Sat Nov 07, 2009 11:08 pm

Made a couple of updates to the GUI and streamlined the downloadable content to the main site (makes it a lot easier to update)

Updated the source code with a few more comments as well, should you find your self wondering what's going on ;)
User avatar
Graham
Moderator
Moderator
 
Posts: 618
Joined: Wed Apr 01, 2009 10:34 pm

Re: iHID

Postby Graham » Sat Jan 09, 2010 2:13 am

Update: Changed project files to be compatible with VB2008 Express
User avatar
Graham
Moderator
Moderator
 
Posts: 618
Joined: Wed Apr 01, 2009 10:34 pm

Re: iHID

Postby rickeybell » Sat Feb 06, 2010 8:28 am

Just so you know, you are my hero!!!!!!! :D :D I have been working on about the same program all day. Thanks for sending me in the right direction.

Rickey Bell
Paramedic
User avatar
rickeybell
Active Member
Active Member
 
Posts: 1
Joined: Sat Feb 06, 2010 8:09 am

Re: iHID

Postby Graham » Fri Mar 12, 2010 7:04 pm

Update: Thanks to AndyO's feedback via a PM, a bug has been removed from the SF Code.
User avatar
Graham
Moderator
Moderator
 
Posts: 618
Joined: Wed Apr 01, 2009 10:34 pm


Return to VB.net

Site Login