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

ArduinoBLE setManufacturerData广播厂商数据失效咨询

Arduino Nano BLE Sense setManufacturerData 不生效原因与正确实现

核心问题原因

  • 第一是BLE传统广播的硬长度限制:无需连接即可被扫描到的广播数据分为主广播包、扫描响应包两部分,单包最大有效载荷仅31字节,总包长上限62字节,要放64字节纯业务载荷本身就超出了硬件协议上限,库底层检测到长度超限后会直接静默丢弃厂商数据字段,不会返回任何报错。
  • 第二是ArduinoBLE库的已知bug与调用逻辑问题:
    • 版本低于1.3.2的正式版库存在广播字段优先级计算错误,如果先设置本地名称、服务UUID等字段,再调用setManufacturerData,库计算剩余广播空间时会多算预留字节,误判厂商数据超长直接丢弃,这也是最初5字节测试数据也无法广播的核心原因。
    • 不带厂商ID参数的setManufacturerData重载是库内部预留的兼容接口,没有做蓝牙规范校验,生成的厂商数据字段不符合SIG标准,绝大多数扫描设备、BLE网关会直接过滤畸形字段,扫出来自然是空的。
    • 调用stopAdvertise后直接修改参数再advertise不会触发广播包缓冲区重建,修改的参数根本不会被加载到广播队列里。
  • 第三是扫描端缓存问题:安卓、部分桌面BLE工具会缓存已发现设备的广播结构,设备固件修改后如果不清除蓝牙缓存、重启蓝牙,会一直显示旧的空字段结果。

正确实现步骤

  • 先把ArduinoBLE库升级到1.3.2及以上正式版,避开旧版本的字段写入bug。
  • 调整载荷长度:64字节纯载荷超出协议上限,至少裁剪2字节,或者把固定不变的设备信息等非实时内容放到后续可读取的特征里,实时温湿度这类短数据放广播即可。20台设备的场景下建议把核心实时数据放主广播包,设备名称这类固定信息放扫描响应包,避免空间冲突。
  • 调整配置顺序:所有广播参数必须在第一次调用advertise前配置完成,优先配置厂商数据,再配置本地名称等其他字段;如果是运行中更新传感数据,直接调用setManufacturerData即可,不需要停广播、重新调用advertise,库会自动在下一个广播周期加载新数据。
  • 必须使用带16位厂商ID参数的接口重载,不要用无厂商ID的内部接口。
  • 无连接场景下直接调用BLE.setConnectable(false)关闭连接属性,能省出3字节左右的广播包空间给业务载荷。

可直接运行的参考代码

#include <ArduinoBLE.h>

// 替换成实际的传感器读取逻辑
float readTemp() { return 24.8; }
float readHumi() { return 60.2; }

void setup() {
  Serial.begin(115200);
  if (!BLE.begin()) {
    while(1); // BLE初始化失败,停止运行
  }

  uint8_t manuPayload[25] = {0};
  // 先配置厂商数据,避开库的长度计算bug
  float temp = readTemp();
  float humi = readHumi();
  memcpy(manuPayload, &temp, 4);
  memcpy(manuPayload + 4, &humi, 4);
  // 0x6861为自定义厂商ID,注意BLE传输为小端序,扫描端解析时注意字节序
  BLE.setManufacturerData(0x6861, manuPayload, 25);

  // 再配置其他广播参数
  BLE.setLocalName("AB1234567890");
  BLE.setConnectable(false); // 无需连接直接关闭可连接属性,省空间
  BLE.setAdvertisingInterval(100); // 广播间隔62.5ms,20台设备不会出现扫描拥堵
  BLE.advertise();
}

void loop() {
  // 周期更新传感数据,直接覆写厂商数据即可
  uint8_t newPayload[25] = {0};
  float temp = readTemp();
  float humi = readHumi();
  memcpy(newPayload, &temp, 4);
  memcpy(newPayload + 4, &humi, 4);
  BLE.setManufacturerData(0x6861, newPayload, 25);

  delay(1000); // 1秒更新一次数据即可
}

额外优化提示

如果需要放更长的业务载荷,可以调用BLE.setScanResponseData()自定义扫描响应包内容,和主广播包搭配最多可携带58字节左右的纯业务载荷(扣除各AD结构的固定头开销),完全满足温湿度+少量设备状态信息的上报需求,不需要和设备建立连接,20台设备并行扫描也不会出现连接排队拖慢效率的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:57:21