The human interface device (HID) class is a specific class of USB devices for which most operating systems maintain an internal driver. Thus, for these types of devices, no driver need be distributed, downloaded or installed. The most common types of HID's are keyboards and mice, athough these are a special case (see below).
HID USB communication explained
The transfer of data under USB is performed using so-called 'reports'. These can be defined as 'in' or 'out' reports from the point of view of the host. Each USB device has a number of 'endpoints' which are really just memory buffers where data is accumulated during a transfer. When a USB host (normally a PC) executes a transfer, a report is delivered to (or read from) the endpoint of the USB device. When a transfer is complete, the report data can be read from the endpoint and acted upon.
Under USB, communications fall into three broad categories, called transfers:
Bulk transfers - Typically used for larger amounts of data for which timing is not such an issue. A good example of this is for flash drives, cameras etc. These transfer types are given the lowest priority on the bus.
Interrupt transfers - Despite the name, these are really periodic data packets, rather than interrupts in the context of firmware. The HID device class uses interrupt transfers exclusively for user data. The HID device firmware specifies a period between transfers in milliseconds, with 1ms being the shortest (ie highest frequency).
Control transfers - Used during the enumeration and handshaking phases of the communication. These transfers may also include a keep-alive transfer which is designed to allow the operating system to maintain control over which devices are connected and/or suspended.
The length of HID reports is defined by the device itself. they can be any size up to 64 bytes. In reality, the packet is longer than this as it contains other information. By the time it has been decoded and made available to the user's code, it is one byte longer than expected. This extra byte is included as the first byte of a HID report is always '0'.
Keyboards and mice
These devices cannot be interfaced using the win32 API. They are hidden from the API by the operating system, to avoid any conflict. For most applications, this is not an issue as keyboard and mouse events can generally be captured without needing focus. It does however seem to cause problems for people who are using barcode scanners, which generally enumerate as a keyboard. Again, the way around this is to capture keyboard events
Simple C# USB interface source code
This HID class package includes a sample program which finds the available devices, connects to one of them and performs a read/write operation before closing the connection. Download the full source here.
Features
- Fully documented source code with xml comments for Intellisense in Visual Studio
- Synchronous and asynchronous read/write functions (see below for translation)
- Function to return data pertinent to all HID devices connected to the PC (USB PID/VID, serial number, product strings, report lengths etc)
- All win32 API interface calls
- Compatable with Windows XP, Vista, 7
Source code example
The following code shows how simple the implementation of this class is. First we get a list of the available devices, then create a handle to one of them. We can then execute as many read/write functions as we like, before closing the object. It really could not be simpler!
//Get the details of all connected USB HID devices
HIDDevice.interfaceDetails[] devices = HIDDevice.getConnectedDevices();
//Select a device from the available devices
string devicePath = devices[selectedDeviceIndex].devicePath;
//create a handle to the device by calling the constructor
HIDDevice device = new HIDDevice(devicePath, false);
//Write a byte array to the device
byte[] writeData = { 0x00, 0x01, 0x02, 0x03, 0x04 };
device.write(writeData); //Its that easy!!
//Read a byte array from the device
byte[] readData = device.read(); //again, that easy!
//close the device to release all handles etc
device.close();
Feature Description
Synchronous Read / Write
This is the simplest way to communicate with any HID device, the read method (byte[] read()) is called, which blocks the calling thread until the data is available. For most HID devices this is 1 - 20ms. When data becomes available, this method returns the packet which was delivered by the device. Easy huh?
Asynchronous Read
If your software is required to react to random events created by your HID device, asynchronous operation is reccomended. A simple callback method is all that is required in your program to handle these events. All the low level interaction is taken care of by our HID interface class. Still easy.








