4. 低功耗蓝牙广播与连接

在 nRF 资产追踪设备中,BLE 广播是设备被手机发现的第一道门。设备周期性地在 37、38、39 三个广播信道上发送广播包,手机扫描到广播后可以读取其中的自定义数据,也可以发起连接进入 GATT 交互。本节围绕三件事展开:广播参数怎么配、自定义广播数据怎么组织、广播间隔与发射功率如何影响功耗与可发现性。

一、广播参数:间隔、功率与信道

nRF Connect SDK 中,广播参数通过 bt_le_adv_param 结构体描述,核心字段包括:

  • options:选择可连接广播(BT_LE_ADV_OPT_CONN)还是不可连接广播(BT_LE_ADV_OPT_NONE)。资产追踪设备通常先以可连接广播让手机读取信息,再决定是否建立连接。
  • interval_min / interval_max:广播间隔,单位 0.625 ms。例如 0x00A0 对应 100 ms,0x0640 对应 1000 ms。两者相等表示固定间隔,不等表示允许控制器在区间内抖动,有助于降低多设备同时广播时的碰撞概率。
  • peer_addr:定向广播的目标地址,普通广播填 NULL。

发射功率不在广播参数结构体中,而是通过 bt_le_adv_start() 之后调用 bt_hci_cmd_send_sync(BT_HCI_OP_VS_WRITE_TX_POWER, ...) 或使用 CONFIG_BT_CTLR_TX_PWR 在编译期设定。nRF52/nRF53 系列支持 -40 dBm 到 +4 dBm 的发射功率档位,常用档位为 -20、-12、-8、-4、0、+4 dBm。

广播间隔与发射功率共同决定平均功耗。以 nRF52832 为例,在 0 dBm 发射功率下,单次广播事件约消耗 6.6 µA·s 的电荷;若间隔为 100 ms,平均电流约为 66 µA;若间隔拉长到 1000 ms,平均电流降至约 6.6 µA。这就是“可发现性”与“续航”之间的直接权衡:间隔越短,手机越快扫到,但功耗越高。

二、自定义广播数据格式

BLE 广播数据由一系列 AD Structure 组成,每个结构为“长度 + 类型 + 数据”。长度字段占 1 字节,表示类型和数据的字节数之和。常用类型包括:

AD 类型值用途
Flags0x01指示设备是否可连接、是否支持 BR/EDR
Complete Local Name0x09完整设备名
Manufacturer Specific Data0xFF厂商自定义数据,前 2 字节为公司标识符
Service Data0x16服务数据,前 2 字节为 UUID

资产追踪设备通常把资产 ID、电量、传感器状态打包进 Manufacturer Specific Data。例如公司标识符使用 Nordic 的 0x0059,后面依次放 4 字节资产 ID、1 字节电量百分比、1 字节状态位。构造代码如下:

static uint8_t mfg_data[] = {
    0x59, 0x00,             /* Nordic 公司标识符 */
    0x12, 0x34, 0x56, 0x78, /* 资产 ID */
    0x5A,                   /* 电量 90% */
    0x01                    /* 状态:运动中 */
};

static const struct bt_data ad[] = {
    BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR),
    BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, sizeof(mfg_data)),
};

注意广播包总长不超过 31 字节(Legacy Advertising),其中 AD Structure 本身还要占长度和类型字段。若数据较多,可改用扩展广播(Extended Advertising)或把部分数据放到扫描响应(Scan Response)中。扫描响应通过 bt_le_adv_start() 的 sd 参数传入,手机主动扫描时才会请求。

三、手机端扫描与连接

手机端使用 nRF Connect 或自研 App 扫描时,会看到设备名、RSSI 和 Manufacturer Data。RSSI 可用于粗略估算距离:在 0 dBm 发射功率下,1 米处 RSSI 约为 -60 dBm,每增加一倍距离约衰减 6 dB。实际环境中墙体、人体遮挡会造成 10~20 dB 的波动,因此 RSSI 只适合做区域级判断,不适合精确测距。

连接建立后,手机可以读取 GATT 服务中的资产信息、配置上报间隔、触发蜂鸣器或 LED。连接期间设备不再广播,功耗显著上升(连接事件平均电流通常在几百 µA 到数 mA),因此资产追踪设备应尽量缩短连接时间,完成配置后立即断开回到广播状态。

四、参数权衡与配置建议

下面这张图展示了广播间隔、发射功率与平均功耗、可发现性之间的参数关系,可作为选型时的参考:

广播间隔 / 发射功率与功耗、可发现性的权衡 广播间隔 (ms) 平均电流 (µA) 20 100 250 500 1000 2000 0 100 200 300 400 0 dBm 发射 +4 dBm 发射 -20 dBm 发射 短间隔:快速发现 功耗高,适合实时追踪 长间隔:续航优先 发现延迟增大

从图中可以读出几个实用结论:

  • 广播间隔从 100 ms 拉长到 1000 ms,平均电流下降约 10 倍,但手机发现设备的最坏延迟也从约 100 ms 增加到约 1 s。
  • 发射功率从 0 dBm 提高到 +4 dBm,电流约增加 2.5 倍,通信距离仅提升约 30%~50%,性价比不高;反之降到 -20 dBm 可省电约 60%,但距离明显缩短。
  • 对于需要实时定位的资产,建议间隔 100~250 ms、功率 0 dBm;对于只需每日上报的资产,间隔可放到 1000~2000 ms、功率 -12~-20 dBm。
实际项目中,可先用 nRF Connect 的 RSSI 曲线观察不同功率下的信号覆盖,再结合功耗分析仪(如 Nordic Power Profiler Kit II)测量平均电流,最后确定参数组合。不要仅凭理论计算就定稿,天线匹配和外壳遮挡会显著改变实际表现。
广播数据一旦超过 31 字节,bt_le_adv_start() 会返回 -EINVAL。调试时若发现广播启动失败,优先检查 AD 数据总长度,而不是怀疑协议栈配置。

最后给出一个可直接参考的配置片段,用于 100 ms 可连接广播、0 dBm 发射、携带厂商数据:

static const struct bt_le_adv_param adv_param =
    BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_CONN,
                         0x00A0,  /* 100 ms */
                         0x00A0,
                         NULL);

err = bt_le_adv_start(&adv_param, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
if (err) {
    printk("Advertising failed to start (err %d)\n", err);
    return;
}

掌握广播参数、数据格式与功耗之间的关系后,就可以根据资产追踪场景的实际需求,在“被快速发现”和“长时间续航”之间找到合适的平衡点。