You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确解码Characteristic UUID 2A37的RR间隔值?解码异常求助

问题分析与解决

核心问题:字节序错误

蓝牙BLE特征数据采用**小端序(Little-Endian)**存储多字节数值,你的代码错误地按大端序拼接了RR间隔的字节,导致计算出异常大的数值。

数据解析过程

原始数据:0x10, 0x54, 0xAA, 0x02, 0x99, 0x02

  1. Flags字节(0x10):二进制为00010000,说明:
    • 心率格式为8位(第0位为0)
    • 存在RR间隔数据(第4位为1)
  2. 心率值:第1字节0x54,即84bpm,这部分你的代码是正确的。
  3. RR间隔数据:从第2字节开始,每2字节代表一个RR间隔值。小端序要求低位字节在前,高位字节在后,所以第一个RR间隔的两个字节0xAA(低位)和0x02(高位)应拼接为0x02AA(十进制682),而不是你的代码中拼接的0xAA02(十进制43522)。

修正后的计算逻辑

RR间隔的单位是1/1024秒,转换为毫秒的公式是:
RR间隔(ms) = (拼接后的十进制值 / 1024) * 1000
代入682计算:682 / 1024 * 1000 ≈ 666ms,这是合理的生理数值。

修正后的C++代码

#include <iostream>
#include <cmath>

using namespace std;

const int RR_INTERVAL_PRESENT_BIT = 4;
const int HEART_RATE_FORMAT_BIT = 0;
const int RR_INTERVAL_UNIT = 1024;

int main() {
  // characteristic UUID value
  unsigned char characteristic[] = {0x10, 0x54, 0xAA, 0x02, 0x99, 0x02};

  // read the flags
  unsigned char flags = characteristic[0];
  int heartRateFormat = (flags & (1 << HEART_RATE_FORMAT_BIT)) ? 2 : 1;
  int rrIntervalPresent = (flags & (1 << RR_INTERVAL_PRESENT_BIT)) ? 1 : 0;

  // calculate heart rate and rr-interval
  int heartRate = 0;
  int rrInterval = 0;
  int index = 1;
  if (heartRateFormat == 2) {
    // 心率的多字节同样是小端序,修正此处逻辑
    heartRate = (characteristic[index + 1] << 8) | characteristic[index];
    index += 2;
  } else {
    heartRate = characteristic[index];
    index += 1;
  }

  if (rrIntervalPresent) {
    // 修正小端序拼接逻辑:低位在前,高位在后
    rrInterval = (characteristic[index + 1] << 8) | characteristic[index];
    rrInterval = round(rrInterval / (double)RR_INTERVAL_UNIT * 1000);
    
    // 读取第二组RR间隔(原始数据包含两组)
    int rrInterval2 = (characteristic[index + 3] << 8) | characteristic[index + 2];
    rrInterval2 = round(rrInterval2 / (double)RR_INTERVAL_UNIT * 1000);
    cout << "Second RR interval: " << rrInterval2 << " ms" << endl;
  }

  cout << "Heart rate: " << heartRate << " bpm" << endl;
  cout << "RR interval: " << rrInterval << " ms" << endl;

  return 0;
}

额外说明

  • 蓝牙BLE的多字节数值(如16位、32位数据)均采用小端序存储,解析时必须注意字节顺序。
  • 你的原始数据包含两组RR间隔(0xAA 0x02和0x99 0x02),第二个值计算后约为653ms,符合正常心率的RR间隔范围。

内容的提问来源于stack exchange,提问作者Kwang Chee Seng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 13:01:11