1.蓝牙简介
什么是蓝牙4.0
蓝牙无线技术是使用范围最广泛的全球短距离无线标准之一,蓝牙4.0版本涵盖了三种蓝牙技术,即传统蓝牙、高速蓝牙和低功耗蓝牙技术,将三种规范合而为一。它继承了蓝牙技术在无线连接上的固有优势,同时增加了高速蓝牙和低功耗蓝牙的特点。这三个规格可以组合或者单独使用。蓝牙4.0规范的核心是低功耗蓝牙(Low Energy),即蓝牙4.0BLE。该技术最大特点是拥有超低的运行功耗和待机功耗,蓝牙低功耗设备使用一粒纽扣电池可以连续工作数年之久。蓝牙4.0技术同时还拥有低成本、向下兼容、跨厂商互操作性强等特点。
蓝牙4.0 BLE技术具有如下特点:
1.高可靠性
对于无线通信而言,由于电磁波在传输过程中容易受很多因素的干扰,例如,障碍物的阻挡、天气状况等。因此,无线通信系统在数据传输过程中,具有内在的不可靠性。
蓝牙技术联盟(SIG)在制定蓝牙4.0规范时已经考虑到了这种数据传输过程中的内在的不确定性,所以在射频、基带协议、链路管理协议(LMP)中采用可靠性措施,包括:差错检测和校正、进行数据编解码、差错控制、数据加噪等,极大地提高了蓝牙无线数据传输的可靠性。另外,使用自适应跳频技术,最大程度地减少和其他2.4GHz ISM频段无线电波的串扰。
2.低成本、低功耗
低功耗蓝牙支持两种部署方式:双模方式和单模方式。
(1)双模方式,低功耗蓝牙功能集成在现有的经典蓝牙控制器中,或在现有经典蓝牙技术(2.1+EDR/3.0+HS)芯片上增加低功耗堆栈,整体架构基本不变,因此成本增加有限。
(2)单模方式,面向高度集成、紧凑的设备,使用一个轻量级连接层(Link Layer)提供超低功耗的待机模式操作。蓝牙4.0BLE技术可以应用于8bit MCU,目前TI公司推出的兼容蓝牙4.0BLE协议的SoC芯片CC2540/CC2541,外接PCB天线和几个阻容器件构成的滤波电路即可实现蓝牙网络节点的构建。
低功耗设计:蓝牙4.0版本强化了蓝牙在数据传输上的低功耗性能,功耗较传统蓝牙降低了百分之九十。
传统蓝牙设备的待机耗电量大一直是其缺陷之一,这与传统蓝牙技术采用 16~32 个频道进行广播不无关系,而低功耗蓝牙仅使用了3个广播通道,且每次广播时射频的开启时间也由传统的 22.5ms 减少到 0.6~1.2ms,这两个协议规范的改变,大幅降低了因为广播数据导致的待机功耗。
低功耗蓝牙设计了用深度睡眠状态来替换传统蓝牙的空闲状态,在深度睡眠状态下,主机(Host)长时间处于超低的负载循环(Duty Cycle)状态,只在需要运作时由控制器来启动,由于主机较控制器消耗的能源更多,因此这样的设计也节省了最多的能源。
3.快速启动,瞬间连接
此前蓝牙版本为人诟病的地方就在于启动速度方面,蓝牙2.1版本的启动连接需要 6s 时间,而蓝牙4.0版本仅仅需要3ms即可完成,几乎是瞬间连接。
4.传输距离极大提高
传统蓝牙传输距离为 2~10m,而蓝牙4.0的有效传输距离可达到 60~100m,传输距离提升了十倍,极大开拓了蓝牙技术的应用前景。当然,上述距离数值是在理想状态下,实际使用过程中因为各种因素的影响,比如:空气湿度、其他电磁信号干扰等等,导致实际距离可能达不到上述理论值,通过抗干扰等处理可以提高实际的传输距离。
5.高安全性
为了保证数据传输的安全性,使用AES-128 CCM加密算法进行数据包加密和认证。
蓝牙4.0BLE网络拓扑结构分为星型拓扑和广播组拓扑。不同的网络拓扑对应不同的应用领域,在蓝牙4.0BLE的无线网络中,不同的网络拓扑结构对网络节点的配置有不同的要求(蓝牙网络节点的类型可以分为主机、从机,也可以分为服务器、客户端,具体配置需要根据配置文件决定)。
2.蓝牙的状态以及基本连接过程
2.1 蓝牙的状态:
蓝牙具有5种状态:
待机状态(standby) :没有连接任何设备,没有传输和发送数据。
广播状态(Advertiser/advertising):周期性广播状态。
扫描状态(Scanner/scanning) :主动寻找正在广播的设备。
发起连接状态(Initiator/initiating):主动发起连接。
连接状态(connected) :已经连接。
2.2蓝牙的角色
主设备 从设备
2.3蓝牙的连接流程
BLE连接流程 |
找公司服务比喻 |
||
Master |
Slave |
消费者 |
服务方 |
待机模式 |
待机模式 |
空闲 |
空闲 |
扫描模式 |
广播模式 |
寻找公司 |
发广告 |
扫描请求 |
扫描回应 |
咨询能提供什么服务 |
告知服务 |
连接请求 |
签署业务合同 |
||
连接参数请求 |
具体合同内容 |
||
参数更新请求 |
合同修改 |
||
参数更新回应 |
合同回应 |
||
建立连接 |
签署合同 |
||
连接事件 |
开始业务合作 |
2.4连接事件和参数
2.4.1连接事件
主设备和从设备建立连接之后,所有的数据通信都是在连接事件(Connection Events)中进行的。
尖刺的波就是连接事件(Connection events),剩下的Sleeping是睡眠时间,设备在建立连接之后的大多数时间都是处于Sleeping,这种情况下耗电量比较低,而在连接事件(Connection events)中,耗电量就相对高很多,这也是BLE为什么省电的原因之一。
每个连接事件(Connection events)中,都需要由Master发起包,再由Slave回复。
2.4.2连接参数
连接参数用于规定主从机数据通信时间,如果连接参数设置不合理,就会导致连接断开。
主要连接参数有以下三个:
连接间隔(Connection interval)
(GAPROLE_MIN_CONN_INTERVAL && GAPROLE_MAX_CONN_INTERVAL)连接间隔,在BLE的两个设备的连接中使用跳频机制。两个设备使用特定的信道发送和接收数据,然后过一段时间后再使用新的信道(BLE协议栈的链路层处理信道的切换)。
两个设备在切换信道后发送和接收数据称为一个连接事件。尽管没有应用数据被发送和接收,两个设备仍旧会交换链路层数据(空包 Empty PDU)来维持连接。
连接间隔就是指在一个连接事件(Connection events)的开始到下一个连接事件(Connection events)的开始的时间间隔。连接间隔以1.25ms为单元,连接间隔的范围是6 ~ 3200既7.5ms ~ 4s之间。
从机忽略(Slave Latency)
允许Slave(从设备)在没有数据要发的情况下,跳过一定数目的连接事件(Connection events),在这些连接事件(Connection events)中不必回复Master(主设备)的包,这样就能更加省电。
范围可以是0 ~ 499
更详细的使用解析如下:
Slave Latency = OFF也就是Slave Latency为0时,Master发包,Slave必须回复,如果不回复,Master就会认为Slave那边接收不正常。
Slave Latency = ON也就是Slave Latency不为0的时候,图中Slave Latency为 3。Master发包,Slave没有数据要回复的时候,就会忽略 3 个连接事件,在第 4 个连接事件接收到Master发送的数据之后,回复Master。如果Slave有数据要发送就会唤醒,也就是说即使Slave Latency为 3,但是在Master发第二包的时候Slave有数据要回复,这个时候就会立即回复Master而不是等到 3 个连接事件之后的第 4 个连接事件去回复。
超时时间(Supervision Timeout)
这个参数设定了一个超时时间,如果BLE在这个时间内没有发生通信的话,就会自动断开。
单位是 10ms,该变量的范围是10 ~ 3200,折算成时间范围是100ms ~ 32s 。
连接间隔、从机时延以及超时时间这三者必须满足如下公式:
Supervision Timeout > (1 +slaveLatency)* (connectionInterval)
上述公式必须满足,否则连接就会不正常断开。
这三个连接参数不同情况下对通信速率和功耗的影响:
1.Connection Interval缩短,Master和Slave通信更加频繁,提高数据吞吐速度,缩短了数据发送的时间,当然也增加了功耗。
2.Connection Interval增长,通信频率降低,数据吞吐速度降低,增加了数据发送的时间,当然,这种设置降低了功耗。
3.Slave Latency减少或者设置为 0,每次Connection Events中都需要回复Master的包,功耗会上升,数据发送速度会提高。
4.Slave Latency加长,功耗下降,数据发送速度降低。
注意修改连接参数的时候要满足一定的要求:
1.安卓设备作主设备时,连接参数满足的要求见本篇博文第二节"连接参数介绍"中提到的内容。另外实际开发过程中发现安卓设备作主设备时存在一个问题,就是部分安卓设备连接BLE设备之后,只能进行一次连接参数的修改。
2. 苹果系统设备作主设备时,连接参数更新的要求比较苛刻,如下:
Interval Max * (Slave Latency + 1) ≤ 2 seconds
Interval Min ≥ 20 ms
Interval Min + 20 ms ≤ Interval Max
Slave Latency ≤ 4
connSupervisionTimeout ≤ 6 seconds
Interval Max * (Slave Latency + 1) * 3 < connSupervisionTimeout
即:
最大连接间隔时间 *(从机延迟 + 1) ≤ 2s
最小连接间隔时间 ≥ 20 ms
最小连接间隔时间 + 20 ms ≤ 最大连接间隔时间
从机延迟 ≤ 4
超时时间 ≤ 6s
最大连接间隔时间 *(从机延迟 + 1)* 3 < 超时时间
所以如果你的BLE从设备需要被IOS主设备连接,那你的BLE从设备的默认申请的连接参数一定要满足上述要求,并且连接过程中修改连接参数的时候也要满足上述要求。
3.蓝牙广播的协议
蓝牙广播相关的参数有以下几种:
Advertising interval 广播间隔
Advertising_Type 广播类型
Own_Address_Type 自身地址类型
Direct_Address_Type 定向地址类型
Direct_Address 定向地址
Advertising_Channel_Map广播信道(一个广播有三个信道)
Advertising_Filter_Policy 广播过滤策略
Advertising Data 广播数据
ScanReponse Data 响应数据
Advertising_Type广播类型
1. 可连接的非定向广播(Connectable Undirected Event Type):
这是一种用途最广的广播类型,包括广播数据和扫描响应数据,它表示当前设备可以接受其他任何设备的连接请求。进行通用广播的设备能够被扫描设备扫描到,或者在接收到连接请求时作为从设备进入一个连接。通用广播可以在没有连接的情况下发出,换句话说,没有主从设备之分。
鉴于此种广播类型用的最多,下面我们来讨论一下此类型下广播事件中广播包的发送情况,另外要注意在一个广播事件中,前一个"ADV_IND PDUs"的开始到相邻的下一个"ADV_IND PDUs"的开始处的时间要小于等于10ms :
第一种情况:仅仅有广播 PDUs 。截图显示如下:
第二种情况:在广播事件的中间有"SCAN_REQ"和"SCAN_RSP PDUs"。截图显示如下:
第三种情况:在广播事件的结尾有"SCAN_REQ"和"SCAN_RSP PDUs"。截图显示如下:
第四种情况:在广播事件的中间接收到"CONNECT_REQ PDU"的情况。截图显示如下
2. 可连接的定向广播(Connectable Directed Event Type):
定向广播类型是为了尽可能快的建立连接。这种报文包含两个地址:广播者的地址和发起者的地址。发起者收到发给自己的定向广播报文之后,可以立即发送连接请求作为回应。
定向广播类型有特殊的时序要求。完整的广播事件必须每3.75ms重复一次。这一要求使得扫描设备只需扫描3.75ms便可以收到定向广播设备的消息。
当然,如此快的发送会让报文充斥着广播信道,进而导致该区域内的其他设备无法进行广播。因此,定向广播不可以持续1.28s以上的时间。如果主机没有主动要求停止,或者连接没有建立,控制器都会自动停止广播。一旦到了1.28s,主机便只能使用间隔长得多的可连接非定向广播让其他设备来连接。
当使用定向广播时,设备不能被主动扫描。此外,定向广播报文的净荷中也不能带有其他附加数据。该净荷只能包含两个必须的地址。
3. 不可连接的非定向广播(Non-connectable Undirected Event Type):
仅仅发送广播数据,而不想被扫描或者连接。这也是唯一可用于只有发射机而没有接收机设备的广播类型。不可连接广播设备不会进入连接态,因此,它只能根据主机的要求在广播态和就绪态之间切换。
4. 可扫描的非定向广播(Scannable Undirected Event Type):
又称可发现广播,这种广播不能用于发起连接,但允许其他设备扫描该广播设备。这意味着该设备可以被发现,既可以发送广播数据,也可以响应扫描发送扫描回应数据,但不能建立连接。这是一种适用于广播数据的广播形式,动态数据可以包含于广播数据之中,而静态数据可以包含于扫描响应数据之中。
注意:所谓的定向和非定向针对的是广播的对象,如果是针对特定的对象进行广播(在广播包PDU中会包含目标对象的MAC)就是定向广播,反之就是非定向。可连接和不可连接是指是否接受连接请求,如果是不可连接的广播类型,它将不回应连接请求。可扫描广播类型是指回应扫描请求。
不同的广播类型对扫描请求和连接请求的不同结果如下图:
Advertising And ScanReponse Data (广播和扫描回应数据)
广播数据和扫描回应数据,它们的长度都不能超过31个字节(0 ~ 31),
数据的格式必须满足下图的要求,可以包含多个AD数据段,但是每个AD数据段必须由"Length:Data"组成,其中Length占用1个octet,Data部分占用Length个字节,所以一个AD段的长度为:Length+1。
格式图如下所示:
注:1 octet = 1 byte = 8 bit