蓝牙具有5种状态:
待机状态(standby) :没有连接任何设备,没有传输和发送数据。
广播状态(Advertiser/advertising):周期性广播状态。
扫描状态(Scanner/scanning) :主动寻找正在广播的设备。
发起连接状态(Initiator/initiating):主动发起连接。
连接状态(connected) :已经连接。
蓝牙的角色将决定蓝牙如何在5种状态中跳转,在蓝牙SDK的框架中也是按照这五种状态为脉络来进行架设的。
SLAVE MASTER
standby standby
advertising scanning
initiating
connected connected
从设备从standby状态进入advertising后就开始按照广播参数进行广播,主机从standby状态进入scanning后,则开始在对应的三个广播通道上监听。监听到的广播信息将通过扫描事件和消息返回。主机决定发起连接设备,进入initiating状态。
链接事件和链接参数
主设备和从设备建立连接后,所有的数据的通信都是在连接事件中进行的。如下图的电流检测曲线所示。
主从设备会按照约定好的一个时间间隔进行一次首发通信,这就像我们通常使用的串口一样,约定好一个波特率,串口中叫波特率是因为每次都串数一个bit,而蓝牙中则被称为链接间隔。在链接间隔之间,蓝牙一直处于sleep模式,这样就会让蓝牙的整个通信非常的省电。所以蓝牙对于时钟计数非常的在意,为什么经常手机连接着设备一会就断了,就是不同步了。
在每个链接事件中,都需要MASTER设备发起包,然后有SLAVE设备进行回复。对于链接的参数,主要是规定主从机通信的时间:
- intervalMin :最小的连接间隔,一般设置范围为6-3200,单位是1.25msintervalMax:最大链接间隔,范围同样是6-3200,单位是1.25msslaverLatency:从机忽略时间,范围是0-499,单位也是1.25mstimeout:超时时间,设置范围10-3200,单位是10ms。
从上面可以计算,蓝牙的链接间隔最短是7.5ms,最长是4s。这里要注意,手机蓝牙的连接间隔的可是值范围并不一样,苹果系统的一般是20ms起步,而各式各样的Android手机不尽相同,但大多数可以从7.5ms起步。
什么是slave Latency呢?
上面提到过,每过一个链接间隔,主从机都会发送和回复一次数据。那么为了让从机能够更省电,我们肯定不希望从机每次都老老实实的回复,因此蓝牙协议中允许从机可以沉默几次,下图是slaverLatency分别为0和3的对比:
再说timeout参数,其设置范围实际为100ms - 32s。这个参数给主从机提供一个判断链接的门限,如果没有链接事件的时间持续超过设定的timeout值,则认定通信连接断开。
连接参数影响功耗和体验
- 链接间隔设置缩短,也就意味着1s内MASTER和SLAVE之间的额通信更频繁,这样可以提高数据吞吐量,当然对应的功耗就会增加。链接间隔设置增长,通信频率降低,数据吞吐量也降低,这样可以有效的降低蓝牙通信的功耗。salve Latency设置小的话,从机回复主机的频次增多,从机的功耗就会增加。salve Latency设置大的话,从机回复主机的频次减少,从机的功耗就会减小。
手机中需要注意的问题:
- 安卓手机作为主设备时,部分手机连接BLE设备后,只能进行一次连接参数的修改,因此从设备最好不要频繁请求修改,开始就规划好链接参数。苹果系统对于链接参数的更新更苛刻,想上面提到的链接间隔必须从20ms起步,slave Latency要小于4,同时timeou要小于6s。