BLE入门 20 蓝牙5速率分析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BLE入门 20 蓝牙5速率分析相关的知识,希望对你有一定的参考价值。

参考技术A

文章从以下几个问题着手分析蓝牙5的速率:

蓝牙5定义的 LE 2M PHY以及蓝牙4.x协议 LE 1M PHY都称为未编码PHY,因为它们每位数据使用1个符号表示(与使用S=2或S=8的新LE编码PHY相比)。

我们需要明白各大芯片厂商数据手册宣传的速度(1 Mbps和新的2 Mbps)仅仅只是理论值(空中速率),并且在应用程序中吞吐量会被削减。原因有多种,我们将在下面一一介绍。

蓝牙5“2x速度”需要硬件支持,因此老的设备/芯片/模块将不支持蓝牙5 2M PHY(市面已经有手机支持蓝牙5 2M PHY)。要注意,为了实现更高吞吐量,需要两个BLE设备相互都支持LE 2M PHY。

此外,当使用更高速度的PHY时,实际上功耗可以做的更低(传输相同数量的数据,时间短功耗低)。这是因为减少了芯片工作时间而又没有增加发射功率。反过来这样做改善了与2.4 GHz频谱内的其他无线技术的共存(也是由于减少了无线电工作时间,减少2,4G带宽的占用)。

1 Mbps(LE 1M PHY),2 Mbps(LE 2M PHY),125 kbps和500 kbps(均使用LE编码PHY,S = 8和S = 2)的数据速率是无线电在空中的速率传输数据,但由于以下原因,应用程序吞吐量是达不到该理论值:

我们感兴趣的部分(真正定义应用程序数据的部分)是ATT Payload。 从图中可以看出,蓝牙低功耗中的每一层都使用了许多额外开销字节。

首先了解下蓝牙5中使用新LE 2M PHY的局限性:

LE 2M PHY上可以发生从端广播模式和主端扫描模式,然后使用LE 2M PHY在第二广告信道上进行连接。

蓝牙5中基本上有三种PHY:原始的1 Mbps PHY,新的2 Mbps和编码的PHY(S = 2或S = 8)。所使用的PHY将直接影响您可以实现的最大数据吞吐量,因为它确定了通过无线方式发送数据包的实际原始数据速率。

连接间隔有效地确定在一个连接事件期间可以发送多少数据包。值越高,在一个连接事件中可以发送的数据包越多(某些设备达到某个限制)。

每个连接事件的数据包数量取决于设备和BLE堆栈,因此它受到限制,并且在特定设备上的设备和堆栈版本之间有所不同。此值还取决于设备的操作,因此无线电可能必须处理其他事件,并且每个连接事件发送的数据包数量可能达不到堆栈允许的最大值。例如,iosandroid之间的数量不同,也会根据设备上运行的操作系统版本而有所不同。

此功能允许数据包大小保持更大的有效负载(最多251个字节,而禁用时为27个字节)。此功能是在蓝牙规范4.2版中引入的。

ATT MTU确定发送器和接收器可以处理的最大数据量以及它们可以保存在缓冲器中的数据量。
MTU值影响开销数据量(特别是3个字节的ATT头)。允许的最小ATT MTU是27个字节。这允许最多20个字节的ATT有效载荷(3个字节用于ATT报头,4个字节用于L2CAP报头)。

对于MTU值有多高,每个规范没有限制,但使用中的特定堆栈可能有其自身的局限性。例如,如果启用DLE,则最多可以传输251 - 4 = 247个字节(扣除L2CAP标头大小后)。在考虑ATT报头(3个字节)之后,我们留下了244个字节用于实际的ATT有效载荷数据。如果MTU至少为247字节,则MTU将适合一个单独的数据包。如果MTU大于247字节,则MTU将跨越多个分组,导致吞吐量下降(由于分组开销和分组之间的定时)。

有效MTU由客户端和服务器支持的ATT MTU的最小值确定。例如,如果客户端支持100字节的ATT MTU并且服务器响应它支持150字节的ATT MTU,则客户端将决定用于从其上进行连接的ATT MTU是100字节。

如果需要高吞吐量,那么我们可以使用Write without response或Notifications将数据从客户端传输到服务器以及从服务器传输到客户端。这些操作不需要其他设备确认收到数据并在下一个数据块发送之前做出响应。

如果接收数据的设备没有要发回的数据,则仍需要按照蓝牙规范发送空数据包。

正如我们在数据包格式图中看到的那样,数据包包含一些不计入应用程序数据(ATT数据)的开销数据。基本上,这些字节将消耗部分传输数据速率,而不考虑作为应用程序数据的一部分发送的任何字节。

正如我们之前提到的,有如下些因数会影响数据吞吐量:

蓝牙版本和PHY确定原始数据传输速率。例如,如果我们使用蓝牙版本4.2和LE 1M PHY,则传输速率为1 Mbps。另一方面,如果我们使用蓝牙5 S = 8的 LE编码PHY,则数据速率降至125 kbps。

DLE,ATT MTU,连接间隔,每个连接间隔的最大数据包数,操作和IFS都是用于实际数据传输时间。

数据包格式在传输的数据量是实际应用程序数据方面起着重要作用。 LE 1M PHY和LE 2M PHY都具有类似的数据包格式。 LE编码PHY具有明显不同的数据包格式,因此我们将分别查看这两种情况:LE 1M PHY和LE 2M PHY计算。

为简单起见,我们做 假设 如下:

步骤:

空包传输时间可以如下计算:

基于此,传输 空1M PHY数据包 的时间将是:

数据包将包含数据包格式图中列出的所有字段,但MIC字段除外(加密禁用)。

如果我们启用了DLE并且ATT MTU等于一个数据包中允许的最大字节数:247个字节,那么我们可以将数据包大小计算为:

2M PHY 的情况下,它将是:

启用DLE并且ATT MTU设置为小于247 时,会产生更多开销(因为现在大于ATT MTU的数据被分成更多数据包)。例如,假设我们将ATT MTU设置为158,那么为了传输244个字节的应用程序数据,我们需要两个数据包而不是一个,导致吞吐量因字节开销增加而增加而增加数据包之间的IFS。

在另一种情况下,我们可以 禁用DLE(有效负载大小最多27个字节)和ATT MTU大于27个字节 。这也将导致需要为相同数量的数据发送更多数据包,从而导致吞吐量下降。

注意:

前一篇文章讲过,这种计算并不总是纯粹的数学计算,需要考虑使用的堆栈和设备的限制。在蓝牙芯片供应商的SDK中,通常在其文档中会列出最大值。 iOS和Android的最大值随操作系统版本而变化,所以要弄清楚并不容易。

一旦计算出最大值,就可以计算出适合所选连接间隔的最大理论数据包数。例如,如果我们的连接间隔为7.5毫秒(规范允许的最低值),则对于上面的示例(使用1M PHY,启用DLE):

每个连接间隔的最大数据包数= [7.5 * 1,000微秒/ 2,468微秒] = 3个数据包
通常,这个数字是不现实的,因为在连续的连接事件上发送的数据包之间存在时间延迟。因此,对于我们的示例,我们将使用2个数据包而不是3个数据包。

一旦我们计算出 每个连接间隔可以传输的最大数据包数 ,我们就可以计算出 数据吞吐量

大家会认为,连接间隔越小,速率肯定更高,实际并不是这样的。

路由器,蓝牙,手机wifi等2.4G的设备干扰,测试设备主从之间的距离,设备之间存在障碍等因数都会影响测试结果。
上面列出的测试值和理论值,可能实际环境中的测量数据吞吐量不一致。
干扰和传输/接收错误会影响数据吞吐量(重试,数据丢失和连接事件关闭会导致吞吐量降低)。
但本文详细分析了所有和速率相关的因素,在实际使用中,大家可以自由DIY。

https://mp.weixin.qq.com/s/12YaDn4sF5f3xTBYA9e2fA

Android 低功耗蓝牙(Ble) 开发总结

参考技术A Android 从 4.3(API Level 18) 开始支持低功耗蓝牙,但是只支持作为中心设备(Central)模式,这就意味着 Android 设备只能主动扫描和链接其他外围设备(Peripheral)。从 Android 5.0(API Level 21) 开始两种模式都支持。

低功耗蓝牙开发算是较偏技术,实际开发中坑是比较多的,网上有很多文章介绍使用和经验总结,但是有些问题答案不好找,甚至有些误导人,比如 :获取已经连接的蓝牙,有的是通过反射,一大堆判断,然而并不是对所有手机有用,关于Ble传输速率问题的解决,都是默认Android每次只能发送20个字节,然而也并不是,,,下面进入正文。

这里用的是 Android5.0 新增的扫描API,

这里说一下,如果做蓝牙设备管理页面,可能区分是否是已连接的设备,网上又通过反射或其他挺麻烦的操作,也不见得获取到,官方Api 就有提供

与外围设备交互经常每次发的数据大于 mtu的,需要做分包处理,接收数据也要判断数据的完整性最后才返回原数据做处理,所以一般交互最少包含包长度,和包校验码和原数据。当然也可以加包头,指令还有其他完整性校验。下面分享几个公用方法:

我自己封装的一个BleUtil ,因为涉及跟公司业务关联性太强(主要是传输包的协议不同)就先不开源出来了,如果这边文章对大家有帮助反馈不错,我会考虑上传个demo到github供大家使用,
在这先给大家推荐一个不错 Demo ,里面除了没有分包,协议,和传输速率。基本的功能都有,而且调试数据到打印到界面上了。最主要是它可以用两个个手机一个当中心设备一个当外围设备调试。

首先传输速率优化有两个方向,1 外围设备传输到Android 。2 Android传输到外围设备。
我在开发中首先先使用上面那位仁兄的demo调试,两个Android 设备调试不延时,上一个成功马上下一个,最多一秒发11个20字节的包。

后来和我们的蓝牙设备调试时发现发送特别快,但是数据不完整,他蓝牙模块接收成功了,但是透传数据到芯片处理时发现不完整,我们的硬件小伙伴说因为 波特率 限制(差不多每10字节透传要耗时1ms)和蓝牙模块的buff (打印时是最多100byte,100打印的)限制,就算蓝牙模块每包都告诉你接收成功,也是没透传完就又接收了。后来通过调试每次发20K数据,最后是 Android 发是 20字节/130ms 稳定。给Android 发是 20字节/ 8ms 。 (天杀的20字节,网上都是说20字节最多了)

后来看了国外一家物联网公司总结的 Ble 吞吐量的文章(上面有连接),知道Android 每个延时是可以连续接收6个包的。就改为 120字节/ 16ms (为啥是16ms,不是每次间隔要6个包吗,怎么像间隔两次,这时因为波特率影响,多了5个包100字节,差不多 我们的单片机透传到蓝牙模块要多耗时不到10ms )
而Android 发数据可以申请 我们设备的mtu 来得到最多每次能发多少字节。延时还是130ms,即:241字节/ 130ms 提高12倍,这个速度还可以。

根据蓝牙BLE协议, 物理层physical layer的传输速率是1Mbps,相当于每秒125K字节。事实上,其只是基准传输速率,协议规定BLE不能连续不断地传输数据包,否则就不能称为低功耗蓝牙了。连续传输自然会带来高功耗。所以,蓝牙的最高传输速率并不由物理层的工作频率决定的。

在实际的操作过程中,如果主机连线不断地发送数据包,要么丢包严重要么连接出现异常而断开。

在BLE里面,传输速度受其连接参数所影响。连接参数定义如下:

1)连接间隔。蓝牙基带是跳频工作的,主机和从机会商定多长时间进行跳频连接,连接上才能进行数据传输。这个连接和广播状态和连接状态的连接不是一样的意思。主机在从机广播时进行连接是应用层的主动软件行为。而跳频过程中的连接是蓝牙基带协议的规定,完全由硬件控制,对应用层透明。明显,如果这个连接间隔时间越短,那么传输的速度就增大。连接上传完数据后,蓝牙基带即进入休眠状态,保证低功耗。其是1.25毫秒一个单位。

2)连接延迟。其是为了低功耗考虑,允许从机在跳频过程中不理会主机的跳频指令,继续睡眠一段时间。而主机不能因为从机睡眠而认为其断开连接了。其是1.25毫秒一个单位。明显,这个数值越小,传输速度也高。

蓝牙BLE协议规定连接参数最小是5,即7.25毫秒;而Android手机规定连接参数最小是8,即10毫秒。iOS规定是16,即20毫秒。

连接参数完全由主机决定,但从机可以发出更新参数申请,主机可以接受也可以拒绝。android手机一部接受,而ios比较严格,拒绝的概率比较高。

参考:
在iOS和Android上最大化BLE吞吐量
最大化BLE吞吐量第2部分:使用更大的ATT MTU

以上是关于BLE入门 20 蓝牙5速率分析的主要内容,如果未能解决你的问题,请参考以下文章

BLE低功耗蓝牙开发相关概念问题记录

nRF52832 改变ATT_MTU提高蓝牙数据发送速率(nRF5_SDK_14.2.0)

如何提高蓝牙BLE的传输速率和稳定性

如何提高蓝牙BLE的传输速率和稳定性

Android BLE设置MTU大小(2020-08-20)

蓝牙5是啥意思