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

Puck.js使用nobleJs获取BLE广播数据异常问题排查

问题根因
  • 核心概念混淆:你混淆了BLE广播和GATT连接通信两种模式。你在Puck.js端调用NRF.setAdvertising仅配置了无连接的广播报文,没有实现GATT服务端的温度服务/特征值逻辑,也没有在连接后主动推送温度数据。你连接设备后发现的6e400001开头的服务是Puck.js默认的Nordic UART串口服务,和你配置在广播里的0x1809温度服务无关,给串口特征开启notify后收到的Data <- Serial1就是串口默认输出,自然拿不到温度值。
  • 逻辑流程错误:你需要的周期性温度数据本身就在广播报文中,完全不需要停止扫描、建立GATT连接,你当前的流程主动中断了扫描流程,自然无法收到每秒更新的广播数据。另外noble默认扫描模式下同一个设备仅上报一次discover事件,即使不停止扫描也拿不到后续更新的广播内容。
修复方案

优先选择无连接广播接收方案,和你现有Puck.js端代码完全匹配,功耗更低实现更简单:

  1. 调整noble接收端逻辑:
    • 启动扫描时开启重复上报,允许同一个设备的多次广播触发discover事件
    • 移除停止扫描、连接设备、发现服务特征、开启notify的冗余逻辑
    • 直接在discover事件回调中从广播报文里解析温度值和厂商数据

修正后的接收端代码:

import noble from "@abandonware/noble";

noble.on("stateChange", async (state) => {
  if (state === "poweredOn") {
    // 第二个参数传true允许重复广播上报,才能拿到每秒更新的数据
    await noble.startScanningAsync([], true);
  }
});

noble.on("discover", async (peripheral) => {
  if (peripheral.id !== "7515300cdefc6fee0cf2d840f8e4a9cf") {
    return;
  }

  // 解析厂商数据
  const manufacturerData = peripheral.advertisement.manufacturerData;
  console.log("厂商数据:", manufacturerData.slice(2).toString()); // 前2字节是厂商ID0x0590,后面是写入的"Moin"

  // 解析0x1809温度服务的广播数据
  const tempServiceData = peripheral.advertisement.serviceData.find(item => item.uuid === '1809');
  if (tempServiceData) {
    // Puck端写入的是单字节整数温度,直接读第一个字节即可
    const temperature = tempServiceData.data.readUInt8(0);
    console.log("当前温度:", temperature, "℃");
  }
});
  1. 如果你确实需要通过GATT连接+notify方式获取数据(比如需要双向通信),则需要修改Puck.js端代码,注册自定义的0x1809温度服务和对应特征,在定时器中更新特征值并触发通知,这种方案不需要依赖广播传输数据。
补充说明

你之前看到厂商数据前的乱码字符是厂商ID0x0590的二进制内容,直接toString会显示乱码,从第3个字节(索引2)开始读取才是你写入的"Moin"字符串。

内容的提问来源于stack exchange,提问作者ppulwey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:09:21