3. 连接建立:连接参数与参数协商

连接建立,是 BLE 通信真正开始的地方。很多初学者觉得这步就是「连上就行」,其实不然。连接参数没配好,项目后期会踩很多坑。我最早做穿戴项目时就吃过这个亏——设备连上了,但功耗高得离谱,用户一天充一次电,直接被投诉。

这一章,我们就把连接建立这件事拆开揉碎。从三个核心参数讲起,再走一遍连接流程,最后聊聊参数更新和协商。嗯,都是实战里绕不开的东西。

3.1 三个核心连接参数

BLE 连接建立后,主从设备之间会维持一个固定的通信节奏。这个节奏由三个参数决定:连接间隔(Connection Interval)、从机延迟(Slave Latency) 和 监控超时(Supervision Timeout)。

说白了,它们决定了「多久发一次数据」「能不能偷懒少发」「断连了多久能发现」。

3.1.1 连接间隔(Connection Interval)

连接间隔,是两次连接事件之间的时间。单位是 1.25ms,取值范围 7.5ms ~ 4s。举个例子:你设了 30(十进制),那实际间隔就是 30 × 1.25 = 37.5ms。

每次连接事件,主设备都会发送一个数据包,从设备必须在这个窗口内回复。所以连接间隔越短,实时性越好,但功耗也越高。

关键权衡:

  • 短间隔(7.5ms ~ 30ms):适合音频、数据透传、遥控等低延迟场景。代价是主从双方都要频繁唤醒,功耗高。
  • 长间隔(100ms ~ 1s):适合传感器、温湿度计、信标等低功耗场景。延迟大,但省电。

我在项目中遇到过一个问题:客户要求传感器数据每 200ms 上报一次,但连接间隔设了 50ms。结果每次上报要等 4 个连接事件才能发完,延迟反而大了。后来我把连接间隔调到 100ms,配合从机延迟,效果更好。

3.1.2 从机延迟(Slave Latency)

从机延迟,允许从设备跳过某些连接事件而不回复。取值范围 0 ~ 499,但必须满足一个公式:

(Slave Latency + 1) × Connection Interval × 1.25ms < Supervision Timeout

这个参数是省电的关键。比如连接间隔 50ms,从机延迟设 9,那从设备最多可以连续跳过 9 个连接事件(即 450ms)不回复。这期间从设备可以深度睡眠,大幅降低功耗。

我的习惯:对于周期性上报数据的传感器,我会把从机延迟设为「允许跳过 1~2 个间隔」。这样既保证数据及时性,又能省 20%~30% 的电。如果是按键类设备,延迟设 0,确保按键按下能立刻响应。

3.1.3 监控超时(Supervision Timeout)

监控超时,是主设备等待从设备回复的最长时间。单位 10ms,范围 100ms ~ 32s。如果超过这个时间还没收到从设备的任何数据包,主设备就认为连接已断开,进入断开状态。

这个值必须大于:

(Slave Latency + 1) × Connection Interval × 1.25ms

否则从设备合法跳过连接事件时,主设备会误判为断连。

我曾经踩过的坑:有个项目,从机延迟设了 100,连接间隔 30ms,监控超时只设了 2s。算一下:(100+1)×30×1.25 = 3787.5ms > 2000ms。结果设备经常莫名其妙断连。后来把监控超时改成 5s,问题解决。记住,这个公式是硬约束,不能违反。

3.2 连接建立流程

连接建立,从广播开始,到连接参数确认结束。我画了一张流程图,方便你理解整体脉络。

BLE 连接建立流程图 BLE 连接建立流程图 1. 从设备广播 2. 主设备扫描 3. 主设备发 CONNECT_REQ 4. 连接参数交换 5. 连接建立完成 说明:CONNECT_REQ 中包含了初始连接参数,后续可通过参数更新流程修改 从设备可以在连接建立后发起参数更新请求,主设备决定是否接受

具体步骤如下:

  1. 从设备广播:从设备在广播信道(37/38/39)上发送广播包,包含设备地址、广播数据等。
  2. 主设备扫描:主设备在广播信道上监听,收到广播包后,可以发起连接。
  3. 主设备发 CONNECT_REQ:主设备发送连接请求帧,包含初始连接参数(连接间隔、从机延迟、监控超时等)。
  4. 连接参数交换:从设备收到 CONNECT_REQ 后,按参数建立连接。如果参数不合理,从设备可以拒绝或后续发起参数更新。
  5. 连接建立完成:双方按协商好的参数开始通信。

注意:CONNECT_REQ 中的参数是主设备单方面决定的。从设备如果觉得参数不合适,可以在连接建立后发起参数更新请求。我建议从设备在固件里预留参数校验逻辑,避免被主设备「带偏」。

3.3 连接更新与参数协商

连接建立后,参数不是一成不变的。BLE 协议栈提供了 连接参数更新请求(Connection Parameter Update Request) 机制,允许从设备主动发起参数协商。

为什么需要参数更新?举个例子:设备刚连上时,需要快速传输大量数据(比如固件升级),这时候需要短连接间隔。升级完成后,进入低功耗待机模式,又希望拉长间隔省电。参数更新就是干这个的。

3.3.1 参数更新流程

参数更新流程如下:

  1. 从设备发起请求:从设备发送 LL_CONNECTION_PARAM_REQ,包含期望的新参数。
  2. 主设备响应:主设备收到后,可以选择接受、拒绝或提出自己的参数。
  3. 协商完成:双方达成一致后,按新参数继续通信。

关键点:参数更新请求只能在连接建立后发起,且必须通过 LL(Link Layer)层协议完成。应用层不能直接修改连接参数,必须通过协议栈提供的 API。

3.3.2 参数协商的实战策略

我在多个项目中总结了一套参数协商策略,分享给你:

场景 推荐连接间隔 从机延迟 监控超时 说明
固件升级(OTA) 7.5ms ~ 15ms 0 500ms 高吞吐,低延迟
传感器数据上报 100ms ~ 500ms 1 ~ 5 2s ~ 5s 平衡功耗与实时性
低功耗待机 1s ~ 4s 10 ~ 50 10s ~ 20s 极致省电
按键/遥控器 30ms ~ 50ms 0 1s 快速响应

我曾经踩过的坑:有个项目,从设备在 OTA 完成后主动发起参数更新,想把连接间隔从 10ms 改成 1s。但主设备不支持参数更新,直接忽略了请求。结果设备一直以 10ms 间隔运行,功耗爆炸。后来我在从设备固件里加了超时重试机制:如果参数更新请求被忽略,就主动断开连接,重新以长间隔广播连接。这样虽然会断连一次,但至少保证了功耗可控。

3.3.3 参数更新的限制

参数更新不是万能的。有几个限制你必须知道:

  • 主设备可能不支持:有些 BLE 主设备(比如老旧手机)不支持参数更新,从设备只能接受初始参数。
  • 参数范围受限:连接间隔不能小于 7.5ms,监控超时不能大于 32s。这些是 BLE 规范硬性规定的。
  • 协商可能失败:主设备可以拒绝参数更新请求。从设备需要做好失败处理,比如保持当前参数或断开重连。

我的建议:在从设备固件里,把参数更新设计成「可配置的」。比如通过一个特征值,让主设备可以随时写入新的参数期望值。这样即使参数更新失败,也可以通过断开重连来应用新参数。我在一个医疗设备项目里就是这么做的,客户后来改需求时,我只需要改一下特征值,不用动固件。

3.4 本章小结

连接参数是 BLE 通信的基石。连接间隔决定通信频率,从机延迟决定省电能力,监控超时决定断连检测速度。三者必须满足公式约束,否则会出现莫名其妙的问题。

连接建立流程看似简单,但 CONNECT_REQ 中的参数是主设备决定的。从设备如果想改,必须在连接建立后发起参数更新请求。参数更新不是总能成功,所以固件里要做好容错处理。

嗯,这一章的内容就到这里。参数配置没有银弹,每个项目都要根据实际场景去调。你可以在开发板上试试不同参数组合,看看功耗和延迟的变化,感受会更直观。