HID Sensor Example compatible with Windows8/8.1/10 built-in driver

With windows 8 and later, Microsoft introduced native support for HID Sensor Usages(0x20)1. So, on windows 8/8.1/10, similar to keyboard/mice, the USB sensors compatible with "HID Sensors Usages" do not need attitional drivers and the system will enumerate the device and install the build-in drivers automatically. This is very convenient platform for both users and developers. For users, we do not need to install any drivers or looking for drivers, the system will do that automatically. For developers, the applications can access the sensor with standard APIs provided by Microsoft2, which is well-tested and support various programming langurages.

This project is an example of temperature sensor that compatible with the "HID Sensor Usages". This project is based on a DS18B20 chip, which is very simple to build on breadboards. Please see the attached circuit:
circuit.JPG
When you successfully build this curcuit, and load the firmware, the sensor will be enumerated as a temperature sensor in your Device Manager:
DeviceManager.JPG
You can test the basic of the sensor with Sensor Diagnostic Tool, which can be found in WDK8 and later:
SensorDiagTool.JPG

The example provided by this project can be modified to other types of sensors, please see the documents3 for supported sensor types.

The first part of such a sensor is the HID report descriptor. In the report descriptor, we define two reoprts, feature report and input report. The feature is bi-directional, the sensor can send its properties to PC or PC can change the settings on sensor. The input report contains the temperature data and the status/event from sensor. PC can request the input report itself by RequestReport or the sensor can send inport report spontaneously.
Here is the report descriptor, it is long (>300 bytes), so v-usb need some modifications, see below:

PROGMEM const char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
    HID_USAGE_PAGE_SENSOR,
    HID_USAGE_SENSOR_TYPE_ENVIRONMENTAL_TEMPERATURE,
    HID_COLLECTION(Physical),
 
    //feature reports (xmit/receive)
    HID_USAGE_PAGE_SENSOR,
    // Sensor Connection Type - RO
    HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE,  
    HID_LOGICAL_MIN_8(0),
    HID_LOGICAL_MAX_8(2),
    HID_REPORT_SIZE(8),
    HID_REPORT_COUNT(1),
    HID_COLLECTION(Logical),
        HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_SEL,
        HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_ATTACHED_SEL_SEL,
        HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_EXTERNAL_SEL_SEL,
        HID_FEATURE(Data_Arr_Abs),
        HID_END_COLLECTION,
   // Reporting State - RW
    HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
    HID_LOGICAL_MIN_8(0),
    HID_LOGICAL_MAX_8(5),
    HID_REPORT_SIZE(8),
    HID_REPORT_COUNT(1),
    HID_COLLECTION(Logical),
        HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL_SEL,
        HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL_SEL,
        HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_SEL_SEL,
        HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS_SEL_WAKE_SEL,
        HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS_SEL_WAKE_SEL,
        HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_THRESHOLD_EVENTS_WAKE_SEL_SEL,
        HID_FEATURE(Data_Arr_Abs),
        HID_END_COLLECTION,
    // Power State - RW
    HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
    HID_LOGICAL_MIN_8(0),
    HID_LOGICAL_MAX_8(5),
    HID_REPORT_SIZE(8),
    HID_REPORT_COUNT(1),
    HID_COLLECTION(Logical),
        HID_USAGE_SENSOR_PROPERTY_POWER_STATE_UNDEFINED_SEL,          
        HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER_SEL,      
        HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D1_LOW_POWER_SEL,       
        HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D2_STANDBY_WITH_WAKE_SEL,
        HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D3_SLEEP_WITH_WAKE_SEL, 
        HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF_SEL,       
        HID_FEATURE(Data_Arr_Abs),
        HID_END_COLLECTION,
    // Sensor State - RW
    HID_USAGE_SENSOR_STATE,
    HID_LOGICAL_MIN_8(0),
    HID_LOGICAL_MAX_8(6),
    HID_REPORT_SIZE(8),
    HID_REPORT_COUNT(1),
    HID_COLLECTION(Logical),
        HID_USAGE_SENSOR_STATE_UNKNOWN_SEL_SEL,
        HID_USAGE_SENSOR_STATE_READY_SEL_SEL,
        HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL_SEL,
        HID_USAGE_SENSOR_STATE_NO_DATA_SEL_SEL,
        HID_USAGE_SENSOR_STATE_INITIALIZING_SEL_SEL,
        HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL_SEL,
        HID_USAGE_SENSOR_STATE_ERROR_SEL_SEL,
        HID_FEATURE(Data_Arr_Abs),
        HID_END_COLLECTION,
    // Report Interval - RW
    HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
    HID_LOGICAL_MIN_32(0x00,0x00,0x00,0x00),
    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
    HID_REPORT_SIZE(32),
    HID_REPORT_COUNT(1),
    HID_UNIT_EXPONENT(0),
    HID_FEATURE(Data_Var_Abs),
    // Minimum Report Interval  -  RO
    HID_USAGE_SENSOR_PROPERTY_MINIMUM_REPORT_INTERVAL,  
    HID_LOGICAL_MIN_32(0x00,0x00,0x00,0x00),
    HID_LOGICAL_MAX_32(0xFF,0xFF,0xFF,0xFF),
    HID_REPORT_SIZE(32),
    HID_REPORT_COUNT(1),
    HID_UNIT_EXPONENT(0),
    HID_FEATURE(Data_Var_Abs),
    // Sensor Accuracy - RO
    HID_USAGE_SENSOR_PROPERTY_ACCURACY,
    HID_LOGICAL_MIN_8(0x00),  //0   
    HID_LOGICAL_MAX_8(0xFF),  //255   
    HID_REPORT_SIZE(8),
    HID_REPORT_COUNT(1),
    HID_UNIT_EXPONENT(0x0E), // x0.01
    HID_FEATURE(Data_Var_Abs),
    // Sensor Resolution - RO
    HID_USAGE_SENSOR_PROPERTY_RESOLUTION,
    HID_LOGICAL_MIN_8(0x00),      // 0
    HID_LOGICAL_MAX_16(0xFF,0xFF),// 65535
    HID_REPORT_SIZE(16),
    HID_REPORT_COUNT(1),
    HID_UNIT_EXPONENT(0x0C), // x0.0001
    HID_FEATURE(Data_Var_Abs),
    // Range Maximum - RO
    HID_USAGE_SENSOR_PROPERTY_RANGE_MAXIMUM,
    HID_LOGICAL_MIN_8(0x00),  //0
    HID_LOGICAL_MAX_8(0xFF),  //255
    HID_REPORT_SIZE(8),
    HID_REPORT_COUNT(1),
    HID_UNIT_EXPONENT(0x00), // x1
    HID_FEATURE(Data_Var_Abs),
    // Range Minimum - RO
    HID_USAGE_SENSOR_PROPERTY_RANGE_MINIMUM,
    HID_LOGICAL_MIN_8(0x81), //-127
    HID_LOGICAL_MAX_8(0xFF), // 127
    HID_REPORT_SIZE(8),
    HID_REPORT_COUNT(1),
    HID_UNIT_EXPONENT(0x00), // x1
    HID_FEATURE(Data_Var_Abs),
    // Change Sensitivity Absolute - RW
    HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_ABS,
    HID_LOGICAL_MIN_8(0x00),  //0
    HID_LOGICAL_MAX_16(0xFF,0xFF),// 65535
    HID_REPORT_SIZE(16),
    HID_REPORT_COUNT(1),
    HID_UNIT_EXPONENT(0x0D), // x0.001
    HID_FEATURE(Data_Var_Abs),
 
    //input reports (transmit)
    HID_USAGE_PAGE_SENSOR,
    // Sensor state
    HID_USAGE_SENSOR_STATE,
    HID_LOGICAL_MIN_8(0),
    HID_LOGICAL_MAX_8(6),
    HID_REPORT_SIZE(8),
    HID_REPORT_COUNT(1),
    HID_COLLECTION(Logical),
        HID_USAGE_SENSOR_STATE_UNKNOWN_SEL_SEL,
        HID_USAGE_SENSOR_STATE_READY_SEL_SEL,
        HID_USAGE_SENSOR_STATE_NOT_AVAILABLE_SEL_SEL,
        HID_USAGE_SENSOR_STATE_NO_DATA_SEL_SEL,
        HID_USAGE_SENSOR_STATE_INITIALIZING_SEL_SEL,
        HID_USAGE_SENSOR_STATE_ACCESS_DENIED_SEL_SEL,
        HID_USAGE_SENSOR_STATE_ERROR_SEL_SEL,
        HID_INPUT(Data_Arr_Abs),
        HID_END_COLLECTION,
    // Sensor Events 
    HID_USAGE_SENSOR_EVENT,
    HID_LOGICAL_MIN_8(0),
    HID_LOGICAL_MAX_8(16),
    HID_REPORT_SIZE(8),
    HID_REPORT_COUNT(1),
    HID_COLLECTION(Logical),
        HID_USAGE_SENSOR_EVENT_UNKNOWN_SEL_SEL,
        HID_USAGE_SENSOR_EVENT_STATE_CHANGED_SEL_SEL,
        HID_USAGE_SENSOR_EVENT_PROPERTY_CHANGED_SEL_SEL,
        HID_USAGE_SENSOR_EVENT_DATA_UPDATED_SEL_SEL,
        HID_USAGE_SENSOR_EVENT_POLL_RESPONSE_SEL_SEL,
        HID_USAGE_SENSOR_EVENT_CHANGE_SENSITIVITY_SEL_SEL,
        HID_INPUT(Data_Arr_Abs),
        HID_END_COLLECTION,
    // Temperature data.
    HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE,
    HID_LOGICAL_MIN_16(0x01,0x80), //    LOGICAL_MINIMUM (-32767)
    HID_LOGICAL_MAX_16(0xFF,0x7F), //    LOGICAL_MAXIMUM (32767)
    HID_REPORT_SIZE(16),
    HID_REPORT_COUNT(1),
    HID_UNIT_EXPONENT(0x0E), // x0.01
    HID_INPUT(Data_Var_Abs),
 
    HID_END_COLLECTION
 
};

Because the length of report descriptor is greater than 255, we need to change following part in usbdrv.c
Line 172:
        USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH, 0,  /* total length of report descriptor */

To:
    (USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH)&0xFF, ((USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH) >> 8)&0xFF,

With the correct report descriptor, the sensor now can be recognized by windows. For the implement of other functions, I will post and upload other details later.

Thanks for viewing!

For a complete list of projects based on V-USB see Objective Development's projects list.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License