4、从机延迟(Slave Latency):工作原理、省电机制、最大延迟计算、实际应用场景
从机延迟,英文叫 Slave Latency。这名字听起来有点吓人,其实说白了就是——让从设备能偷懒睡大觉的参数。
我刚开始做蓝牙项目时,总觉得这个参数可有可无。直到有一次做一款温湿度传感器,电池撑不过三天,老板差点让我去仓库搬货。后来我调大了 Slave Latency,续航直接飙到两周。嗯,从那以后我再也不敢小看它了。
4.1 工作原理:它到底在干什么?
先回忆一下蓝牙的连接事件。主设备和从设备每隔一个 Connection Interval 就得互相打个招呼,交换数据。哪怕两边都没话说,也得空转一次。
Slave Latency 的作用就是:允许从设备跳过若干个连接事件,不响应主设备的唤醒。
举个例子。假设 Connection Interval 是 30ms,Slave Latency 设为 4。那么从设备最多可以连续 4 个连接事件都不理主设备。主设备照常发数据包,但从设备可以继续睡觉。直到第 5 个连接事件,从设备才必须醒来回应。
核心逻辑:Slave Latency 不是强制从设备必须跳过,而是给它一个「跳过权」。有数据要发时,从设备随时可以醒来参与连接事件。没数据时,就安心睡大觉。
你想想看,这跟咱们平时上班摸鱼是不是有点像?活干完了,没必要一直盯着电脑,但老板叫你的时候你得在。
4.2 省电机制:为什么能省电?
蓝牙从设备的功耗大头在哪?不是数据处理,而是射频收发。每次连接事件,从设备都要打开接收器,等待主设备的数据包。这个过程大概持续几百微秒到几毫秒,但架不住次数多啊。
假设 Connection Interval 是 20ms,一小时就有 18 万个连接事件。每个事件耗电 0.5mAh,算下来光空转就吃掉不少电量。
Slave Latency 的省电逻辑很简单:减少射频开启次数。
- Latency = 0:每个连接事件都参与,射频一直忙活
- Latency = 10:每 11 个事件才参与一次,射频空闲时间暴增
我在项目中实测过一组数据,大家可以参考:
| Slave Latency | 连接事件参与率 | 相对功耗(基准 100%) | 适用场景 |
|---|---|---|---|
| 0 | 100% | 100% | 低延迟交互(鼠标、键盘) |
| 4 | 20% | 约 35% | 周期性上报(温湿度计) |
| 9 | 10% | 约 20% | 低频率传感器 |
| 19 | 5% | 约 12% | 极低功耗待机 |
个人经验:我习惯把 Slave Latency 设到 7~10 之间作为起点。这个区间省电效果明显,又不会让连接变得太迟钝。之后再根据实际测试微调。
4.3 最大延迟计算:别让数据堵在路上
Slave Latency 不是想设多大就设多大。蓝牙协议规定了一个上限,叫 Slave Latency Max。这个值由主设备在连接建立时协商,从设备只能接受或拒绝,不能单方面改大。
最大延迟的计算公式很简单:
最大延迟 = Connection Interval × (Slave Latency + 1)
举个例子:
- Connection Interval = 30ms
- Slave Latency = 9
- 最大延迟 = 30 × (9 + 1) = 300ms
这意味着从设备最坏情况下,要等 300ms 才能收到主设备的数据。如果应用层对实时性要求高,比如游戏手柄,300ms 的延迟用户能明显感觉到卡顿。
避坑指南:我曾经在一个项目中把 Slave Latency 设到 30,Connection Interval 是 50ms,算下来最大延迟 1.55 秒。结果设备配对后经常断连,因为主设备以为从设备挂了。后来我才意识到,最大延迟不能超过 Supervision Timeout 的一半,否则连接会不稳定。
蓝牙协议规定:
Supervision Timeout > (1 + Slave Latency) × Connection Interval × 2
翻译成人话就是:连接超时时间必须大于最大延迟的两倍。否则主设备在超时前收不到回应,直接判定连接丢失。
4.4 实际应用场景:什么时候该用?什么时候不该用?
Slave Latency 不是万能的。用对了是神器,用错了是坑。我按场景给大家梳理一下:
✅ 适合用 Slave Latency 的场景
- 周期性上报的传感器:温湿度计、气压计、光照传感器。这些设备每隔几秒甚至几分钟才上报一次数据,中间完全可以睡大觉。
- 低交互频率的配件:智能门锁、电子标签、资产追踪器。用户不会频繁操作,但要求电池撑半年以上。
- 数据量小的通知类设备:比如智能手环的心率监测,每 5 分钟上报一次平均值,不需要实时流式传输。
❌ 不适合用 Slave Latency 的场景
- 高实时性交互设备:游戏手柄、遥控器、无线鼠标。用户每次操作都希望立即响应,延迟超过 50ms 就会抱怨。
- 音频流传输:蓝牙耳机、音箱。音频数据是连续流,Slave Latency 会导致断流和卡顿。
- 需要频繁双向通信的设备:比如文件传输、OTA 升级。从设备需要持续参与连接事件,跳过反而降低吞吐量。
我的习惯做法:在项目初期,我会先确定应用层能容忍的最大延迟。比如用户按一下开关,希望在 200ms 内看到反馈。那我就把最大延迟控制在 150ms 以内,留 50ms 余量给协议栈和处理时间。然后反推 Slave Latency 的值。
4.5 核心知识体系
下面这张图是我自己总结的 Slave Latency 决策流程,每次做新项目我都会拿出来对照一下:
这张图的核心思路是:先看实时性,再看数据频率,最后验证超时约束。三步走完,Slave Latency 的值基本就定下来了。
4.6 几个容易踩的坑
最后分享几个我踩过的坑,希望大家别重蹈覆辙:
- 坑一:Slave Latency 设太大导致断连。前面说过,最大延迟不能超过 Supervision Timeout 的一半。我建议留 20% 的余量,别卡着上限设。
- 坑二:忽略主设备的能力。有些老款手机或蓝牙芯片,对 Slave Latency 的支持有限。设太大可能直接拒绝连接。我习惯在连接建立后读一下实际协商值,确认双方都接受。
- 坑三:动态调整时没考虑应用层。有些场景需要根据电量动态调整 Slave Latency。比如电量低于 20% 时增大延迟省电。但应用层可能正在做 OTA 升级,这时候增大延迟会导致传输变慢甚至超时。我一般会在调整前先通知应用层,等它进入空闲状态再改。
重要提醒:Slave Latency 不是越大越好。省电和延迟是一对矛盾体。我见过有人为了省电把 Latency 设到 50,结果设备响应慢得像蜗牛,用户差评如潮。记住一句话:省电的前提是不影响用户体验。