第四节:BLE连接建立——连接参数、连接间隔、从设备延迟、监督超时
好,咱们接着聊。上一节我们把广播讲透了,现在设备已经能被手机扫描到了。接下来最关键的一步——建立连接。
连接建立,说白了就是两个设备约定好「咱们以后怎么通信」。这个约定,就是连接参数。我做了这么多年低功耗蓝牙,见过太多产品因为连接参数没设好,要么功耗爆炸,要么连接断断续续。今天咱们就把这四个核心参数掰开揉碎了讲。
4.1 连接间隔(Connection Interval)
连接间隔,是主机和从机之间两次通信的时间间隔。单位是1.25ms的倍数。比如你设了100,那就是125ms通信一次。
这个参数直接影响功耗和实时性。间隔越小,数据传得越及时,但设备就得频繁醒来,功耗自然高。反过来,间隔大了省电,但数据延迟就大了。
我个人的习惯是:
- 医疗贴片场景:一般设30ms到50ms。比如心电贴片,数据要实时上传,延迟不能太大。
- 体温贴片:可以放宽到100ms甚至200ms。体温变化慢,没必要那么频繁通信。
- 胰岛素泵控制:建议20ms以内。控制指令延迟高了会出问题。
重要:连接间隔的范围是7.5ms(最小值)到4s(最大值)。但实际应用中,iOS和Android对连接间隔有各自的限制。iOS要求连接间隔在30ms以上,否则可能拒绝连接。Android相对宽松,但也不建议低于20ms。
我在项目中遇到过一件事。有个客户做血糖贴片,为了省电把连接间隔设到了200ms。结果手机端收数据时总是丢包,用户投诉说数据不连续。后来一查,是连接间隔太大,手机端的缓存溢出了。嗯,这里要注意:连接间隔不是越大越好,得看对端设备的处理能力。
4.2 从设备延迟(Slave Latency)
这个参数,很多人容易搞混。从设备延迟,允许从设备在连接事件中「跳过」几次不响应,从而省电。
举个例子:连接间隔是50ms,从设备延迟设为3。那么从设备最多可以连续跳过3次连接事件,也就是150ms才响应一次。这期间主机还是会按时发数据包,但从设备可以继续睡觉。
你想想看,这对医疗贴片来说太有用了。比如体温贴片,数据变化慢,没必要每个连接事件都起来应答。设个从设备延迟,能省不少电。
我建议的配置原则:
- 实时性要求高的场景(心电、脑电):从设备延迟设为0。别省这点电,数据丢了更麻烦。
- 非实时场景(体温、血氧趋势):可以设2到5。我一般设3,省电效果明显。
- 注意:从设备延迟不能太大,否则主机可能认为从设备掉线了。这个后面讲监督超时会提到。
实战技巧:从设备延迟的值,最好结合连接间隔一起算。比如连接间隔50ms,延迟设3,那么从设备最长150ms才响应一次。这个延迟对体温监测来说完全够用,但功耗能降低60%以上。
4.3 监督超时(Supervision Timeout)
监督超时,是主机判断从设备是否掉线的依据。如果在这个时间内没有收到从设备的任何数据包,主机就认为连接断了。
单位是10ms的倍数,范围100ms到32s。这个值必须大于连接间隔乘以(1 + 从设备延迟)。
公式很简单:
监督超时 > 连接间隔 × (1 + 从设备延迟) × 2
为什么要乘以2?因为要考虑丢包重传。我曾经遇到过一个问题:监督超时设得太紧,结果信号稍微差一点就断连。用户贴了没几分钟就断一次,体验极差。
我个人的经验值:
- 医疗贴片:监督超时建议设在5s到10s之间。太短容易误断,太长又影响重连速度。
- 信号不稳定场景(比如运动时):可以放宽到15s。但别超过20s,否则用户等重连会不耐烦。
- 注意:监督超时不能超过32s,这是BLE协议的限制。
避坑指南:我曾经在一个项目中,把监督超时设成了3s,连接间隔50ms,从设备延迟设了10。结果从设备延迟10次,也就是500ms才响应一次,但监督超时3s看起来够用。实际上因为无线环境干扰,偶尔丢包几次,3s很快就到了,导致频繁断连。后来我把监督超时改到6s,问题解决。
教训:监督超时一定要留够余量,建议至少是连接间隔×(1+从设备延迟)的3倍以上。
4.4 四个参数的联动关系
这四个参数不是孤立的,它们互相影响。我画个表格,大家一看就明白:
| 参数 | 增大 | 减小 | 典型医疗贴片值 |
|---|---|---|---|
| 连接间隔 | 省电,延迟大 | 费电,实时性好 | 30-100ms |
| 从设备延迟 | 省电,丢包风险增加 | 费电,可靠性高 | 0-5 |
| 监督超时 | 连接稳定,断连检测慢 | 断连检测快,易误断 | 5-10s |
说白了,这就是一个平衡游戏。省电和实时性永远是对立面。医疗贴片因为要长时间佩戴,省电是刚需,但也不能牺牲数据可靠性。
我一般这样配:
- 先确定连接间隔。根据数据量来,心电30ms,体温100ms。
- 再设从设备延迟。非实时数据设3-5,实时数据设0。
- 最后算监督超时。保证大于连接间隔×(1+从设备延迟)×3。
4.5 实战中的参数协商
连接参数不是主机单方面定的。从设备可以在连接建立后,通过连接参数更新请求(Connection Parameter Update Request)来协商。
我建议的做法是:
- 广播阶段:在广播包里带上你期望的连接参数。这样主机在连接时就会尽量靠近你的要求。
- 连接建立后:如果主机给的参数不理想,立即发起参数更新请求。别等,越早越好。
- 注意:iOS对参数更新有限制,不能太频繁。我一般只请求一次,如果被拒绝就接受现状。
代码示例:在nRF5 SDK中发起连接参数更新请求:
// 定义期望的连接参数
ble_gap_conn_params_t conn_params;
conn_params.min_conn_interval = MSEC_TO_UNITS(30, UNIT_1_25_MS); // 30ms
conn_params.max_conn_interval = MSEC_TO_UNITS(50, UNIT_1_25_MS); // 50ms
conn_params.slave_latency = 3; // 从设备延迟
conn_params.conn_sup_timeout = MSEC_TO_UNITS(6000, UNIT_10_MS); // 6s
// 发起更新请求
sd_ble_gap_conn_param_update(conn_handle, &conn_params);
嗯,这里要注意:参数更新请求不是一定会被接受的。主机有自己的策略,比如iOS就经常拒绝太小的连接间隔。所以你的设备要做好「给什么参数就用什么参数」的准备。
4.6 总结一下
连接建立阶段的参数配置,直接决定了医疗贴片的功耗和用户体验。我做了这么多项目,最大的体会就是:没有万能参数,只有最适合场景的参数。
最后送大家一句话:调试连接参数时,别光看实验室数据。戴上贴片去走走、跑跑、出出汗,模拟真实使用场景。很多问题,只有在这种「不完美」的环境下才会暴露出来。
下一节,咱们讲连接建立后的数据交互——ATT和GATT。这两个协议栈层面的东西,才是真正决定你数据传输效率的关键。