USB HID and C++



The AHid.dll allows you to transfer data between an USB Host and a HID device. Based on a sample application, we show you the required steps to connect your device to Windows. Figure 1 presents the GUI of the sample application.

The buttons are used to connect to the device, to send data to it and to reset the transfer counters.

The application is partitioned in three sections. The Device part displays values that are used for Input and Output Reports as well. It includes the Vendor ID, the Product ID, the Interface ID and the GUID of your device. The Vendor ID and the Product ID are given hexadecimal. This allows a direct link to the GUID (compare to figure 1). All other values are given decimal (except for Data). The Interface ID holds the interface number. Often an USB HID device has only a single interface and does not make use of this number. This is expressed by setting the Interface ID to -1 (no interface).

Figure 1: GUI to send and receive data from PC to USB HID device and back.

The Output part is all about transferring data from Host to device. In figure 1, the Report ID is set to 0 and the value for the Report size is 32. The Report size is part of the Report Descriptor of the firmware of any USB HID device. The value of 0 for the Report ID also arises from the Report Descriptor. Whenever the Report ID is omitted in the Report Descriptor, a value of 0 is preconditioned.

The Input part is concerned with the data reception from the device. Report Size and ID follows the criteria listed in the Output part.


The usage of AHid.dll is always the same.

First, you have to make a call to AHid_init() to initialize the driver (figure 2). The next step includes the configuration (registration) of the transfer pipes. This is done by AHid_register(). The data transfer between Host and device can start now. The required parameters of AHid_register() are also part of the Report Descriptor.

Figure 2: Initialisation of the DLL with AHid_init() and registration / deregistration of the data pipes with AHid_register() and AHid_deregister().

The connection state is tracked by the AHid_find() function (figure 3). Its states are ATTACHED or REMOVED. In most cases (maybe in all cases) it is less relevant how fast a change in these values is displayed. It is therefore enough to call AHid_find() less frequently, maybe every few seconds might do it. The sample application is using a timer callback function with a resolution of 1 Herz.

Figure 3: Tracking the connection state with AHid_find() and requesting the GUID with AHid_identify().

The function AHid_identify() reads the GUID of an USB HID device (figure 3). The GUID is only required if you use several devices with AHid.dll at the same time and if you want to combine the Input and Output pipes of each individual device. All transfer pipes of a device have the same GUID. The pipes of other devices have different GUIDs.

You can send data by using the AHid_write() function (figure 4). At first, the data to write is extracted from the corresponding Edit Control. Afterwards, the data is written once or several times depending on the loop counter (figure 1).

Figure 4: Send data to your device with AHid_write().

Data reception is done by AHid.dll absolutely independent from you application. That means, even if you don't call AHid_read(), the data itself is not missed or lost. AHid.dll buffers all - as long as there is memory available.

Figure 5: Read data from your device with AHid_read().

It does not really matter if you call AHid_read() only every 100 milliseconds, as it is done in the sample application using a timer callback. The only thing to do make sure is to read the maximum amount of bytes possibly arriving meanwhile. Assuming a maximum transfer rate of one data packet each millisecond with Low and Full Speed USB and a callback interval of 100 milliseconds (depending on timer initialization), you have to read up to 100 data packets (one per millisecond). And exactly this is done in figure 5.