4. 广播与扫描实战
BLE 广播(Advertising)是设备被发现的第一步。nRF 系列芯片把广播行为抽象成一组可配置参数:广播类型、广播数据(AD Structure)、扫描响应数据、广播间隔、发射功率与信道。理解这些参数如何组合成空口上的实际数据包,是调试“手机搜不到设备”“连接不稳定”“功耗偏高”等问题的基础。本章围绕 nRF Connect 手机 App 的实测观察,把广播包从配置到空口再到扫描端解析的链路串起来。
广播包的结构:AD Structure 与 AD Type
广播数据不是一段自由文本,而是由若干 AD Structure 拼接而成。每个 AD Structure 的第一个字节是长度字段(Length),表示后续“类型 + 数据”的字节数;第二个字节是 AD Type,例如 0x01 表示 Flags、0x09 表示完整设备名(Complete Local Name)、0x03 表示完整的 16 位 UUID 列表、0xFF 表示厂商自定义数据(Manufacturer Specific Data)。解析时按长度逐段跳读,直到遇到长度为 0 的填充或数据结束。
以 Nordic 常见的示例为例,一段广播数据可以写成:
// 广播数据(AD Structure 序列)
02 01 06 // Flags: LE General Discoverable, BR/EDR Not Supported
09 09 4E 6F 72 64 69 63 5F 54 61 67 // Complete Local Name: "Nordic_Tag"
05 03 0D 18 // Complete 16-bit UUID: 0x180D (Heart Rate)
0A FF 59 00 01 02 03 04 05 06 // Manufacturer Data: 公司ID 0x0059 + 自定义负载
这里 0x02 表示后面有 2 字节(类型 0x01 + 数据 0x06);0x09 表示后面 9 字节(类型 0x09 + 8 字节名称)。注意长度字段只统计“类型 + 数据”,不包含长度字节自身。广播包总长度受限于 31 字节(Legacy Advertising),扫描响应包同样最多 31 字节,两者合计可承载约 62 字节的有效信息。若需要更长数据,应改用扩展广播(Extended Advertising),但手机端兼容性需确认。
可连接、不可连接与定向广播
广播类型决定了设备是否接受连接请求,以及是否允许被主动扫描。常见类型包括:
- ADV_IND(可连接、可扫描的非定向广播):最常用,任何中心设备都可发起连接,也可发送扫描请求获取扫描响应。
- ADV_NONCONN_IND(不可连接、不可扫描的非定向广播):只广播数据,不接受连接,也不响应扫描请求。适合信标(Beacon)类应用。
- ADV_SCAN_IND(可扫描、不可连接):可被扫描请求,返回扫描响应,但不接受连接。
- ADV_DIRECT_IND(定向广播):只面向指定目标地址(InitA),用于快速重连,广播间隔通常很短,功耗较高但连接建立快。
选择哪种类型,取决于设备角色。例如一个只上报温湿度的传感器,若不需要被连接配置,用 ADV_NONCONN_IND 可以省去连接维护开销;若需要手机连接读取历史数据,则必须使用 ADV_IND。定向广播适合已知对端地址的快速回连场景,但目标地址变化后需要重新配置。
广播间隔与功耗的权衡
广播间隔(Advertising Interval)是两次广播事件之间的时间,范围通常为 20 ms 到 10.24 s。间隔越短,被发现越快,但射频开启越频繁,平均功耗越高。以 nRF52 系列为例,在 0 dBm 发射功率下,一次广播事件(三个信道 37/38/39 依次发送)的电流脉冲约数毫安,持续时间约 1~2 ms。若间隔为 100 ms,占空比约 1%~2%;若间隔为 1 s,占空比降至 0.1%~0.2%,平均电流可降到几十微安量级。
实际工程中常用折中:需要快速被发现的设备用 100~300 ms;电池供电、对发现时延不敏感的信标用 1~2 s;定向快速重连可用 20~30 ms,但仅维持短时间。Nordic SDK 中通过 ble_gap_adv_params_t 的 interval 字段设置,单位是 0.625 ms。例如设置 160 表示 100 ms,设置 1600 表示 1 s。
ble_gap_adv_params_t adv_params = {
.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED,
.interval = 160, // 160 × 0.625 ms = 100 ms
.duration = 0, // 0 表示持续广播
.filter_policy = BLE_GAP_ADV_FP_ANY,
};
用 nRF Connect 手机 App 验证广播包
烧录固件后,打开 nRF Connect(Nordic 官方 App),进入 Scanner 页签,可以看到周围设备的列表。每个条目显示设备名、RSSI、MAC 地址和广播类型图标。点击某个设备展开,能看到 RAW 数据、AD Structure 解析结果以及扫描响应内容。重点观察三件事:
- 广播数据是否与代码一致:检查 Flags、设备名、UUID、厂商数据是否按预期出现,长度字段是否正确。
- 扫描响应是否被触发:若设备配置了扫描响应数据,App 会在扫描请求后显示第二段数据。若没有,检查广播类型是否支持扫描。
- RSSI 与广播间隔的间接判断:RSSI 反映信号强度,不能直接测间隔,但若设备列表刷新频率明显变化,可辅助判断广播是否在持续发送。
如果 App 中看不到设备,先确认广播是否已启动、发射功率是否过低、是否被过滤策略限制。若能看到设备但连接失败,检查广播类型是否为可连接类型,以及目标地址是否匹配。
广播配置与验证的完整链路
下面这张图把“配置参数 → 空口广播包 → 扫描端解析 → 结果判断”串成一条信号链,帮助你在调试时快速定位问题出在哪一段。
调试时建议按这条链逐段核对:先在代码里确认广播参数和 AD 数据,再用 nRF Connect 看空口实际内容,最后根据现象回到对应环节修改。广播间隔和发射功率是功耗与发现速度的两个主要旋钮,实际项目中应结合电池容量、期望发现时延和手机端扫描占空比一起估算,而不是只凭经验取值。