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

使用Web Bluetooth API读取BGM220-EK4314A温度数据异常求助

核心错误点
  • 未开启GATT特征通知:现有代码仅读取了客户端特征配置描述符(CCC)的默认值,未写入开启通知的指令,也没有调用特征的startNotifications()方法,外设不会主动推送温度更新,绑定的characteristicvaluechanged监听永远不会触发。
  • 温度值解析不符合蓝牙规范:根据蓝牙SIG官方定义,Health Thermometer服务的temperature_measurement特征结构为:首字节(偏移0)是标志位,从偏移1位置开始存储32位IEEE 11073格式的温度值。现有代码直接读取偏移0的8位无符号整数,拿到的只是标志位数值,和实际温度完全无关。
  • 服务声明缺失:optionalServices配置中没有加入健康温度计服务对应的UUID 0x1809,部分浏览器环境下会拦截未声明服务的访问请求,导致服务获取失败。
修正步骤
  1. 在optionalServices数组中补充健康温度计服务UUID 0x1809
  2. 删除冗余的CCC描述符读取逻辑,在绑定值变化监听后调用startNotifications()开启特征订阅,该API会自动完成CCC描述符的写入操作,无需手动处理
  3. 重写温度值解析逻辑,跳过首字节标志位,从偏移1位置读取32位小端序浮点数,即为摄氏度温度值
  4. 可选:开启通知后主动调用readValue()获取一次初始温度,无需等第一次通知推送
修正后完整代码
const deviceName = "Thermometer Example";

function isWebBLEAvailable() {
  if (!navigator.bluetooth) {
    console.log("Web BLE unavailable");
    return false;
  }
  console.log("Web BLE available");
  return true;
}

function handleTempChanged(event) {
  const dataView = event.target.value;
  // 偏移0为标志位,偏移1开始读32位小端序浮点温度值
  const temperature = dataView.getFloat32(1, true);
  const tempText = `${temperature.toFixed(1)} ℃`;
  console.log("收到温度更新:", tempText);
  document.getElementById("target").textContent = `当前温度:${tempText}`;
}

async function getDeviceInfo() {
  const $target = document.getElementById("target");
  try {
    console.log("请求蓝牙设备...");
    const device = await navigator.bluetooth.requestDevice({
      // 补充健康温度计服务UUID到可选服务列表
      optionalServices: [0x1800, 0x1801, 0x1809, 0x180a],
      filters: [{ name: deviceName }, { services: ["health_thermometer"] }],
    });

    console.log("已连接设备:", device.name);
    const server = await device.gatt.connect();
    console.log("GATT连接成功");

    const healthThermService = await server.getPrimaryService("health_thermometer");
    console.log("获取健康温度计服务成功");

    const tempChar = await healthThermService.getCharacteristic("temperature_measurement");
    console.log("获取温度测量特征成功");

    // 绑定值变化监听
    tempChar.addEventListener("characteristicvaluechanged", handleTempChanged);
    // 开启通知订阅
    await tempChar.startNotifications();
    console.log("温度通知已开启");

    // 读取初始温度值
    const initialValue = await tempChar.readValue();
    const initialTemp = initialValue.getFloat32(1, true);
    $target.textContent = `当前温度:${initialTemp.toFixed(1)} ℃`;

  } catch (error) {
    console.log("操作出错:", error);
    $target.textContent = `连接出错:${error.message}`;
  }
}

document.querySelector("form").addEventListener("submit", function (event) {
  event.stopPropagation();
  event.preventDefault();
  if (isWebBLEAvailable()) {
    getDeviceInfo();
  }
});
补充说明
  • Web Bluetooth API仅在HTTPS站点或localhost本地调试环境下可用,普通HTTP环境下接口会被浏览器拦截。
  • 如果你使用的固件是将温度数据放在BLE广播包中(无需连接即可收到数据),则不需要走上述GATT连接流程,直接调用navigator.bluetooth.requestLEScan()开启广播扫描,解析广播包中0x1809服务对应的字段即可拿到温度。你所用的Simplicity Studio官方Health Thermometer例程默认采用GATT通知模式推送数据,上述修正代码可以直接使用。

内容的提问来源于stack exchange,提问作者Amal K O

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:01:08