前言
(1)自适应跳频算法是相当的简单,小学生都能够看懂,而且网上已经有相当多的关于自适应跳频算法的介绍。既然如此,为什么我还要写这样一篇博客呢?
(2)原因很简单,我发现各位大佬可能是觉得自适应跳频算法太简单,以至于又加上了一堆其他深奥的内容,用以拔高整篇博客质量。当然,深度提高了,但是对于我这种小菜鸡来说,就容易搞的脑壳痛。
(3)因此,这里小菜鸡斗胆再写一篇博客介绍一下自适应跳频算法,并举例进行分析。
为什么需要自适应跳频算法
(1)首先我们需要知道
BLE
的40
个信道分布如下。
(2)在
40
个信道中,数据信道0 ~ 8
,11 ~ 20
,24 ~ 31
这些信道都将会与WI-FI
信道进行冲突。除了常见的WI-FI
以外,因为2.4GHZ
频段属于免费频段因此还会有例如Zigbee
等协议采用该频段,造成拥挤。
(3)为了保证
BLE
通讯过程中,降低与其他无线电协议产生碰撞几率,就需要使用一个跳频算法来进行保证。
(4)因此,我们即可知道,自适应跳频算法就是一种频率跳变的无线电技术,它能够屏蔽差的信道并将其重新映射到好的信道。
自适应跳频算法介绍
自适应跳频算法公式
(1)跳频算法公式如下:
<1> f n f_{n} fn : 当前BLE
连接事件使用的信道。
<2> f n + 1 f_{n+1} fn+1 : 下一次BLE
连接事件使用的理论信道。
<3> h o p hop hop : 每次跳频的间隔,值为5~16
。
<3> % \% % : 取余,因为数据信道只有37
个。
f n + 1 = ( f n + h o p ) % 37 f_{n+1}=(f_{n} + hop) \% 37 fn+1=(fn+hop)%37
(2)在跳频算法中,我们计算出来的 f n + 1 f_{n+1} fn+1 可能并不是可用信道,因此就需要
ChannelMap
、Used
、numUsed
这三个参数了。
<1>ChannelMap
:5byte
数据,实际使用37bit
,用来表示设备间传输的信道图。其中0
表示信道不可用,1
表示信道可用。高位表示信道数高,低位为信道数低。
<2>Used
: 一个数组,用来记录当前ChannelMap
中的可用信道。
<3>numUsed
: 可用信道数量。
(3)当我们在上述的跳频算法中,获得的 f n + 1 f_{n+1} fn+1并不是可用信道时,就需要再使用如下算法得重映射后的信道。
<1> C h a n n e l Channel Channel : 重映射后的信道。
<2> U s e d [ ] Used[] Used[] : 可用信道数组
<3> f n + 1 f_{n+1} fn+1 : 下一次BLE
连接事件使用的理论信道。
<4> % \% % : 取余,因为可用数据信道只有numUsed
个。
<5> n u m U s e d numUsed numUsed : 可用信道数量。
C h a n n e l = U s e d [ f n + 1 % n u m U s e d ] Channel = Used[f_{n+1} \% numUsed] Channel=Used[fn+1%numUsed]
自适应跳频算法举例说明
所有信道均正常
(1)首先,我们假设
0~37
个信道都是可供BLE
进行使用的。那么此时的
<1>ChannelMap = 0001 1111 1111 1111 1111 1111 1111 1111 1111 1111
<2>Used = [0,1,2,3,4,5,...,35,36]
<3>numUsed = 37
(2)我们预设hop
值为5
,初始信道 f n f_{n} fn为0
,那么信道分布如下:
<0>我们第一个信道设置为0,为好信道,因此无需进行重映射。因此实际信道也为0。
<1>因为上一个信道 f n f_{n} fn为0
,hop
为5
,所以 f n f_{n} fn+hop = 5,5 % 37 = 5
。而信道5
为可用信道,因此此时采用信道5
。
<…>
<8>因为上一个信道 f n f_{n} fn为35
,所以 f n f_{n} fn+hop = 40,40 % 37 = 3
。而信道3
为可用信道,因此此时采用信道3
。
连接事件计数器 | 未映射时信道 | 是否进行映射 | 实际信道 |
---|---|---|---|
0 | 0 | 否 | 0 |
1 | 5 | 否 | 5 |
2 | 10 | 否 | 10 |
3 | 15 | 否 | 15 |
4 | 20 | 否 | 20 |
5 | 25 | 否 | 25 |
6 | 30 | 否 | 30 |
7 | 35 | 否 | 35 |
8 | 3 | 否 | 3 |
部分信道正常
(1)上述情况为理想状态,那么我们现在假设
3
个主要的WI-FI
信道都正在使用,此时的
<1>ChannelMap = 0001 1110 0000 0000 1110 1111 1111 0110 0000 0000
。注意,从左到右表示36
到0
信道。
<2>Used = [9,10,21,22,23,33,34,35,36]
<3>numUsed = 9
(2)我们预设hop
值为7
,初始信道 f n f_{n} fn为7
,那么信道分布如下:
<0>首先,因为我们的初始信道 f n f_{n} fn为7
,而信道7
不是可用信道,因此它会被重映射。因为numUsed = 9
,所以 f n + 1 m o d n u m U s e d = 7 m o d 9 = 7 f_{n+1} \ mod \ \ numUsed = 7 \ mod \ 9 = 7 fn+1 mod numUsed=7 mod 9=7。又因为Used[7] = 35
,因此最终重映射后的实际信道为35
。
<…>后面计算方法同理。
连接事件计数器 | 未映射时信道 | 是否进行映射 | 实际信道 |
---|---|---|---|
0 | 7 | 是 | 35 |
1 | 14 | 是 | 33 |
2 | 21 | 否 | 21 |
3 | 28 | 是 | 10 |
4 | 35 | 否 | 35 |
5 | 5 | 是 | 33 |
6 | 12 | 是 | 22 |
7 | 19 | 是 | 10 |
8 | 26 | 是 | 36 |
9 | 33 | 否 | 33 |
10 | 3 | 是 | 22 |
11 | 10 | 否 | 10 |
自适应跳频算法学习存在问题
为什么hop为5~16?
(1)根据上面的例子,想必各位已经能够成功掌握自适应跳频算法了。那么,我们此时是否应该思考一个问题,为什么跳频算法的跳数值
hop
是在5~16
范围内呢?
(2)因为大多数干扰一般都会占据几兆带宽,使用过小的hop
值,并不能快速的脱离干扰源,这样将会造成持续的干扰。
(3)同理,如果使用过大的hop
值,也无法快速脱离干扰源。根据前面所说的跳频算法,如果我们的 f n = 20 f_{n} = 20 fn=20, h o p = 17 hop = 17 hop=17,那么第一次信道为20
,第二次就是0
,第三次就是17
。 这样我们会发现第一次和第三次的信道差距仅仅3
个信道。
存在一个好信道,为什么不一直使用到不能使用为止?
(1)通过上面的了解,我们又会发现一个问题。如果某个信道是可用的,那为什么还需要跳到下一个信道中呢?按照常识来说,既然我们找到了一个可用信道,不应该一直使用该信道,直到该信道不可用为止吗?
(2)这个时候我们就需要考虑到一个问题,我们发现当前信道不可用了,那么做出改变,还来得及吗?因为数据信道大多和WI-FI
的信道存在冲突,而WI-FI
这种互联网流量存在突发性。当我们突然发现该信道不可用了,那么我们想通知对端设备更改信道,此时会发现,信息将无法有效的被对端设备接收。
(3)一旦信道失效,BLE
设备就需要断开连接,重新进行连接同步,这将会耗费许多能量。
(4)而且处于同一区域的网络,会自发的选择干净的频率。如果使用单信道模型,将会出现,短时间相同信道网络数量激增情况。(这个从现实角度举例,就好比大家发现某个专业很好,就都一股脑往里面冲,最终导致内卷严重)
(5)如果使用跳频算法,将能够对网络流量在时域和频域做出合理的分配,这样就能够允许大量的网络在同一区域同时工作。(注意,这个“同时”是较大的单位,例如分钟。如果从us
级单位来看,并不是同时工作)
(6)最终,BLE
设备采用是的,一个连接事件之内保持相同信道进行数据的交互,在下一个连接事件到来之时,将会换至另外一个信道中进行通讯。
参考
(1)低功耗蓝牙开发权威指南 — 7.4 信道
(2)低功耗蓝牙开发权威指南 — 7.7.5 信道图
(3)低功耗蓝牙开发权威指南 — 7.11.1 自适应跳频
(3)低功耗蓝牙开发权威指南 — 7.12.5 单信道连接事件