You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过Web Bluetooth向含CRC的特征正确发送指令?

Web Bluetooth支持带CRC校验的指令格式吗?如何正确发送?

Web Bluetooth 完全支持发送{data}<CRC>这种格式的指令——你的问题大概率出在CRC计算的参数匹配、字节拼接顺序或者指令构造细节上,下面一步步帮你排查和解决:

先分析你尝试过程中可能的问题点

  1. CRC参数不匹配
    你用在线工具计算CRC,但BLE设备的CRC算法参数(比如多项式、初始值、输入/输出字节反转、结果异或值)可能和工具默认选项不一致。比如很多工业BLE设备用CRC-16/CCITT(多项式0x1021,初始值0xFFFF),或者CRC-16/Modbus(多项式0x8005,初始值0xFFFF),参数错了计算出的CRC完全无效,设备自然不会响应。

  2. CRC字节顺序错误
    设备要求的CRC是大端(高位字节在前)还是小端(低位字节在前)?比如计算出的CRC是0x1234,大端是[0x12, 0x34],小端是[0x34, 0x12],搞反的话设备无法解析校验值。

  3. 指令拼接错误
    以指令R为例,正确的字节序列应该是:R的ASCII码(0x52) + CRC的两个字节,而不是你示例里的随机数值[22,22,22]——你需要确保发送的是真实的指令字节+正确的CRC字节。

正确的实现步骤和代码示例

第一步:确认设备的CRC参数

先查BLE设备的文档,明确以下CRC-16的关键参数(拿常见的CRC-16/CCITT举例):

  • 多项式:0x1021
  • 初始值:0xFFFF
  • 输入字节:是否反转
  • 输出结果:是否反转
  • 结果异或值:0x0000(或其他值)

第二步:在代码中实现匹配的CRC计算

不要依赖在线工具,自己写符合设备参数的CRC函数,避免参数不匹配。比如下面是符合CRC-16/CCITT的实现:

function calculateCRC16CCITT(data) {
  let crc = 0xFFFF;
  for (let byte of data) {
    crc ^= byte << 8;
    for (let i = 0; i < 8; i++) {
      crc = (crc & 0x8000) ? (crc << 1) ^ 0x1021 : crc << 1;
    }
    crc &= 0xFFFF; // 保持16位
  }
  return crc;
}

第三步:构造指令并发送

以指令R为例,按以下步骤构造字节数组:

// 1. 转换指令数据为Uint8Array
const commandData = new TextEncoder().encode('R'); // 得到 [0x52]

// 2. 计算CRC
const crcValue = calculateCRC16CCITT(commandData);

// 3. 把CRC拆分为两个字节(根据设备要求的字节顺序,这里假设大端)
const crcBytes = [
  (crcValue >> 8) & 0xFF, // 高位字节
  crcValue & 0xFF          // 低位字节
];

// 4. 拼接指令+CRC
const fullCommand = new Uint8Array([...commandData, ...crcBytes]);

// 5. 发送指令(确保特征支持WRITE操作)
await someCharacteristic.writeValue(fullCommand);

额外排查建议

  • 确认你写入的特征具有writewriteWithoutResponse属性(可以通过someCharacteristic.properties.has('write')检查)。
  • 有些设备会通过另一个特征返回响应,而不是你写入的特征——检查设备文档,确认响应对应的特征UUID,给那个特征注册监听器。
  • 用Chrome的chrome://bluetooth-internals/工具调试,查看你发送的字节是否和设备要求的格式完全一致,这能帮你快速定位字节拼接或CRC的问题。

内容的提问来源于stack exchange,提问作者mr.Deepwest

火山引擎 最新活动