查看: 7850|回复: 15

[已解决] Leonardo做USB HID Device实现多点触控的问题

[复制链接]
  • TA的每日心情
    无聊
    2017-1-24 10:00
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    发表于 2015-9-29 23:18 | 显示全部楼层 |阅读模式
    问题简述:怎么用Leonardo实现USB HID协议下的多点触控设备。

    萌新的我在看过官方的鼠标库和鼠标demo之后,打算按照鼠标库的实现方法,利用HID.h库制作一个能实现多点触控的设备。按照微软的文章写好了报告描述符,现在电脑(Windows7 旗舰版)能正常识别出设备,但是只能被识别为单点触控设备。连接到手机上(安卓,OTG)也是只能识别出一个触摸点的信息,报告后面第二个触摸点的信息就被忽略了。所以来论坛里求助一下,不知道是哪里出的问题。

    以下是报告描述符和相关的函数。希望论坛里的大大们给解答一下,怎么才能成功被识别为多点触控设备。

    报告描述符:

    kittenblock中小学创客名师推荐的图形化编程软件

    static const uint8_t _hidReportDescriptor[] PROGMEM = {
        0x05, 0x0d,                 // USAGE_PAGE (Digitizers)
        0x09, 0x04,                 // USAGE (Touch Screen)
        0xa1, 0x01,                 // COLLECTION (Application)
        0x85, REPORTID_MTOUCH,      //   REPORT_ID (Touch)
        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)
        0x09, 0x32,                 //       USAGE (In Range)
        0x81, 0x02,                 //       INPUT (Data,Var,Abs)
        0x95, 0x06,                 //       REPORT_COUNT (6)
        0x81, 0x03,                 //       INPUT (Cnst,Ary,Abs)
        0x75, 0x08,                 //       REPORT_SIZE (8)
        0x09, 0x51,                 //       USAGE ( Contact Identifier)
        0x95, 0x01,                 //       REPORT_COUNT (1)
        0x81, 0x02,                 //       INPUT (Data,Var,Abs)
        0xa1, 0x00,                 //       COLLECTION (Physical)
        0x05, 0x01,                 //          USAGE_PAGE (Generic Desk..
    //    0x26, 0xff, 0x0f,           //          LOGICAL_MAXIMUM (4095)
        0x75, 0x10,                 //          REPORT_SIZE (16)
        0x55, 0x00,                 //          UNIT_EXPONENT (0)
        0x65, 0x00,                 //          UNIT(None)
    //    0x55, 0x0e,                 //          UNIT_EXPONENT (-2)
    //    0x65, 0x33,                 //          UNIT(Inch,EngLinear)
        0x09, 0x30,                 //          USAGE (X)
        0x26, 0x38, 0x04,           //          LOGICAL_MAXIMUM (1080)
        0x35, 0x00,                 //          PHYSICAL_MINIMUM (0)
        0x46, 0x38, 0x04,           //          PHYSICAL_MAXIMUM (1080)
        0x81, 0x02,                 //          INPUT (Data,Var,Abs)
        0x09, 0x31,                 //          USAGE (Y)
        0x46, 0x80, 0x07,           //          PHYSICAL_MAXIMUM (1920)
        0x26, 0x80, 0x07,           //          LOGICAL_MAXIMUM (1920)
        0x81, 0x02,                 //          INPUT (Data,Var,Abs)
        0x45, 0x00,                 //          PHYSICAL_MAXIMUM (0)reset
        0xc0,                       //       END_COLLECTION
        0xc0,                       //    END_COLLECTION
        //------------------------------------------
        0x05, 0x0d,                 //    USAGE_PAGE (Digitizers)
        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)
        0x09, 0x32,                 //       USAGE (In Range)
        0x81, 0x02,                 //       INPUT (Data,Var,Abs)
        0x95, 0x06,                 //       REPORT_COUNT (6)
        0x81, 0x03,                 //       INPUT (Cnst,Ary,Abs)
        0x75, 0x08,                 //       REPORT_SIZE (8)
        0x09, 0x51,                 //       USAGE ( Contact Identifier)
        0x95, 0x01,                 //       REPORT_COUNT (1)
        0x81, 0x02,                 //       INPUT (Data,Var,Abs)
        0xa1, 0x00,                 //       COLLECTION (Physical)
        0x05, 0x01,                 //          USAGE_PAGE (Generic Desk..
        //    0x26, 0xff, 0x0f,           //          LOGICAL_MAXIMUM (4095)
        0x75, 0x10,                 //          REPORT_SIZE (16)
        0x55, 0x00,                 //          UNIT_EXPONENT (0)
        0x65, 0x00,                 //          UNIT(None)
        //    0x55, 0x0e,                 //          UNIT_EXPONENT (-2)
        //    0x65, 0x33,                 //          UNIT(Inch,EngLinear)
        0x09, 0x30,                 //          USAGE (X)
        0x26, 0x38, 0x04,           //          LOGICAL_MAXIMUM (1080)
        0x35, 0x00,                 //          PHYSICAL_MINIMUM (0)
        0x46, 0x38, 0x04,           //          PHYSICAL_MAXIMUM (1080)
        0x81, 0x02,                 //          INPUT (Data,Var,Abs)
        0x09, 0x31,                 //          USAGE (Y)
        0x46, 0x80, 0x07,           //          PHYSICAL_MAXIMUM (1920)
        0x26, 0x80, 0x07,           //          LOGICAL_MAXIMUM (1920)
        0x81, 0x02,                 //          INPUT (Data,Var,Abs)
        0x45, 0x00,                 //          PHYSICAL_MAXIMUM (0)reset
        0xc0,                       //       END_COLLECTION
        0xc0,                       //   END_COLLECTION
        //------------------------------------------
        0x05, 0x0d,                 //   USAGE_PAGE (Digitizers)
        0x09, 0x54,                 //   USAGE (Contact Count)
        0x95, 0x01,                 //   REPORT_COUNT (1)
        0x75, 0x08,                 //   REPORT_SIZE (8)
        0x81, 0x02,                 //   INPUT (Data,Var,Abs)
        //------------------------------------------
        0x85, REPORTID_MAX_COUNT,   //   REPORT_ID (Contact Count Max)
        0x09, 0x55,                 //   USAGE(Contact Count Maximum)
        0x95, 0x02,                 //   REPORT_COUNT (1)
        0x25, 0x0a,                 //   LOGICAL_MAXIMUM (10)
        0xb1, 0x03,                 //   FEATURE (Const,Var,Abs)
        0xc0,                       // END_COLLECTION
        //------------------------------------------
        0x09, 0x0E,                 // USAGE (Device Configuration)
        0xa1, 0x01,                 // COLLECTION (Application)
        0x85, REPORTID_FEATURE,     //   REPORT_ID (Configuration)
        0x09, 0x23,                 //   USAGE (Device Settings)
        0xa1, 0x02,                 //   COLLECTION (logical)
        0x09, 0x52,                 //    USAGE (Device Mode)
        0x09, 0x53,                 //    USAGE (Device Identifier)
        0x15, 0x00,                 //    LOGICAL_MINIMUM (0)
        0x25, 0x0a,                 //    LOGICAL_MAXIMUM (10)
        0x75, 0x08,                 //    REPORT_SIZE (8)
        0x95, 0x02,                 //    REPORT_COUNT (2)
        0xb1, 0x02,                 //   FEATURE (Data,Var,Abs
        0xc0,                       //   END_COLLECTION
        0xc0,                       // END_COLLECTION
        //------------------------------------------
        0x05, 0x01,                 // USAGE_PAGE (Generic Desktop)     0
        0x09, 0x02,                 // USAGE (Mouse)                    2
        0xa1, 0x01,                 // COLLECTION (Application)         4
        0x85, REPORTID_MOUSE,       //   REPORT_ID (Mouse)              6
        0x09, 0x01,                 //   USAGE (Pointer)                8
        0xa1, 0x00,                 //   COLLECTION (Physical)          10
        0x05, 0x09,                 //     USAGE_PAGE (Button)          12
        0x19, 0x01,                 //     USAGE_MINIMUM (Button 1)     14
        0x29, 0x02,                 //     USAGE_MAXIMUM (Button 2)     16
        0x15, 0x00,                 //     LOGICAL_MINIMUM (0)          18
        0x25, 0x01,                 //     LOGICAL_MAXIMUM (1)          20
        0x75, 0x01,                 //     REPORT_SIZE (1)              22
        0x95, 0x02,                 //     REPORT_COUNT (2)             24
        0x81, 0x02,                 //     INPUT (Data,Var,Abs)         26
        0x95, 0x06,                 //     REPORT_COUNT (6)             28
        0x81, 0x03,                 //     INPUT (Cnst,Var,Abs)         30
        0x05, 0x01,                 //     USAGE_PAGE (Generic Desktop) 32
        0x09, 0x30,                 //     USAGE (X)                    34
        0x09, 0x31,                 //     USAGE (Y)                    36
        0x75, 0x10,                 //     REPORT_SIZE (16)             38
        0x95, 0x02,                 //     REPORT_COUNT (2)             40
        0x15, 0x00,                 //     LOGICAL_MINIMUM (0)          42
        0x26, 0xff, 0x7f,           //     LOGICAL_MAXIMUM (32767)      44
        0x81, 0x02,                 //     INPUT (Data,Var,Abs)         47
        0xc0,                       //   END_COLLECTION                 49
        0xc0                        // END_COLLECTION                   50/51
    };



    相关函数:

    kittenblock中小学创客名师推荐的图形化编程软件

        data[0] = 0x00;             //D0 Tip Switch  D1 In Range
        data[1] = Contact_ID_A;     //Contact Identifier
        data[2] = 0x00;             //XL
        data[3] = 0x00;             //XH
        data[4] = 0x00;             //YL
        data[5] = 0x00;             //YH
        //------------------------
        data[6] = 0x00;
        data[7] = Contact_ID_B;
        data[8] = 0x00;
        data[9] = 0x00;
        data[10] = 0x00;
        data[11] = 0x00;
        //-------------------------
        data[12] = 0x00;            //Contact Count
    



    kittenblock中小学创客名师推荐的图形化编程软件

    void TouchScreen_::Send_REPORTID_MAX_COUNT(void) {
        uint8_t m[1];
        m[0] = 2;
        HID.SendReport(REPORTID_MAX_COUNT, m, 1);
    }
    
    void TouchScreen_::Send_REPORTID_FEATURE(void) {
        uint8_t m[2];
        m[0] = 0x02;                    //Device Mode
        m[0] = REPORTID_MTOUCH;         //Device Identifier
        HID.SendReport(REPORTID_FEATURE, m, 2);
    }
    
    void TouchScreen_::TouchDownA(uint16_t x, uint16_t y) {
        data[0] = 0x03;
        data[2] = LSB(x);
        data[3] = MSB(x);
        data[4] = LSB(y);
        data[5] = MSB(y);
        data[12] += 1;
        HID.SendReport(REPORTID_MTOUCH, data, 13);
        
    }
    
    void TouchScreen_::TouchUpA(void) {
        data[0] = 0x00;
        data[2] = 0x00;
        data[3] = 0x00;
        data[4] = 0x00;
        data[5] = 0x00;
        data[12] -= 1;
        HID.SendReport(REPORTID_MTOUCH, data, 13);
    }
    
    
    void TouchScreen_::TouchDownB(uint16_t x, uint16_t y) {
        data[0] = 0x03;
        data[8] = LSB(x);
        data[9] = MSB(x);
        data[10] = LSB(y);
        data[11] = MSB(y);
        data[12] += 1;
        HID.SendReport(REPORTID_MTOUCH, data, 13);
        
    }
    
    void TouchScreen_::TouchUpB(void) {
        data[6] = 0x00;
        data[8] = 0x00;
        data[9] = 0x00;
        data[10] = 0x00;
        data[11] = 0x00;
        data[12] -= 1;
        HID.SendReport(REPORTID_MTOUCH, data, 13);
    }
    



    以下是在HID.cpp里修改的地方:

    kittenblock中小学创客名师推荐的图形化编程软件

    bool HID_Setup(USBSetup& setup, u8 i)
    {
        if (HID_INTERFACE != i) {
            return false;
        } else {
            u8 r = setup.bRequest;
            u8 requestType = setup.bmRequestType;
            if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
            {
                if (HID_GET_REPORT == r)
                {
                    //HID_GetReport();
                    
                    if(0x02 == setup.wValueL) {
                        u8 id = 0x02;
                        uint8_t m[1];
                        m[0] = 2;
                        USB_Send(HID_TX, &id, 1);
                        USB_Send(HID_TX | TRANSFER_RELEASE,m,1);
                    }
                    return true;
    



    实在是不知道出了什么问题,就是不能被识别为多点触控设备,在这里先谢过论坛里各位大大了。希望各位大大能给解答一下。
  • TA的每日心情
    无聊
    2017-1-24 10:00
  • 签到天数: 10 天

    [LV.3]偶尔看看II

     楼主| 发表于 2015-9-30 10:56 | 显示全部楼层

    然而这个问题已经坑了我好久了,小伙伴都等着我呢QwQ

    但是板子就是不能被识别为多点触控设备,不管是手机上还是win7上都不行

    QwQ网上的教程也都基本不管用呀QwQ

    该用户从未签到

    发表于 2015-9-30 20:04 | 显示全部楼层
    呃  这种东西是这样的:windows很可能不完全follow HID spec

    所以你要做的是:找一个确定OK 的研究一下
    打赏作者鼓励一下!
  • TA的每日心情
    无聊
    2017-1-24 10:00
  • 签到天数: 10 天

    [LV.3]偶尔看看II

     楼主| 发表于 2015-9-30 20:08 | 显示全部楼层
    Zoologist 发表于 2015-9-30 20:04
    呃  这种东西是这样的:windows很可能不完全follow HID spec

    所以你要做的是:找一个确定OK 的研究一下 ...

    我是看着MS的标准抄的。MS是有一部分自己扩展的,还提交给了USB组织,然后在巨硬官网上也有相关的资料,但是抄下来就是不能成功的被识别为多点设备QwQ死活都是单点设备。

    现有的demo都是基于51或者32的,没见有基于AVR或者arduino的QwQ

    不知道大大在这方面有没有研究能给讲一下的QwQ

    该用户从未签到

    发表于 2015-9-30 21:32 | 显示全部楼层
    槑小子 发表于 2015-9-30 20:08
    我是看着MS的标准抄的。MS是有一部分自己扩展的,还提交给了USB组织,然后在巨硬官网上也有相关的资料, ...

    对照 51 或者其他的多点触摸,完全copy descriptor试试看吧

    我只搞过 HID 的 mouse 和KB
    打赏作者鼓励一下!
  • TA的每日心情
    无聊
    2017-1-24 10:00
  • 签到天数: 10 天

    [LV.3]偶尔看看II

     楼主| 发表于 2015-9-30 21:33 | 显示全部楼层
    Zoologist 发表于 2015-9-30 21:32
    对照 51 或者其他的多点触摸,完全copy descriptor试试看吧

    我只搞过 HID 的 mouse 和KB ...

    已经打算改用串行报告了,不用并行报告了,说不定能有点效果QwQ

    该用户从未签到

    发表于 2015-12-31 15:03 | 显示全部楼层
    用feature 返回你的点数  不懂的话加我qq 2656045054

    该用户从未签到

    发表于 2015-12-31 15:05 | 显示全部楼层
    返回 feature

    该用户从未签到

    发表于 2015-12-31 15:06 | 显示全部楼层
    就可以识别你的多点了
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    新手求助,串口通信AT指令发送无反应
    新手求助,串口通信AT指令
    现在想用arduino uno板连接esp12-N无线模块发送数据,但是使用串口助手发送AT指令
    【Arduino】108种传感器模块系列实验(40)---旋转编码器模块
    【Arduino】108种传感器模
    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
    Arduino串口事件
    Arduino串口事件
    向各位大佬求助,学习了serialEvent(),按照书上的程序,我是直接使用的示例中的serial
    基于arduino的delta并联机械手
    基于arduino的delta并联机
    delta并联机械手现在广泛应用于工业,因为资金有限,用舵机做的,底座这些也是
    基于机器视觉的智能分拣机械臂
    基于机器视觉的智能分拣机
    本作品是一个基于机器视觉的智能机械臂操作平台,其采用atmega32单片机作为主控制系统
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表