Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Custom HID and Sensor example for nRF5 SDK 15.x

Hi,

I had some troubles getting a custom HID device to work that has both input and output reports to Windows 10 host. Here is my working example template that might save some time for others attempting something similar.

https://github.com/tikonen/ble_app_hids_custom

This implements

  • Custom BLE HID device that has both an output and input report. Tested to work with Windows 10. I used Win32 API SetupDiEnumDeviceInterfaces+SetupDiGetDeviceInterfaceDetail to find the device path. Device path can be opened CreateFile. Reports can be read/received simply via WriteFile and ReadFile
  • Delayed I2C read from si7021 sensor (this sensor requires wait of 25ms before data is ready to read)
  • GPIO interrupt triggered reading from sensor

Thanks!

Parents
  • Thank you Tikonen!

    I am currently developing a BLE HID composite device, consisting of a standard keyboard, a standard mouse and a custom HID device.

    On the device side, I have managed to implement everything and it seems to work: keyboard and mouse work as expected, and I can see the custom HID data with an nRF sniffer.

    My problem is that I can't find out how to access (on the PC side) the data exchanged with the custom HID device.

    May I kindly ask you if you can share some more details about your code on Windows? Would you perhaps be willing to share the piece of source code, like you did with your Nordic chip firmware?

    What SDK are you using to develop the Windows application? (I use Xamarin).

    Thanks in advance!

  • This answer probably comes too late but for anybody who comes here by google:

    Windows 10 does not allow anymore direct access to certain devices (Mouse and Keyboard namely) for security reasons. However, it's still possible to send and receive raw HID packets for many device classes, at least vendor specific. There are quite good examples in MSDN but essentially you look up device path (based on vendor and device id) by using SetupDiEnumDeviceInterfaces and then call CreateFile to open the device. Then simpy call WriteFile and ReadFile. Here are some example snippets.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <SetupAPI.h>
    #include <hidsdi.h>
    #include <usbiodef.h>
    #include <fileapi.h>
    #include <Cfgmgr32.h>
    #include <initguid.h>
    #include <hidclass.h>
    void listHidDevices()
    {
    CONFIGRET cr = CR_SUCCESS;
    PWSTR DeviceInterfaceList = NULL;
    ULONG DeviceInterfaceListLength = 0;
    do {
    cr = CM_Get_Device_Interface_List_Size(&DeviceInterfaceListLength, (LPGUID)&GUID_DEVINTERFACE_HID, NULL, CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES);
    if (cr != CR_SUCCESS) {
    break;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Reply
  • This answer probably comes too late but for anybody who comes here by google:

    Windows 10 does not allow anymore direct access to certain devices (Mouse and Keyboard namely) for security reasons. However, it's still possible to send and receive raw HID packets for many device classes, at least vendor specific. There are quite good examples in MSDN but essentially you look up device path (based on vendor and device id) by using SetupDiEnumDeviceInterfaces and then call CreateFile to open the device. Then simpy call WriteFile and ReadFile. Here are some example snippets.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <SetupAPI.h>
    #include <hidsdi.h>
    #include <usbiodef.h>
    #include <fileapi.h>
    #include <Cfgmgr32.h>
    #include <initguid.h>
    #include <hidclass.h>
    void listHidDevices()
    {
    CONFIGRET cr = CR_SUCCESS;
    PWSTR DeviceInterfaceList = NULL;
    ULONG DeviceInterfaceListLength = 0;
    do {
    cr = CM_Get_Device_Interface_List_Size(&DeviceInterfaceListLength, (LPGUID)&GUID_DEVINTERFACE_HID, NULL, CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES);
    if (cr != CR_SUCCESS) {
    break;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Children
No Data