4. 连接参数调优:连接间隔、延迟与超时时间的平衡艺术
蓝牙连接参数,说白了就是三个数字:连接间隔、从机延迟和超时时间。
这三个参数就像三根绳子,牵着一台蓝牙设备。拉得太紧,功耗高;放得太松,连接容易断。我做了这么多年蓝牙开发,见过太多产品因为参数没调好,要么电池撑不过一天,要么动不动就断连。
今天咱们就把这三个参数掰开揉碎了讲清楚。
4.1 三个参数各自管什么
先看一张图,把整体关系理清楚。
4.2 连接间隔:决定功耗与响应速度
连接间隔,就是主机和从机之间两次通信的间隔时间。单位是1.25ms的整数倍,范围从7.5ms到4s。
你想想看,如果间隔设成7.5ms,设备每秒要醒来133次。功耗能不高吗?反过来,如果设成100ms,每秒只醒来10次,省电多了。
核心原则:
- 低功耗场景(如温湿度传感器):间隔设大,100ms~500ms
- 低延迟场景(如鼠标、遥控器):间隔设小,7.5ms~30ms
- 平衡场景(如手环、耳机):30ms~100ms
我记得有一次做智能门锁项目,产品经理要求开锁响应时间小于200ms。我一开始把连接间隔设成50ms,结果电池撑不到一个月。后来我把间隔调到100ms,配合从机延迟,响应时间还是200ms以内,但电池续航翻了一倍。
4.3 从机延迟:省电的利器
从机延迟,允许从机在连续N个连接事件中不回复主机。说白了,就是让从机可以「偷懒」。
举个例子:连接间隔是50ms,从机延迟设成4。那么从机最多可以连续跳过4个连接事件,也就是200ms内不用醒来。这期间主机还是会按时发数据包,但从机可以继续睡觉。
我的经验:
从机延迟不是越大越好。延迟太大,数据会堆积。我曾经在一个数据采集项目里把延迟设成9,结果主机收数据时发现一次要收10包,缓冲区直接溢出。后来我控制在3~5之间,问题就解决了。
从机延迟的典型配置:
| 场景 | 连接间隔 | 从机延迟 | 实际唤醒间隔 |
|---|---|---|---|
| 低功耗传感器 | 200ms | 4 | 1s |
| 实时控制 | 15ms | 0 | 15ms |
| 音频流 | 50ms | 2 | 150ms |
4.4 超时时间:最后的防线
超时时间,是主机判断连接是否断开的依据。如果主机在超时时间内没收到从机的任何回复,就会认为连接断了。
超时时间必须大于:连接间隔 × (1 + 从机延迟)。这是蓝牙规范强制要求的。
我曾经踩过的坑:
有一次我把超时时间设成连接间隔的2倍,想着够了吧?结果从机延迟设了4,实际唤醒间隔是5个连接事件。超时时间只够等2个事件,从机还在睡觉呢,主机就判定断连了。后来我养成了一个习惯:超时时间至少是「连接间隔 × (从机延迟 + 3)」。
超时时间的推荐范围:
- 稳定环境(室内、近距离):5s~10s
- 复杂环境(有遮挡、移动):10s~20s
- 极端环境(远距离、强干扰):20s~30s
4.5 三个参数的平衡公式
我个人习惯用一个简单公式来估算参数是否合理:
实际唤醒间隔 = 连接间隔 × (1 + 从机延迟)
超时时间 ≥ 实际唤醒间隔 × 3
举例:
连接间隔 = 50ms
从机延迟 = 3
实际唤醒间隔 = 50 × (1 + 3) = 200ms
超时时间 ≥ 200 × 3 = 600ms
实际设成 1s 比较稳妥
为什么是3倍?因为蓝牙通信有丢包重传机制。一次唤醒可能丢包,需要等下一个唤醒周期重传。3倍能保证至少有一次重传机会。
4.6 实战调优步骤
我一般按这个流程来调参数:
- 先定连接间隔:根据应用场景的延迟要求,确定连接间隔的上限
- 再定从机延迟:在满足延迟要求的前提下,尽量增大延迟来省电
- 最后定超时时间:按公式计算,再加50%的余量
- 实际测试:在真实环境中跑24小时,观察断连次数和功耗
避坑指南:
- 不要用蓝牙规范允许的最大值。规范允许4s的连接间隔,但实际很多手机不支持
- iOS和Android对连接参数的处理不一样。iOS更严格,参数不合理会直接拒绝连接
- 参数更新需要主机同意。从机可以发起参数更新请求,但主机有权拒绝
4.7 不同平台的参数限制
| 平台 | 最小连接间隔 | 最大连接间隔 | 从机延迟上限 | 超时时间范围 |
|---|---|---|---|---|
| iOS | 15ms | 100ms | 4 | 5s~30s |
| Android | 7.5ms | 4s | 9 | 1s~32s |
| Windows | 7.5ms | 4s | 9 | 1s~32s |
嗯,这里要注意。iOS的限制特别多。如果你做的是MFi设备,连接间隔不能超过100ms,从机延迟不能超过4。否则iOS会直接拒绝连接参数更新请求。
4.8 一个完整的调优案例
去年我做了一个蓝牙体温贴的项目。要求是:
- 每5秒上报一次体温数据
- 纽扣电池续航至少3个月
- 连接不能断,断了要能快速重连
我当时的参数配置:
连接间隔: 100ms
从机延迟: 4
超时时间: 6s
实际唤醒间隔: 100 × (1 + 4) = 500ms
每5秒上报数据,需要唤醒10次
每次唤醒发送1包数据,功耗约2mA
平均电流: 2mA × (10/5000) = 0.4mA
加上休眠电流0.01mA,总平均电流约0.41mA
纽扣电池CR2032容量约220mAh
理论续航: 220 / 0.41 ≈ 536小时 ≈ 22天
嗯,不够。后来我把连接间隔调到200ms,从机延迟设成9:
实际唤醒间隔: 200 × (1 + 9) = 2000ms
每5秒只需要唤醒2.5次
平均电流: 2mA × (2.5/5000) = 0.1mA
总平均电流约0.11mA
理论续航: 220 / 0.11 ≈ 2000小时 ≈ 83天
超时时间设成: 200 × (9 + 3) = 2400ms,取整设成3s
实际测试跑了90天,电池还有余量。连接一次都没断过。
小结一下:
连接参数调优没有万能公式。每个项目都要根据实际需求去试。我的建议是:先按理论算一遍,再在实际环境里跑一周,用抓包工具看看实际的连接事件间隔和丢包率。数据会告诉你该往哪个方向调。