4. BLE广播与扫描:广播信道与数据信道、广播包格式、扫描参数优化、连接间隔设置
BLE的广播机制,说白了就是设备在“喊话”。它不关心有没有人在听,只管按固定节奏往外丢数据包。我刚开始做低功耗项目时,总觉得广播嘛,不就是发几个字节吗?结果一测功耗,电池撑了不到三天就趴窝了。后来才明白——广播这玩意儿,用好了是门铃,用不好就是广场舞大喇叭。
4.1 广播信道与数据信道
BLE在2.4GHz频段划分了40个信道,编号0~39。但真正用于广播的只有3个:37、38、39。为什么是这三个?
你想想看,2.4GHz频段上Wi-Fi和蓝牙挤在一起,干扰很严重。BLE的设计者特意选了三个互不重叠的信道——37在2402MHz,38在2426MHz,39在2480MHz。它们避开了Wi-Fi的1、6、11三个主信道,能最大程度降低碰撞概率。
信道分配速查表
| 信道编号 | 频率(MHz) | 用途 | 备注 |
|---|---|---|---|
| 37 | 2402 | 广播/扫描 | 起始信道 |
| 38 | 2426 | 广播/扫描 | 中间信道 |
| 39 | 2480 | 广播/扫描 | 最高频信道 |
| 0~36 | 2404~2478 | 数据通信 | 连接后使用 |
数据信道则不同。连接建立后,双方会在37个数据信道上跳频通信。跳频序列由连接事件决定,每次收发都换一个信道。我有个项目就因为没处理好跳频同步,导致连接后频繁断连——后来发现是主从设备的信道映射表没对齐。
4.2 广播包格式
广播包的结构其实不复杂。我拆开给你看:
广播包 = 前导码(1字节) + 接入地址(4字节) + PDU(2~39字节) + CRC(3字节)
PDU是核心部分。它又分成两种:
- ADV_IND:可连接的非定向广播,最常用
- ADV_NONCONN_IND:不可连接的非定向广播,纯广播场景用
- ADV_SCAN_IND:可扫描的非定向广播,允许扫描请求
- ADV_DIRECT_IND:定向广播,指定目标设备
PDU内部结构长这样:
PDU头部(2字节) + 广播地址(6字节) + 广播数据(0~31字节)
广播数据部分采用AD Structure格式:
长度(1字节) + AD Type(1字节) + AD Data(长度-1字节)
我的习惯:广播数据最多31字节,但实际能用的往往更少。我一般把核心信息控制在20字节以内,留出余量给厂商自定义数据。曾经有个项目非要塞满31字节,结果扫描端解析时频繁丢包——广播数据越长,接收成功率越低。
4.3 扫描参数优化
扫描参数直接影响功耗和发现速度。核心参数就两个:
- 扫描窗口:每次扫描持续的时间
- 扫描间隔:两次扫描开始之间的时间
扫描器在每个广播信道上监听扫描窗口时长,然后跳到下一个信道。一个完整的扫描周期覆盖37、38、39三个信道。
注意:扫描窗口不能大于扫描间隔。如果窗口=间隔,那就是连续扫描——功耗最高,但发现最快。如果窗口远小于间隔,功耗低,但可能错过广播包。
我常用的经验值:
| 场景 | 扫描窗口 | 扫描间隔 | 平均功耗 |
|---|---|---|---|
| 快速发现 | 30ms | 30ms | 高 |
| 平衡模式 | 30ms | 100ms | 中 |
| 低功耗 | 10ms | 500ms | 低 |
我曾经做过一个信标项目,要求电池撑一年。扫描端是手机,功耗不是问题。但广播端是纽扣电池设备,广播间隔设了500ms,扫描窗口设了30ms——结果手机经常要等好几秒才能发现设备。后来我把广播间隔降到200ms,扫描窗口提到50ms,发现时间缩短到1秒以内,功耗只多了不到10%。
4.4 连接间隔设置
连接建立后,主从设备按固定间隔交换数据。这个间隔叫连接间隔(Connection Interval),范围是7.5ms~4s,步进1.25ms。
连接间隔的选择是个权衡:
- 间隔小:延迟低,数据吞吐高,但功耗大
- 间隔大:功耗低,但延迟高,吞吐低
我一般按这个原则选:
- 实时控制类(如遥控器):7.5ms~30ms
- 数据采集类(如传感器):50ms~200ms
- 低功耗监测类(如温湿度计):500ms~2s
避坑指南:我曾经把连接间隔设成4s,想着省电。结果设备每隔4秒才发一次数据,用户按了遥控器要等4秒才有反应——产品直接被退货。后来改成30ms,功耗虽然高了点,但用户体验完全不一样。
还有一个容易被忽略的参数:从机延迟(Slave Latency)。它允许从设备跳过若干个连接事件,继续睡眠。比如连接间隔100ms,从机延迟设为9,那从设备可以睡1秒才起来收一次数据。这对低功耗非常友好。
但要注意:从机延迟不能太大,否则主设备会认为连接丢失。BLE规范规定,从机延迟最大值为499,但实际芯片往往有更严格的限制。
4.5 广播与扫描的完整流程
我把整个流程画了张图,方便你理解:
4.6 实战建议
最后给几个我踩过坑之后总结的经验:
广播间隔别太短:20ms以下的广播间隔会让芯片持续发射,功耗飙升。除非你做的是一对一的快速配对,否则建议100ms起步。
扫描窗口别太大:连续扫描(窗口=间隔)的功耗是间歇扫描的3~5倍。如果不需要实时发现,把扫描窗口降到10ms,间隔拉到500ms以上。