1

我正在尝试使用 WebHID API 从我的数字化仪(X Tilt、Y Tilt、Tip Pressure、Tip Switch、Eraser、Pen、Puck 等)获取传感器输入。这是我到目前为止所得到的:

index.js:

page_log = text => {
  let p = document.createElement("p");
  p.textContent = text;
  log.appendChild(p);
};

let device;

if (!("hid" in navigator)) {
  page_log("WebHID is not available yet.");
}

navigator.hid.getDevices().then(devices => {
  if (devices.length == 0) {
    page_log(`No HID devices selected. Press the "request device" button.`);
    return;
  }
  if (devices.length > 1) {
    page_log(`You have multiple devices.`);
  }
  device = devices[0];
  page_log(`User previously selected "${device.productName}" HID device.`);
  page_log(`Now press "open device" button to receive input reports.`);
});

requestDeviceButton.onclick = async event => {
  document.body.style.display = "none";
  try {
    const filters = [
      {
        vendorId: 0x056a, // Wacom Co., Ltd
        productId: 0x00b1 //PTZ-630 [Intuos3 (6x8)]
      },
      {
        vendorId: 0x056a, // Wacom Co., Ltd
        productId: 0x00b2 //PTZ-930 [Intuos3 (9x12)]
      },
      {
        vendorId: 0x056a, // Wacom Co., Ltd
        productId: 0x00b3 //PTZ-1230 [Intuos3 (12x12)]
      },
      {
        vendorId: 0x056a, // Wacom Co., Ltd
        productId: 0x00b4 //PTZ-1231W [Intuos3 (12x19)]
      },
    ];

    [device] = await navigator.hid.requestDevice({ filters });
    if (!device) return;

    page_log(`User selected "${device.productName}" HID device.`);
    page_log(`Now press "open device" button to receive input reports.`);
  } finally {
    document.body.style.display = "";
  }
};


openButton.onclick = async event => {
  if (!device) return;

  await device.open().catch(console.error);
  page_log(`Waiting for user to press button...`);

  device.addEventListener("inputreport", event => {
    const { data, device, reportId } = event;

    let buffArray = new Uint8Array(data.buffer);
    console.log(buffArray);
    // console.log(device);
  
  });
};

控制台输出:

index.js:72 Uint8Array(9) [224, 49, 125, 58, 74, 0, 35, 195, 85]
index.js:72 Uint8Array(9) [224, 49, 109, 58, 64, 0, 35, 194, 94]
index.js:72 Uint8Array(9) [224, 49, 94, 58, 43, 0, 35, 194, 102]
index.js:72 Uint8Array(9) [224, 49, 82, 58, 22, 0, 35, 193, 113]
index.js:72 Uint8Array(9) [224, 49, 52, 58, 1, 0, 35, 193, 123]
index.js:72 Uint8Array(9) [224, 49, 26, 57, 228, 0, 35, 192, 128]
index.js:72 Uint8Array(9) [224, 48, 253, 57, 190, 0, 35, 64, 141]
index.js:72 Uint8Array(9) [224, 48, 223, 57, 137, 0, 35, 65, 148]
index.js:72 Uint8Array(9) [224, 48, 203, 57, 90, 0, 35, 66, 159]
index.js:72 Uint8Array(9) [224, 48, 186, 57, 36, 0, 35, 66, 167]
index.js:72 Uint8Array(9) [224, 48, 177, 56, 242, 0, 35, 67, 174]
index.js:72 Uint8Array(9) [224, 48, 166, 56, 208, 0, 35, 196, 178]

如何找出每个数字对应的传感器?

我已经尝试阅读WebHID 规范HID 使用表,但到目前为止我一直无法找到解密输出所需的信息。


更新:

安装 Wacom 的官方驱动程序后,我在 Windows 中进行了测试,我从 InputReport 中获得了更多数据。

输出:(带有 wacom 驱动程序的 Windows)

index.js:73 reportId: 15
index.js:76 Uint8Array(10) [2, 224, 55, 229, 45, 137, 0, 30, 176, 195]
index.js:73 reportId: 15
index.js:76 Uint8Array(21) [2, 224, 55, 163, 45, 99, 0, 31, 49, 189, 15, 2, 224, 55, 98, 45, 69, 0, 31, 49, 190]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 29, 90, 238, 97, 50, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 212, 254, 192, 249, 232, 28, 184, 136, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 241, 89, 197, 97, 30, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 56, 255, 36, 250, 76, 29, 228, 137, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 162, 89, 144, 97, 30, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 56, 255, 36, 250, 76, 29, 228, 137, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 136, 89, 123, 97, 22, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 56, 255, 36, 250, 76, 29, 228, 137, 0, 0]
index.js:73 reportId: 15
index.js:76 Uint8Array(10) [2, 224, 55, 34, 45, 31, 0, 31, 178, 185]
index.js:73 reportId: 15
index.js:76 Uint8Array(32) [2, 224, 54, 215, 45, 2, 0, 32, 50, 183, 15, 2, 224, 54, 139, 44, 226, 0, 32, 179, 183, 15, 2, 224, 54, 62, 44, 187, 0, 33, 52, 178]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 27, 89, 51, 97, 14, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 156, 255, 136, 250, 176, 29, 16, 139, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 171, 88, 237, 96, 6, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 250, 176, 29, 0, 0, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 53, 88, 163, 96, 254, 2, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 250, 20, 30, 0, 0, 0, 0]
index.js:73 reportId: 15
index.js:76 Uint8Array(10) [2, 224, 53, 239, 44, 147, 0, 34, 54, 175]

注意:我已经记录了reportId这次,因为我现在得到了 2 个不同的。

我还注意到HIDDevice.collections对象中的不同数据: devtools 截图窗口 这次我在我的一个outputReports.

输出:(Linux用于比较)

index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 31, 174, 22, 67, 0, 38, 203, 177]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 31, 33, 21, 8, 0, 39, 204, 180]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 30, 165, 20, 8, 0, 40, 77, 183]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 30, 16, 19, 51, 0, 40, 206, 182]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 29, 134, 18, 97, 0, 41, 80, 181]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 29, 9, 17, 191, 0, 39, 80, 183]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 28, 210, 17, 27, 0, 36, 215, 184]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 28, 225, 16, 150, 0, 35, 86, 186]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 29, 45, 16, 15, 0, 33, 83, 184]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 29, 162, 15, 153, 0, 32, 83, 190]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 30, 110, 15, 51, 0, 32, 86, 195]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 31, 96, 14, 214, 0, 31, 87, 199]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [160, 32, 212, 14, 142, 0, 26, 216, 202]

另外HIDDevice.collections我在linux上: 在此处输入图像描述

所以我仍然不明白如何使用featureReports,InputReportsOutputReports. 所以我发现我从 Windows 上的 Wacom 驱动程序中获得的 HID 数据比 Linux 上的要多。


更新 2:

我一直在查看HIDDevice.collectionWindows 输出上的对象,并将其与Report Descriptors我在 Linux 上运行(以使它们可读)得到的usbhid-dump进行hidrd-convert比较。这是我到目前为止所发现的。

  • 看起来我只需要查看inputReports适当的元素,reportID因为我只是想读取发送到主机的传感器数据。

  • 我查看数组items以查看报告发送了哪些数据。

    • 我查看项目的索引号以了解从 DataView(我的变量)items中提取数据的顺序。data
    • 我查看reportCountreportSize了解 DataView 中该项目的数据形状。
    • 我查看每个项目的“使用情况”以了解数据的用途。
      • 不幸的是,WebHID 似乎并没有在每个项目的基础上公开“使用情况” (就像我在节目中的“报告描述符”usbhid-dump一样)。相反,它仅在每个集合的基础上公开它。
      • 可以在HID 使用表中查找“使用情况”(如果可用),方法是通过 的十六进制值查找“使用页面” ,然后对给定的十六进制值执行相同usagePage操作。collectionusage

例子:

    if (reportId !== 7) return;
    console.log('reportId: ' + reportId);
    let zero_through_six = data.getUint8(0);


    let report_data = [
      (zero_through_six & 128) == 128,  //0 (1-bit)
      (zero_through_six & 64) == 64,    //1 (1-bit)
      (zero_through_six & 32) == 32,    //2 (1-bit)
      (zero_through_six & 16) == 16,    //3 (1-bit)
      (zero_through_six & 8) == 8,      //4 (1-bit)
      (zero_through_six & 4) == 4,      //5 (1-bit)
      zero_through_six & 3,             //6 (2-bits)
      data.getUint16(1), //7
      data.getUint16(3), //8
      data.getUint16(5), //9
      data.getUint16(7), //10
      data.getUint32(9), //11
      data.getBigUint64(13), //12
      data.getUint32(21), //13
      data.getUint16(23), //14
      data.getUint16(25), //15
      data.getUint16(27), //16
      data.getUint16(29), //17
      data.getUint16(31), //18
      data.getUint16(33), //19
    ];

    console.log(report_data);

  });

这是我在 Windows 版本上拆分我进入的数据和数组时所做的事情。第一个items[1-6]是 1 位,items[7]是2 位,items[7-10]是 16 位,依此类推。

同样,由于 WebHID 不会针对每个项目公开“使用情况”,因此每个项目映射到的传感器/按钮仍然未知。至少在单独测试每个简单的测试之外,这在如此复杂的设备上很难做到。

更新 3:

事实证明,我的用例并不需要WebHID API(从我的数字化仪获取传感器输入)。看起来PointerEventMouseEvent属性可以满足我的需求。(真的,实际上应该先看看那个(;一_一))至少,我学会了一些如何使用WebHID API。

4

1 回答 1

2

我猜https://web.dev/devices-introduction/会很有用,因为它解释了如何选择适当的 API 来与您选择的硬件设备进行通信。

恭喜你弄明白了!

于 2021-04-13T07:57:20.147 回答