WebHID API演示Demo教程:装备列表,装备毗连,数据读写 ...

饭宝  论坛元老 | 2025-2-16 05:25:15 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1010|帖子 1010|积分 3030

1. 简介

WebHID API允许网页应用直接与HID(人机接口装备)举行通讯。本教程将演示怎样创建一个底子的WebHID应用,实现以下功能:


  • 表现和获取HID装备列表
  • 毗连/断开HID装备
  • 读取装备数据
  • 向装备发送数据

2. 兼容性和条件条件

2.1 欣赏器支持



  • 重要支持Chrome欣赏器
  • 必要在安全上下文中运行(HTTPS或localhost)
2.2 权限要求



  • 必要用户明确授权才气访问HID装备
  • 某些操作系统大概必要额外的权限设置
3. 项目布局

项目包含两个重要文件:
  1. ├── index.html    // 页面结构和样式
  2. └── hid-demo.js   // WebHID功能实现
复制代码

4. 实现步骤

4.1 创建底子HTML布局

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <title>HID Device Communication</title>
  6.   <style>
  7.     #output {
  8.       width: 100%;
  9.       height: 200px;
  10.       margin: 10px 0;
  11.       padding: 5px;
  12.       border: 1px solid #ccc;
  13.       overflow-y: auto;
  14.     }
  15.     /* ... 其他样式 ... */
  16.   </style>
  17. </head>
  18. <body>
  19.   <h1>WebHID API 演示</h1>
  20.   
  21.   <button id="connectButton">连接新HID设备</button>
  22.   
  23.   <h2>已连接设备列表:</h2>
  24.   <ul id="deviceList"></ul>
  25.   
  26.   <div class="input-group">
  27.     <input type="text" id="sendData" placeholder="输入要发送的数据(用逗号分隔的数字)">
  28.     <button id="sendButton">发送数据</button>
  29.   </div>
  30.   
  31.   <h2>输出日志:</h2>
  32.   <pre id="output"></pre>
  33.   <script src="hid-demo.js"></script>
  34. </body>
  35. </html>
复制代码
4.2 实现WebHID核心功能

4.2.1 初始化和获取装备列表

  1. let currentDevice = null;
  2. document.addEventListener('DOMContentLoaded', () => {
  3.   // 获取已授权的设备
  4.   navigator.hid.getDevices()
  5.     .then(devices => {
  6.       updateDeviceList(devices);
  7.     })
  8.     .catch(error => {
  9.       console.error('Error getting devices:', error);
  10.     });
  11. });
复制代码
4.2.2 毗连新装备

  1. document.getElementById('connectButton').addEventListener('click', async () => {
  2.   try {
  3.     const devices = await navigator.hid.requestDevice({
  4.       filters: [] // 空过滤器显示所有设备
  5.     });
  6.    
  7.     if (devices.length > 0) {
  8.       updateDeviceList(devices);
  9.     }
  10.   } catch (error) {
  11.     console.error('Error connecting to device:', error);
  12.   }
  13. });
复制代码
4.2.3 装备毗连/断开处理

  1. async function toggleConnect(device) {
  2.   try {
  3.     if (device.opened) {
  4.       await device.close();
  5.       currentDevice = null;
  6.       appendToOutput(`设备已断开: ${device.productName}`);
  7.     } else {
  8.       await device.open();
  9.       currentDevice = device;
  10.       appendToOutput(`设备已连接: ${device.productName}`);
  11.       
  12.       // 监听设备输入报告
  13.       device.addEventListener('inputreport', event => {
  14.         const {data, reportId} = event;
  15.         const value = new Uint8Array(data.buffer);
  16.         appendToOutput(`收到数据 (报告ID ${reportId}): ${Array.from(value)}`);
  17.       });
  18.     }
  19.    
  20.     // 刷新设备列表显示
  21.     const devices = await navigator.hid.getDevices();
  22.     updateDeviceList(devices);
  23.   } catch (error) {
  24.     console.error('Error toggling device connection:', error);
  25.     appendToOutput(`操作失败: ${error.message}`);
  26.   }
  27. }
复制代码
4.2.4 数据发送功能

  1. document.getElementById('sendButton').addEventListener('click', async () => {
  2.   if (!currentDevice || !currentDevice.opened) {
  3.     alert('请先连接设备!');
  4.     return;
  5.   }
  6.   const data = document.getElementById('sendData').value;
  7.   try {
  8.     const dataArray = new Uint8Array(data.split(',').map(x => parseInt(x.trim())));
  9.     await currentDevice.sendReport(0, dataArray);
  10.     appendToOutput('已发送数据: ' + data);
  11.   } catch (error) {
  12.     console.error('Error sending data:', error);
  13.     appendToOutput('发送数据失败: ' + error.message);
  14.   }
  15. });
复制代码
5. 利用阐明

5.1 毗连装备


  • 点击"毗连新HID装备"按钮
  • 在弹出的系统对话框中选择要毗连的装备
  • 装备将表如今已毗连装备列表中
5.2 数据收发


  • 毗连装备后,装备发送的数据会自动表如今输出日志中
  • 在输入框中输入要发送的数据(格式:逗号分隔的数字,如 1,2,3,4)
  • 点击"发送数据"按钮发送数据
6. 注意事项


  • 数据格式

    • 发送数据必要利用逗号分隔的数字格式
    • 不同装备大概必要特定的数据格式,请参考装备文档

  • 报告ID

    • 当前示例利用默认报告ID (0)
    • 某些装备大概必要特定的报告ID,必要相应修改代码

  • 错误处理

    • 所有操作都包含错误处理
    • 错误信息会表如今输出日志中

  • 安全性

    • 必须在HTTPS或localhost环境下运行
    • 必要用户明确授权才气访问装备

7. 调试发起


  • 利用Chrome开发者工具监控控制台输出
  • 查抄装备毗连状态和错误信息
  • 验证数据格式是否符合装备要求
  • 确保装备驱动正确安装
8. 扩展发起


  • 添加装备过滤器,只表现特定范例的装备
  • 实现自定义数据格式转换
  • 添加数据可视化功能
  • 实现装备自动重连机制
9. 参考资源



  • WebHID API MDN文档
  • HID接口规范
  • HIDDevice接口
完整Demo
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.   <title>HID Device Communication</title>
  7.   <style>
  8.     #output {
  9.       width: 100%;
  10.       height: 200px;
  11.       margin: 10px 0;
  12.       padding: 5px;
  13.       border: 1px solid #ccc;
  14.       overflow-y: auto;
  15.     }
  16.     #deviceList {
  17.       margin: 10px 0;
  18.     }
  19.     #deviceList li {
  20.       margin: 5px 0;
  21.       padding: 5px;
  22.       border: 1px solid #eee;
  23.       display: flex;
  24.       justify-content: space-between;
  25.       align-items: center;
  26.     }
  27.     .input-group {
  28.       margin: 10px 0;
  29.     }
  30.   </style>
  31. </head>
  32. <body>
  33.   <h1>WebHID API 演示</h1>
  34.   
  35.   <button id="connectButton">连接新HID设备</button>
  36.   
  37.   <h2>已连接设备列表:</h2>
  38.   <ul id="deviceList"></ul>
  39.   
  40.   <div class="input-group">
  41.     <input type="text" id="sendData" placeholder="输入要发送的数据(用逗号分隔的数字)">
  42.     <button id="sendButton">发送数据</button>
  43.   </div>
  44.   
  45.   <h2>输出日志:</h2>
  46.   <pre id="output"></pre>
  47.   <script src="hid-demo.js"></script>
  48. </body>
  49. </html>
复制代码
  1. let currentDevice = null;document.addEventListener('DOMContentLoaded', () => {  // 获取已授权的装备  navigator.hid.getDevices()    .then(devices => {      updateDeviceList(devices);    })    .catch(error => {      console.error('Error getting devices:', error);    });  // 毗连新装备按钮变乱  document.getElementById('connectButton').addEventListener('click', async () => {    try {      // 请求毗连HID装备      const devices = await navigator.hid.requestDevice({        filters: [] // 空过滤器表现所有装备      });            if (devices.length > 0) {        updateDeviceList(devices);      }    } catch (error) {      console.error('Error connecting to device:', error);    }  });  // 发送数据按钮变乱  document.getElementById('sendButton').addEventListener('click', async () => {    if (!currentDevice || !currentDevice.opened) {      alert('请先毗连装备!');      return;    }    const data = document.getElementById('sendData').value;    console.log('发送数据: ' + data);    try {      // 将输入数据转换为Uint8Array      const dataArray = new Uint8Array(data.split(',').map(x => parseInt(x.trim())));      await currentDevice.sendReport(5, dataArray);      appendToOutput('已发送数据: ' + data);      console.log('已发送数据: ' + data);    } catch (error) {      console.error('Error sending data:', error);      appendToOutput('发送数据失败: ' + error.message);    }  });});// 更新装备列表表现function updateDeviceList(devices) {  const deviceList = document.getElementById('deviceList');  deviceList.innerHTML = '';    devices.forEach(device => {    const li = document.createElement('li');    li.textContent = `${device.productName} (VID: ${device.vendorId}, PID: ${device.productId})`;        const connectBtn = document.createElement('button');    connectBtn.textContent = device.opened ? '断开' : '毗连';    connectBtn.addEventListener('click', () => toggleConnect(device));        li.appendChild(connectBtn);    deviceList.appendChild(li);  });}// 毗连/断开装备async function toggleConnect(device) {
  2.   try {
  3.     if (device.opened) {
  4.       await device.close();
  5.       currentDevice = null;
  6.       appendToOutput(`设备已断开: ${device.productName}`);
  7.     } else {
  8.       await device.open();
  9.       currentDevice = device;
  10.       appendToOutput(`设备已连接: ${device.productName}`);
  11.       
  12.       // 监听设备输入报告
  13.       device.addEventListener('inputreport', event => {
  14.         const {data, reportId} = event;
  15.         const value = new Uint8Array(data.buffer);
  16.         appendToOutput(`收到数据 (报告ID ${reportId}): ${Array.from(value)}`);
  17.       });
  18.     }
  19.    
  20.     // 刷新设备列表显示
  21.     const devices = await navigator.hid.getDevices();
  22.     updateDeviceList(devices);
  23.   } catch (error) {
  24.     console.error('Error toggling device connection:', error);
  25.     appendToOutput(`操作失败: ${error.message}`);
  26.   }
  27. }
  28. // 添加输出信息function appendToOutput(message) {  const output = document.getElementById('output');  output.textContent += message + '\n';  output.scrollTop = output.scrollHeight;}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

饭宝

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表