簡體   English   中英

USB HID 多點觸控串行報告

[英]USB HID multitouch serial reporting

我正在創建一個連接到 Windows 計算機並在計算機上模擬觸摸屏的 Arduino 設備。 屏幕不屬於 Arduino,而是 Arduino 通過 USB 將 HID 觸摸消息中繼到 Windows 10 計算機。

我做的第一件事是中繼 AbsoluteMouse 事件而不是 Digitizer 事件。 這對我來說很好。 但是,由於我的設備支持多點觸控,我想使用多點觸控 HID 消息而不是 AbsoluteMouse。 作為概念證明,我從僅中繼一根手指的數據開始。 (我計划在我開始工作后添加更多的手指)。 我正在采用 SerialReport 方法,因為它似乎是最容易實現的:

我找到了很多使用 AbsoluteMouse 的例子,所以基本上我只需要復制粘貼 HID 報告就行了。 但是,對於觸摸屏,很難獲得代碼示例。 (I只找到突觸觸摸板樣本這不是觸摸屏)。 因此,我嘗試實現自己的代碼來報告觸摸消息。 但這失敗了。 我想我明白如何解釋 HID 描述符,但這是我第一次,所以我不確定......我的消息結構有什么問題嗎?

#define REPORTID_MTOUCH                 1

static const uint8_t _hidSerialMultiTouchDescriptor[] PROGMEM = {
    // https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/sample-report-descriptor--serial-reporting-mode-
    // Linked from: https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/selecting-packet-reporting-modes-in-multitouch-drivers
    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, 0x00,                         //   COLLECTION (Physical)
    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, 0x03,                         //     REPORT_COUNT (3)
    0x81, 0x03,                         //     INPUT (Cnst,Ary,Abs)
    0x09, 0x32,                         //     USAGE (In Range)
    0x09, 0x47,                         //     USAGE (Confidence)
    0x95, 0x02,                         //     REPORT_COUNT (2)
    0x81, 0x02,                         //     INPUT (Data,Var,Abs)
    0x95, 0x0a,                         //     REPORT_COUNT (10)
    0x81, 0x03,                         //     INPUT (Cnst,Ary,Abs)
    0x05, 0x01,                         //     USAGE_PAGE (Generic Desk..
    0x26, 0xff, 0x7f,                   //     LOGICAL_MAXIMUM (32767)
    0x75, 0x10,                         //     REPORT_SIZE (16)
    0x95, 0x01,                         //     REPORT_COUNT (1)
    0x65, 0x00,                         //     UNIT (None)
    0x09, 0x30,                         //     USAGE (X)
    0x81, 0x02,                         //     INPUT (Data,Var,Abs)
    0x09, 0x31,                         //     USAGE (Y)
    0x46, 0x00, 0x00,                   //     PHYSICAL_MAXIMUM (0)
    0x81, 0x02,                         //     INPUT (Data,Var,Abs)
    0x05, 0x0d,                         //     USAGE PAGE (Digitizers)
    0x09, 0x48,                         //     USAGE (Width)
    0x09, 0x49,                         //     USAGE (Height)
    0x95, 0x01,                         //     REPORT_COUNT (2)
    0x81, 0x02,                         //     INPUT (Data,Var,Abs)
    0x81, 0x03,                         //     INPUT (Cnst,Ary,Abs)
    0x09, 0x51,                         //     USAGE (Contact Identifier)
    0x75, 0x10,                         //     REPORT_SIZE (16)
    0x95, 0x02,                         //     REPORT_COUNT (1)
    0x81, 0x02,                         //     INPUT (Data,Var,Abs)
    0x09, 0x55,                         //    USAGE(Maximum Count)
    0x15, 0x00,                         //   LOGICAL_MINIMUM (0)
    0x25, 0x08,                         //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                         //   REPORT_SIZE (8)
    0x95, 0x01,                         //   REPORT_COUNT (1)
    0xb1, 0x02,                         //   FEATURE (Data,Var,Abs)
    0xc0,                               //   END_COLLECTION
    0xc0                               // END_COLLECTION
};

這是我對上述消息的實現:

typedef union {
  struct{
    uint8_t TipSwitchLsb4Bits_InRange_Confidence_Empty2Bits;
    uint8_t Padding8_10Minus2;
    int16_t xAxis;
    int16_t yAxis;
    int16_t width;
    int16_t height;
    int16_t ContactId;
    uint8_t MaximumCount;
  };
} HID_SerialTouchReport;

void reportTouch(unsigned int x, unsigned int y) {
  HID_SerialTouchReport report;
  report.TipSwitchLsb4Bits_InRange_Confidence_Empty2Bits = 0xff;
  report.xAxis = x;
  report.yAxis = y;
  report.width = 4;
  report.height = 4;
  report.ContactId = 0;
  report.MaximumCount = 1;
  HID().SendReport(REPORTID_MTOUCH, &report, sizeof(report));
}

...
  static HIDSubDescriptor node(_hidSerialMultiTouchDescriptor, sizeof(_hidSerialMultiTouchDescriptor));
HID().AppendDescriptor(&node);
...

//Move the pointer diagonally across the screen:
for(unsigned int x=0; x<32767; x+=1000) {
  reportTouch(x, x);
  delay(50);
}

測試代碼應該在Microsoft Paint上從左上角到右下角繪制一條對角線。

當我使用 AbsoluteMouse 描述符/消息進行測試時,一切正常。 所以我認為問題出在我對 HID_SerialTouchReport 的定義中。

一些引起我注意的事情:

  1. 為什么“PHYSICAL_MAXIMUM (0)”來的同時仍然定義“USAGE (Y)”。 它與 Y 而不是 X 有某種關系嗎? 為什么它是“0”?
  2. “INPUT(Cnst,Ary,Abs)”中“Ary”對於高度和寬度的意義是什么?
  3. 我有點“捏造”的東西:“report.TipSwitchLsb4Bits_InRange_Confidence_Empty2Bits=0xff;”。 然而,這對我來說似乎沒問題,因為我認為所有非填充位無論如何都需要設置為“1”。
  4. 我不確定應該將 report.MaximumCount 設置為什么。 我曾嘗試嘗試不同的 Count & Id 值,但都沒有效果。
  5. 我的 Arduino 確實在設備管理器中顯示為“復合設備”,所以我認為並非一切都是錯誤的。
  6. 在我鏈接的文章中,“串行數據包”模式適用於舊版 Windows 7,我使用的是 Windows 10。但我認為這應該不是問題。
  7. 雖然我確實直接從 Microsoft 站點復制了 HID 描述符,但我不確定我是否正確構建了消息結構。 (我是不是忘記了一些?)

或者完全是其他原因導致我的代碼失敗?

很難確定,但看起來 HID 報告描述符與您的 HID_SerialTouchReport 結構不匹配。 以下是我解碼您的描述符的方式:

//--------------------------------------------------------------------------------
// Decoded Application Collection
//--------------------------------------------------------------------------------

/*
05 0D        (GLOBAL) USAGE_PAGE         0x000D Digitizer Device Page 
09 04        (LOCAL)  USAGE              0x000D0004 Touch Screen (CA=Application Collection) 
A1 01        (MAIN)   COLLECTION         0x00000001 Application (Usage=0x000D0004: Page=Digitizer Device Page, Usage=Touch Screen, Type=CA)
85 01          (GLOBAL) REPORT_ID          0x01 (1) 
09 22          (LOCAL)  USAGE              0x000D0022 Finger (CL=Logical Collection) 
A1 00          (MAIN)   COLLECTION         0x00000000 Physical (Usage=0x000D0022: Page=Digitizer Device Page, Usage=Finger, Type=CL) <-- Warning: USAGE type should be CP (Physical)
09 42            (LOCAL)  USAGE              0x000D0042 Tip Switch (MC=Momentary Control) 
15 00            (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0 <-- Info: Consider replacing 15 00 with 14
25 01            (GLOBAL) LOGICAL_MAXIMUM    0x01 (1)  
75 01            (GLOBAL) REPORT_SIZE        0x01 (1) Number of bits per field  
95 01            (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (1 field x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
95 03            (GLOBAL) REPORT_COUNT       0x03 (3) Number of fields  
81 03            (MAIN)   INPUT              0x00000003 (3 fields x 1 bit) 1=Constant 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 32            (LOCAL)  USAGE              0x000D0032 In Range (MC=Momentary Control) 
09 47            (LOCAL)  USAGE              0x000D0047 Confidence (DV=Dynamic Value) 
95 02            (GLOBAL) REPORT_COUNT       0x02 (2) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (2 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
95 0A            (GLOBAL) REPORT_COUNT       0x0A (10) Number of fields  
81 03            (MAIN)   INPUT              0x00000003 (10 fields x 1 bit) 1=Constant 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
05 01            (GLOBAL) USAGE_PAGE         0x0001 Generic Desktop Page 
26 FF7F          (GLOBAL) LOGICAL_MAXIMUM    0x7FFF (32767)  
75 10            (GLOBAL) REPORT_SIZE        0x10 (16) Number of bits per field  
95 01            (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
65 00            (GLOBAL) UNIT               0x00000000 No unit (0=None) <-- Redundant: UNIT is already 0x00000000
09 30            (LOCAL)  USAGE              0x00010030 X (DV=Dynamic Value) 
81 02            (MAIN)   INPUT              0x00000002 (1 field x 16 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 31            (LOCAL)  USAGE              0x00010031 Y (DV=Dynamic Value) 
46 0000          (GLOBAL) PHYSICAL_MAXIMUM   0x0000 (0) <-- Redundant: PHYSICAL_MAXIMUM is already 0 <-- Info: Consider replacing 46 0000 with 44
81 02            (MAIN)   INPUT              0x00000002 (1 field x 16 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
05 0D            (GLOBAL) USAGE_PAGE         0x000D Digitizer Device Page 
09 48            (LOCAL)  USAGE              0x000D0048 Width (DV=Dynamic Value) 
09 49            (LOCAL)  USAGE              0x000D0049 Height (DV=Dynamic Value) 
95 01            (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields <-- Redundant: REPORT_COUNT is already 1 
81 02            (MAIN)   INPUT              0x00000002 (1 field x 16 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
81 03            (MAIN)   INPUT              0x00000003 (1 field x 16 bits) 1=Constant 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 51            (LOCAL)  USAGE              0x000D0051 Contact Identifier (DV=Dynamic Value) 
75 10            (GLOBAL) REPORT_SIZE        0x10 (16) Number of bits per field <-- Redundant: REPORT_SIZE is already 16 
95 02            (GLOBAL) REPORT_COUNT       0x02 (2) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (2 fields x 16 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 55            (LOCAL)  USAGE              0x000D0055 Contact Count Maximum (SV=Static Value) 
15 00            (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0 <-- Info: Consider replacing 15 00 with 14
25 08            (GLOBAL) LOGICAL_MAXIMUM    0x08 (8)  
75 08            (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field  
95 01            (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
B1 02            (MAIN)   FEATURE            0x00000002 (1 field x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
C0             (MAIN)   END_COLLECTION     Physical 
C0           (MAIN)   END_COLLECTION     Application 
*/

//--------------------------------------------------------------------------------
// Digitizer Device Page featureReport 01 (Device <-> Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x01 (1)
                                                     // Collection: TouchScreen Finger
  uint8_t  DIG_TouchScreenFingerContactCountMaximum; // Usage 0x000D0055: Contact Count Maximum, Value = 0 to 8
} featureReport01_t;


//--------------------------------------------------------------------------------
// Digitizer Device Page inputReport 01 (Device --> Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x01 (1)
                                                     // Collection: TouchScreen Finger
  uint8_t  DIG_TouchScreenFingerTipSwitch : 1;       // Usage 0x000D0042: Tip Switch, Value = 0 to 1
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  DIG_TouchScreenFingerInRange : 1;         // Usage 0x000D0032: In Range, Value = 0 to 1
  uint8_t  DIG_TouchScreenFingerConfidence : 1;      // Usage 0x000D0047: Confidence, Value = 0 to 1
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint16_t GD_TouchScreenFingerX;                    // Usage 0x00010030: X, Value = 0 to 32767
  uint16_t GD_TouchScreenFingerY;                    // Usage 0x00010031: Y, Value = 0 to 32767
  uint16_t DIG_TouchScreenFingerWidth;               // Usage 0x000D0048: Width, Value = 0 to 32767
                                                     // Usage 0x000D0049 Height (DV=Dynamic Value) Value = 0 to 32767 <-- Ignored: REPORT_COUNT (1) is too small
  uint16_t pad_8;                                    // Pad
  uint16_t DIG_TouchScreenFingerContactIdentifier[2]; // Usage 0x000D0051: Contact Identifier, Value = 0 to 32767
} inputReport01_t;

當我為 Width 和 Height 設置正確的報告計數並刪除(不必要的?)填充字節、不必要的 UNIT 和 PHYSICAL_MAXIMUM 以及多余的 GLOBAL 項,並將聯系人標識符 REPORT_COUNT 從 2 更改為 1 時,對我來說看起來更好:

//--------------------------------------------------------------------------------
// Decoded Application Collection
//--------------------------------------------------------------------------------

/*
05 0D        (GLOBAL) USAGE_PAGE         0x000D Digitizer Device Page 
09 04        (LOCAL)  USAGE              0x000D0004 Touch Screen (CA=Application Collection) 
A1 01        (MAIN)   COLLECTION         0x00000001 Application (Usage=0x000D0004: Page=Digitizer Device Page, Usage=Touch Screen, Type=CA)
85 01          (GLOBAL) REPORT_ID          0x01 (1) 
09 22          (LOCAL)  USAGE              0x000D0022 Finger (CL=Logical Collection) 
A1 00          (MAIN)   COLLECTION         0x00000000 Physical (Usage=0x000D0022: Page=Digitizer Device Page, Usage=Finger, Type=CL) <-- Warning: USAGE type should be CP (Physical)
09 42            (LOCAL)  USAGE              0x000D0042 Tip Switch (MC=Momentary Control) 
15 00            (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0 <-- Info: Consider replacing 15 00 with 14
25 01            (GLOBAL) LOGICAL_MAXIMUM    0x01 (1)  
75 01            (GLOBAL) REPORT_SIZE        0x01 (1) Number of bits per field  
95 01            (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (1 field x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
95 03            (GLOBAL) REPORT_COUNT       0x03 (3) Number of fields  
81 03            (MAIN)   INPUT              0x00000003 (3 fields x 1 bit) 1=Constant 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 32            (LOCAL)  USAGE              0x000D0032 In Range (MC=Momentary Control) 
09 47            (LOCAL)  USAGE              0x000D0047 Confidence (DV=Dynamic Value) 
95 02            (GLOBAL) REPORT_COUNT       0x02 (2) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (2 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
95 0A            (GLOBAL) REPORT_COUNT       0x0A (10) Number of fields  
81 03            (MAIN)   INPUT              0x00000003 (10 fields x 1 bit) 1=Constant 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
05 01            (GLOBAL) USAGE_PAGE         0x0001 Generic Desktop Page 
26 FF7F          (GLOBAL) LOGICAL_MAXIMUM    0x7FFF (32767)  
75 10            (GLOBAL) REPORT_SIZE        0x10 (16) Number of bits per field  
95 01            (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
09 30            (LOCAL)  USAGE              0x00010030 X (DV=Dynamic Value) 
81 02            (MAIN)   INPUT              0x00000002 (1 field x 16 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 31            (LOCAL)  USAGE              0x00010031 Y (DV=Dynamic Value) 
81 02            (MAIN)   INPUT              0x00000002 (1 field x 16 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
05 0D            (GLOBAL) USAGE_PAGE         0x000D Digitizer Device Page 
09 48            (LOCAL)  USAGE              0x000D0048 Width (DV=Dynamic Value) 
09 49            (LOCAL)  USAGE              0x000D0049 Height (DV=Dynamic Value) 
95 02            (GLOBAL) REPORT_COUNT       0x02 (2) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (2 fields x 16 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 51            (LOCAL)  USAGE              0x000D0051 Contact Identifier (DV=Dynamic Value) 
95 01            (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (1 field x 16 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 55            (LOCAL)  USAGE              0x000D0055 Contact Count Maximum (SV=Static Value) 
25 08            (GLOBAL) LOGICAL_MAXIMUM    0x08 (8)  
75 08            (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field  
B1 02            (MAIN)   FEATURE            0x00000002 (1 field x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
C0             (MAIN)   END_COLLECTION     Physical 
C0           (MAIN)   END_COLLECTION     Application 
*/

//--------------------------------------------------------------------------------
// Digitizer Device Page featureReport 01 (Device <-> Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x01 (1)
                                                     // Collection: TouchScreen Finger
  uint8_t  DIG_TouchScreenFingerContactCountMaximum; // Usage 0x000D0055: Contact Count Maximum, Value = 0 to 8
} featureReport01_t;


//--------------------------------------------------------------------------------
// Digitizer Device Page inputReport 01 (Device --> Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x01 (1)
                                                     // Collection: TouchScreen Finger
  uint8_t  DIG_TouchScreenFingerTipSwitch : 1;       // Usage 0x000D0042: Tip Switch, Value = 0 to 1
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  DIG_TouchScreenFingerInRange : 1;         // Usage 0x000D0032: In Range, Value = 0 to 1
  uint8_t  DIG_TouchScreenFingerConfidence : 1;      // Usage 0x000D0047: Confidence, Value = 0 to 1
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
  uint16_t GD_TouchScreenFingerX;                    // Usage 0x00010030: X, Value = 0 to 32767
  uint16_t GD_TouchScreenFingerY;                    // Usage 0x00010031: Y, Value = 0 to 32767
  uint16_t DIG_TouchScreenFingerWidth;               // Usage 0x000D0048: Width, Value = 0 to 32767
  uint16_t DIG_TouchScreenFingerHeight;              // Usage 0x000D0049: Height, Value = 0 to 32767
  uint16_t DIG_TouchScreenFingerContactIdentifier;   // Usage 0x000D0051: Contact Identifier, Value = 0 to 32767
} inputReport01_t;

這些 HID 報告描述符的手工制作非常棘手,以至於即使是 Microsoft 時常出錯,我也不感到驚訝。 如果只有一些編程高手(即比我更好)可以想出一些不錯的軟件來創建它們,我認為世界會變得更美好:)

披露:我使用我編寫的一些名為hidrdd 的免費軟件解碼了您的報告描述符。 我一直想將它移植到 Python,但還沒有開始學習 Python。

順便說一句,var 和 ary 之間的區別最好理解為 C 聲明之間的區別:

// var is like:
uint8_t my_value1;
uint8_t my_value2;

// ary is like:
uint8_t my_value[2];

最大計數似乎是“最大接觸計數”用法 - 即同時按下的最大手指數,並且是功能報告的一部分(可以從設備發送或接收)。 報告描述符指示它可以具有同時按下的 0 個手指和 8 個手指之間的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM