连接间隔详解:7.5ms到4s的范围选择
连接间隔,说白了就是两个设备之间「多久聊一次天」。
BLE协议规定,这个间隔可以在7.5ms到4s之间任意选择。但你别以为随便选一个就行。我见过太多项目,就是因为间隔没选好,要么功耗爆炸,要么数据丢包。
今天我就把这块掰开揉碎了讲清楚。
连接间隔到底是什么?
连接间隔,指的是两个BLE设备之间,两次连接事件的时间差。
每次连接事件,主设备和从设备会交换一次数据。你可以把它想象成两个人打电话——
- 短间隔:相当于每7.5ms就通一次话,每次说几句话就挂
- 长间隔:相当于每4s才通一次话,每次可以多说点
嗯,这个比喻虽然糙了点,但道理是一样的。
7.5ms到4s,这个范围怎么来的?
这个范围不是随便定的。我查过蓝牙Core Spec 5.x,里面明确规定了连接间隔的单位是1.25ms。
所以实际可选的间隔值是:
连接间隔 = N × 1.25ms
其中N的范围是:6 ~ 3200
6 × 1.25ms = 7.5ms
3200 × 1.25ms = 4000ms = 4s
你可能会问:为什么是1.25ms?
其实这是为了兼容蓝牙时钟的精度。BLE的时钟基频是3.2kHz,周期正好是312.5μs。1.25ms是它的4倍,方便硬件做分频。
短间隔的利弊分析
短间隔,我一般指7.5ms到30ms这个范围。
优点:
- 延迟低。数据从发送到接收,最快7.5ms就能完成
- 适合实时性要求高的场景,比如游戏手柄、鼠标
- 数据吞吐量大。单位时间内能传输更多数据包
缺点:
- 功耗高。设备频繁唤醒,电流消耗直线上升
- 信道拥挤。频繁占用射频资源,容易碰撞
- 对硬件要求高。MCU需要频繁处理中断
我记得有个项目是做蓝牙鼠标的。当时我选了7.5ms的间隔,结果电池两天就没电了。后来改成15ms,功耗降了一半,用户也感觉不到延迟差异。
所以你看,不是越短越好。
长间隔的利弊分析
长间隔,我一般指100ms以上,甚至到4s。
优点:
- 功耗极低。设备大部分时间都在休眠
- 信道利用率高。射频资源占用少
- 适合电池供电的传感器设备
缺点:
- 延迟高。数据从产生到发送,可能要等几百毫秒甚至几秒
- 吞吐量低。单位时间内能传的数据有限
- 不适合实时控制类应用
我曾经做过一个温湿度传感器项目,要求电池用一年。我选了1s的连接间隔,配合深度睡眠,最终实现了两节AA电池用18个月。
但如果你拿这个间隔去做智能锁,那用户按一下按钮要等1秒才有反应,体验就太差了。
如何选择连接间隔?
这里我给出一个经验法则:
| 应用场景 | 推荐间隔 | 原因 |
|---|---|---|
| 游戏手柄、鼠标 | 7.5ms ~ 15ms | 需要低延迟 |
| 音频传输 | 15ms ~ 30ms | 平衡延迟和吞吐量 |
| 健康监测(心率、血氧) | 50ms ~ 100ms | 数据量不大,但需要实时性 |
| 环境传感器(温湿度、气压) | 500ms ~ 2s | 数据变化慢,省电为主 |
| 信标、定位标签 | 1s ~ 4s | 极低功耗,偶尔上报位置 |
当然,这只是参考。实际项目中,你还要考虑:
- 主设备的处理能力
- 射频环境是否嘈杂
- 电池容量和寿命要求
- 数据包的大小和频率
避坑指南
我曾经踩过的坑:
有一次做多设备连接的项目,一个手机同时连了6个传感器。我每个传感器都设了7.5ms的间隔。结果呢?手机蓝牙直接崩溃了,因为每个连接事件都要处理,根本忙不过来。
后来我把间隔错开,有的设10ms,有的设15ms,有的设20ms,问题就解决了。
所以,多设备场景下,不要所有设备都用同一个间隔。错开一点,能大大降低主设备的负担。
连接间隔的协商机制
你可能不知道,连接间隔不是主设备单方面决定的。
从设备可以通过「连接参数更新请求」来协商。具体流程是:
- 从设备发送LL_CONNECTION_PARAM_REQ
- 主设备收到后,可以选择接受或拒绝
- 如果接受,双方在新的间隔下工作
嗯,这里要注意:iOS对连接参数更新有严格限制。苹果要求从设备必须在连接建立后5秒才能发起更新请求,而且间隔不能低于30ms。
我建议你在做iOS兼容时,直接设好30ms以上的间隔,省得后面还要协商。
实际项目中的经验
我个人习惯的做法是:
- 先根据应用场景选一个初始间隔
- 然后做功耗测试,看实际电流曲线
- 如果功耗超标,逐步增大间隔,每次增加50%
- 如果延迟超标,逐步减小间隔,每次减少30%
你想想看,这样迭代几次,总能找到最优值。
另外,我建议你在产品中预留一个动态调整间隔的接口。这样用户可以根据自己的使用习惯来调节,比如「省电模式」用长间隔,「性能模式」用短间隔。
小技巧:
如果你用的是Nordic的nRF5 SDK,可以直接调用sd_ble_gap_conn_param_update()来更新连接间隔。代码大概是这样:
ble_gap_conn_params_t conn_params;
conn_params.min_conn_interval = 80; // 100ms
conn_params.max_conn_interval = 120; // 150ms
conn_params.slave_latency = 0;
conn_params.conn_sup_timeout = 4000; // 4s
sd_ble_gap_conn_param_update(conn_handle, &conn_params);
总结
连接间隔的选择,本质上是在功耗和性能之间做权衡。
短间隔适合实时控制,但费电。长间隔省电,但延迟高。没有完美的值,只有适合你项目的值。
我建议你:
- 先明确你的核心需求(低延迟还是低功耗)
- 参考上面的表格选一个初始值
- 实际测试后微调
- 别忘了考虑多设备场景和iOS兼容性
下一章,我会讲从设备延迟(Slave Latency)这个参数。它能在不增加延迟的情况下,进一步降低功耗。敬请期待。