在BLE蓝牙中一次写入超过20字节数据包的方法和技巧

        android是一个坑,蓝牙是android的坑中坑,BLE是蓝牙的坑中坑,而20字节数据包的限制是BLE中最不合理的坑,只要开发的APP需要与BLE通信,就绕不开这个坑,因为20字节的数据包的确太小了。如何跳出这个坑几乎是每一个开发者都要面临的问题。无论是网上还是论坛里关于跳这个坑的博文很多,当我也成为一个跳坑者的时候看了很多这样的博文,但是,这些博文中真正有过跳坑经历的作者很少,有知识、有营养的贴子很少,都是抄来抄去。本作者不做这样的搬运工,写的文章都是亲历的跳坑过程,如果所介绍的方法和技巧对你无效,那只可能设备和环境的个性差别所致。

        我现在所用的开发工具是android studio 3.5.2,具体的配置如下图:

       在版本为android 5.1.1的真实手机上实现手机与ble蓝牙模块JDY 16的通信,在手机与蓝牙建立起联系后,需要蓝牙模块透传一条72字节的数据时,发现模块只能接收到前20字节,因此掉入了这个坑。实验时是用两条链接的UUID作为数据传送到蓝牙模块,发现模块收到的信息是这样的:

收到的信息刚好是20字节。据商家说,JDY 16模块传送的数据包不受20字节的限制,因此,我把分包传送作为备选方案,先试试不分包的方法。网上说修改mtu数据就能够实现大于20字节数据包的传送,于是照葫芦画瓢地写了requestMtu()方法,并在requestMtu()方法的返回值和回调中捕捉到了mtu数据改变成功的信息,这个图是requestMtu()方法的返回值为真时信息:

这个图是回调后的控制台显示的信息,从最后一行看,mtu已经改变为100字节了。在这里,有些情况我已经确认,在发出修改mtu值的请求后,requestMtu()方法会返回一个判断结果,回调也会有一个mtu修改的结果,它们有时会有矛盾,看下图:

我发出了一个把mtu值修改成512字节的请求,requestMtu()方法返回了真,就是说我已经获得了512字节的mtu,但再看图的最后一行,控制台显示的mtu只有244,这个现象说明了一个事实:这个蓝牙4.2模块的最大mtu只有244,回调中的mtu值是正确的mtu值,requestMtu()方法返回值只能作为参考,并非你请求的mtu值就是你最后得到的mtu值,这个需要注意,如果发送的信息超过模块mtu的最大值,恐怕还是逃不出分包的命运哈。

        再回到实验中来,虽然上面的返馈信息都反映出我修改mtu的请求已经获得批准,应该可以发送超过20字节的数据包了,但是,app实际运行时蓝牙模块反而一个字节的信息都没有收到,看来连20字节的信息都没有发送出去,别说超过20字节啦。这坑真有点深了,看了很多文章,几乎没有文章说到这种情况,好像有一篇文章说到requestMtu()不工作,他怀疑是方法问题后也没有下文,似乎没有人解决过这个问题。我分析后认为,app和手机端的设置都已经成功了,问题应该出在蓝牙模块端,是不是哪个参数没有设置对?咨询了商家,回复说这款JDY 16模块默认就是无字节限制发送,无需进行设置。这样一来貌似走进了死胡同,找不到问题原因。不过,从一篇国外的文章中看到一个开发者说,请求修改了mtu后,需要updata mtu,只有updata后,新的mtu才能起作用,至于如何updata mtu,他只字未提。这个又给了一个提示,是不是有个updata mtu的方法?一番寻找后无果,就在我准备暂时放一放这个问题在坑里睡一觉的时候,突然灵机一动,难道是在回调成功后系统需要时间来重新布置新的mtu环境吗?于是,在收到回调信息后我加了一条sleep(200)语句:延时200毫秒等等,再运行app时奇迹出现了:

这个16进制显示的图,能看到有多少字节:

       这个免分包一次发送超20字节的方法终于成功了!这真的是踏破铁鞋无觅处,来得全不费功夫啊,成与不成之间就是一层纸。以下贴出关键的代码,供需要者参考。

调用requestMtu()方法后延时的代码:

 

这个是requestMtu()方法的代码:

这个是改变mtu请求发生后回调的处理代码:

这个是往JDY 16写的方法:

嗯,就是这么多了,有问题可以留言讨论。

 

 

 

<think>好的,我需要解决用户在HarmonyOS开发中测试蓝牙BLE模块命令写入速率的问题。首先,我得回顾一下BLE的基础知识,尤其是数据速率相关的部分。BLE的物理层速率通常是1Mbps,但实际的有效数据传输速率会受连接参数协议开销的影响,比如连接间隔、数据包长度等。 接下来,考虑用户的具体需求:测试写入命令的速率。根据引用中的信息,HarmonyOS提供了BLE开发相关的API,比如蓝牙状态处理、扫描流程等。可能需要使用这些API来发送数据并测量时间。 我应该先建议用户建立一个稳定的BLE连接。根据引用[3],需要检查蓝牙是否开启,并启动扫描连接流程。连接成功后,获取GattServiceCharacteristic,确保具有写入权限。 然后,考虑如何设计测试方法。用户需要连续发送数据包,并记录开始结束时间,计算总时间内的数据量。这里需要注意数据包的大小,因为BLE每个数据包的有效载荷最大为20字节(对于ATT MTU默认23字节的情况)。如果用户发送的数据超过这个长度,可能需要分包处理,这会增加时间。 同时,连接参数如连接间隔、从机延迟等会影响传输速率。用户可能需要调整这些参数以达到最佳性能,但需要确保设备兼容性。引用[4]提到BLE为低功耗设备提供了高效通信方案,所以测试时也要考虑功耗速率之间的平衡。 代码实现方面,用户需要初始化蓝牙、连接设备、获取特征值,然后循环发送数据。每次发送后记录时间戳,最后计算总速率。需要注意的是,异步写入的回调可能会影响实际速率,因此要确保每次写入完成后再发送下一个,避免队列堵塞。 可能的问题包括数据包分割、ACK机制带来的延迟,以及系统调度的影响。建议用户多次测试取平均值,并尝试不同数据长度连接参数来优化速率。 最后,生成相关问题,帮助用户进一步理解优化方法性能分析,比如如何调整连接参数或提高有效吞吐量。这些都需要结合HarmonyOS的APIBLE协议规范来进行。</think>在HarmonyOS中测试BLE模块的写入命令速率,可以通过以下步骤实现: ### 一、基础准备 1. **确认蓝牙状态** 先调用`bluetooth.getState()`检查蓝牙是否开启[^3],若未开启需调用`bluetooth.enable()` 2. **建立BLE连接** 通过`bluetooth.BLE.createGattClientDevice()`创建GATT客户端连接,获取特征值(Characteristic)时需确认其具备`WRITE`权限 ### 二、速率测试核心方法 ```typescript // 示例代码(HarmonyOS Next) let startTime: number = 0; let totalBytes: number = 0; const TEST_PACKET = new Uint8Array(20); // BLE单包最大有效载荷 async function testWriteSpeed() { const device = await bluetooth.BLE.createGattClientDevice(deviceId); const service = await device.getService(serviceUUID); const characteristic = await service.getCharacteristic(charUUID); startTime = new Date().getTime(); for (let i = 0; i < 100; i++) { // 测试100次写入 await characteristic.writeValue(TEST_PACKET); totalBytes += TEST_PACKET.length; } const duration = (new Date().getTime() - startTime) / 1000; console.log(`速率:${(totalBytes * 8 / duration / 1024).toFixed(2)} Kbps`); } ``` ### 三、关键影响因素 1. **连接参数优化** - 连接间隔(Connection Interval):建议设置为`15-30ms`(7.5ms单位) - 从机延迟(Slave Latency):可设置为`0`以禁用延迟 - 超时时间(Supervision Timeout):建议`4s`以上 2. **协议开销计算** 每个ATT包包含: - 3字节头(Opcode + Handle) - 20字节有效载荷 - 总传输量:$3+20=23$字节/包 - 实际有效速率:$\frac{20}{23} \times 理论速率$ ### 四、性能分析工具 1. **HDF性能分析模块** 使用`hdc shell hidumper -s 3601 -a -profiler`获取蓝牙协议栈性能数据 2. **DevEco Profiler** 通过`Bluetooth Trace`模块可视化分析: - 数据包间隔分布 - GATT操作耗时 - 协议栈缓冲状态
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值