This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BLE HID Multi-touch with Windows PC

Hello

I am using nRF5 SDK ver.16 to try to create a BLE HID touchscreen device.
I referenced ble_hids_mouse example and changed HID report map.
On Windows 10, it works pretty good with single-touch. However multi-touch don't work.
I was assuming the "Contact count maximum" is cause of the problem.
I followed the guide and set this feature value (Contact count maximum) is 10. But have changed nothing. 

  • How do confirm that the feature value was updated?
  • Have any other reason?

This is HID report descriptor:

static uint8_t rep_map_data[] =
{
/*--------------------------------------------------------------------------*/\
/* INPUT REPORT ID Touch                                                    */\
/*--------------------------------------------------------------------------*/\    
	0x05, 0x0D,                    // USAGE_PAGE(Digitizers)
	0x09, 0x04,                    // USAGE     (Touch Screen)
	0xA1, 0x01,                    // COLLECTION(Application)
	0x85, 0x01,  				   //   REPORT_ID
	/* Touch one */
	0x09, 0x22,                    //   USAGE (Finger)
	0xA1, 0x02,                    //   COLLECTION (Logical)     
	0x09, 0x42,                    //     USAGE (Tip Switch)
	0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
	0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
	0x75, 0x01,                    //     REPORT_SIZE (1)
	0x95, 0x01,                    //     REPORT_COUNT(1)
	0x81, 0x02,                    //     INPUT (Data,Var,Abs)
	0x95, 0x07,                    //     REPORT_COUNT (7)
	0x81, 0x03,                    //     INPUT (Cnst,Ary,Abs)
	0x09, 0x51,                    //     USAGE (Contact Identifier)
	0x75, 0x08,                    //     REPORT_SIZE (8)
	0x95, 0x01,                    //     REPORT_COUNT (1)
	0x81, 0x02,                    //     INPUT (Data,Var,Abs)
	0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
	0x09, 0x30,                    //     Usage (X)
	0x09, 0x31,                    //     Usage (Y)
	0x16, 0x00, 0x00,              //     Logical Minimum (0)
	0x26, 0x10, 0x27,              //     Logical Maximum (10000)
	0x36, 0x00, 0x00,              //     Physical Minimum (0)
	0x46, 0x10, 0x27,              //     Physical Maximum (10000)
	0x65, 0x11,                    //     Unit (Centimeter, SI-Linear)
	0x75, 0x10,                    //     Report Size (16),
	0x95, 0x02,                    //     Report Count (2),
	0x81, 0x02,                    //     Input (Data,Var,Abs)
	0xC0,                          //   END_COLLECTION  
	/* Touch two */
	0x09, 0x22,                    //   USAGE (Finger)
	0xA1, 0x02,                    //   COLLECTION (Logical)     
	0x09, 0x42,                    //     USAGE (Tip Switch)
	0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
	0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
	0x75, 0x01,                    //     REPORT_SIZE (1)
	0x95, 0x01,                    //     REPORT_COUNT(1)
	0x81, 0x02,                    //     INPUT (Data,Var,Abs)
	0x95, 0x07,                    //     REPORT_COUNT (7)
	0x81, 0x03,                    //     INPUT (Cnst,Ary,Abs)
	0x09, 0x51,                    //     USAGE (Contact Identifier)
	0x75, 0x08,                    //     REPORT_SIZE (8)
	0x95, 0x01,                    //     REPORT_COUNT (1)
	0x81, 0x02,                    //     INPUT (Data,Var,Abs)
	0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
	0x09, 0x30,                    //     Usage (X)
	0x09, 0x31,                    //     Usage (Y)
	0x16, 0x00, 0x00,              //     Logical Minimum (0)
	0x26, 0x10, 0x27,              //     Logical Maximum (10000)
	0x36, 0x00, 0x00,              //     Physical Minimum (0)
	0x46, 0x10, 0x27,              //     Physical Maximum (10000)
	0x65, 0x11,                    //     Unit (Centimeter, SI-Linear)
	0x75, 0x10,                    //     Report Size (16),
	0x95, 0x02,                    //     Report Count (2),
	0x81, 0x02,                    //     Input (Data,Var,Abs)
	0xC0,                          //   END_COLLECTION  
	/* Scan time */
	0x55, 0x0C,                    //   UNIT_EXPONENT (-4)           
	0x66, 0x01, 0x10,              //   UNIT (Seconds)
	0x35, 0x00,                    //   PHYSICAL_MINIMUM (0)
	0x47, 0xff, 0xff, 0x00, 0x00,  //   PHYSICAL_MAXIMUM (65535)
	0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
	0x27, 0xff, 0xff, 0x00, 0x00,  //   LOGICAL_MAXIMUM (65535) 
	0x75, 0x10,                    //   REPORT_SIZE (16)             
	0x95, 0x01,                    //   REPORT_COUNT (1) 
	0x09, 0x56,                    //   USAGE (Scan Time)
	0x81, 0x02,                    //   INPUT (Data,Var,Abs) 
	/* Contact count */
	0x09, 0x54,                    //   USAGE (Contact count)
	0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
	0x25, 0x0A,                    //   LOGICAL_MAXIMUM (10)
	0x75, 0x08,                    //   REPORT_SIZE (8)
	0x95, 0x01,                    //   REPORT_COUNT(1)
	0x81, 0x02,                    //   INPUT (Data,Var,Abs)
/*--------------------------------------------------------------------------*/\
/* FEATURE REPORT ID Max Contact                                            */\
/*--------------------------------------------------------------------------*/\    
	0x85, 0x03,   				   //   REPORT_ID
	0x09, 0x55,                    //   USAGE(Contact Count Maximum)
	0x25, 0x0A,                    //   LOGICAL_MAXIMUM (10)
	0x95, 0x01,                    //   REPORT_COUNT(1)
	0x75, 0x08,                    //   REPORT_SIZE (8)
	0xB1, 0x02,                    //   FEATURE (Data,Var,Abs)
/*--------------------------------------------------------------------------*/\
/* FEATURE REPORT ID Microsoft signature                                    */\
/*--------------------------------------------------------------------------*/\  
	0x85, 0x44,    				   //   REPORT_ID
	0x06, 0x00, 0xff,              //   USAGE_PAGE (Vendor Defined) 
	0x09, 0xC5,                    //   USAGE (Vendor Usage 0xC5)    
	0x15, 0x00,                    //   LOGICAL_MINIMUM (0)          
	0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (0xff) 
	0x75, 0x08,                    //   REPORT_SIZE (8)             
	0x96, 0x00, 0x01,              //   REPORT_COUNT (0x100 (256))             
	0xb1, 0x02,                    //   FEATURE (Data,Var,Abs) 
	0xC0                           // END_COLLECTION
};

Thank you

  • Hi

    I helped out with a similar case some time ago, and provided a modified version of the ble_hids_mouse example to try to implement multi touch functionality:
    https://devzone.nordicsemi.com/f/nordic-q-a/38587/is-multi-touch-hid-possible-with-nrf51822-chip

    The example can be found here:
    ble_app_hids_mouse.zip

    Please note that this example was made for nRF5 SDK v15.2.0, but you should be able to implement the changes in later versions of the SDK if needed. 

    The report descriptor used looks like this:

            0x05, 0x0D,        // Usage Page (Digitizer)
            0x09, 0x04,        // Usage (Touch Screen)
            0xA1, 0x01,        // Collection (Application)
            0x85, 0x01,        //   Report Id 1
            0x09, 0x22,        //   Usage (Finger)
            0xA1, 0x02,        //   Collection (Logical)
            0x09, 0x42,        //     Usage (Tip Switch)
            0x15, 0x00,        //     Logical Minimum (0)
            0x25, 0x01,        //     Logical Maximum (1)
            0x75, 0x01,        //     Report Size (1)
            0x95, 0x01,        //     Report Count (1)
            0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0x09, 0x30,        //     Usage (Tip Pressure)
            0x25, 0x7F,        //     Logical Maximum (127)
            0x75, 0x07,        //     Report Size (7)
            0x95, 0x01,        //     Report Count (1)
            0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0x09, 0x51,        //     Usage (0x51 - Contact identifier)
            0x26, 0xFF, 0x00,  //     Logical Maximum (255)
            0x75, 0x08,        //     Report Size (8)
            0x95, 0x01,        //     Report Count (1)
            0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
            0x09, 0x30,        //     Usage (X)
            0x09, 0x31,        //     Usage (Y)
            0x26, 0xFF, 0x7F,  //     Logical Maximum (32767)
            0x65, 0x00,        //     Unit (None)
            0x75, 0x10,        //     Report Size (16)
            0x95, 0x02,        //     Report Count (2)
            0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0xC0,              //   End Collection
            0x05, 0x0D,        //   Usage Page (Digitizer)
            0x27, 0xFF, 0xFF, 0x00, 0x00,  //   Logical Maximum (65534)
            0x09, 0x56,        //   Usage (0x56 - Scan Time)
            0x75, 0x10,        //   Report Size (16)
            0x95, 0x01,        //   Report Count (1)
            0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0x09, 0x54,        //   Usage (0x54 - Contact count)
            0x25, 0x05,        //   Logical Maximum (5)
            0x75, 0x08,        //   Report Size (8)
            0x95, 0x01,        //   Report Count (1)
            0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
            0x05, 0x0D,        //   Usage Page (Digitizer)
            0x09, 0x55,        //   Usage (0x55 - Contact point maximum)
            0x25, 0x0A,        //   Logical Maximum (10)
            0x75, 0x08,        //   Report Size (8)
            0x95, 0x01,        //   Report Count (1)
            0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
            0xC0               // End Collection 

    Best regards
    Torbjørn

Related