uni-app 蓝牙4.0接收数据 setbiemtu回调成功 仍然只能接收20字节数据
uni-app 蓝牙4.0接收数据 setbiemtu回调成功 仍然只能接收20字节数据
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
Windows | 1909 | HBuilderX |
### 操作步骤:
蓝牙芯片XC620(ble4.0),连接由设备发送20字节以上数据,真机调试只能接受20字节数据
### 预期结果:
setblemtu设置后 服务端26字节数据可全部接收
### 实际结果:
前20字节数据被接受 后6字节数据丢失 无法触发特征值监听
### bug描述:
应用插件 微信小程序转UNIAPP
设备端(蓝牙4.0)发送26字节数据 uniapp运行至手机只能接受20字节 且特征值监听只能触发一次 已调用blesetmtu且success回调
测试蓝牙5.0 uniapp运行至手机 数据接收无误
更换软件NRFconnect (蓝牙4.0)不请求MTU 26字节log打印分两次接收 请求MTU后 可一次接收26字节
更多关于uni-app 蓝牙4.0接收数据 setbiemtu回调成功 仍然只能接收20字节数据的实战教程也可以访问 https://www.itying.com/category-93-b0.html
9 回复
真机运行
微信小程序log
蓝牙4.0是这种差异 所以有常识拼包 但是后六个字节无法触发特征值监听
NRFCONNECT测试 MTU23
监听是两次
MTU507 一次接收全部
都没有遇到这个问题嘛?实在不行就要搞Android了
题主,你那时有弄出来吗,同样的问题设置了也是只能最大26不知道为什么,如果不设置只能20
回复 木杉丶: 解决这个问题了吗?
回复 1***@qq.com: 官方给的就是不行的,直接去市场买了个原生插件用了,原生的可以 https://ext.dcloud.net.cn/plugin?id=4945
回复 1***@qq.com: 其实你要是用官方的也行,只是要分段发送,比如最大20就每次20字节20字节的发送,但是官方的这个东西又有个bug就是每次发送间隔太长了。要是字节数据多这分段发送就慢太多了,当然你要是不要求速率你可以直接用官方的也行,但是那个最大字节设置是没用的只能做分段发送。
这是一个典型的蓝牙4.0 MTU限制问题。虽然你调用了setBLEMTU
并收到success回调,但实际MTU协商可能并未真正生效。
问题分析:
- 蓝牙4.0默认MTU为23字节,扣除3字节ATT头后,有效载荷只有20字节
- 即使MTU协商成功,部分安卓设备对蓝牙4.0的MTU扩展支持不完善
- 蓝牙5.0由于原生支持更大MTU,所以工作正常
解决方案:
- 分片接收处理 在特征值变化的回调中,不要依赖单次完整数据,而是实现数据拼接:
let receivedData = new Uint8Array(0);
function onCharacteristicValueChange(res) {
const newData = new Uint8Array(res.value);
// 合并数据
const mergedData = new Uint8Array(receivedData.length + newData.length);
mergedData.set(receivedData);
mergedData.set(newData, receivedData.length);
receivedData = mergedData;
// 根据协议判断数据完整性
if (/* 数据完整判断条件 */) {
// 处理完整数据
processCompleteData(receivedData);
receivedData = new Uint8Array(0); // 清空缓存
}
}
- 优化MTU设置时机 在连接建立后立即设置MTU,并添加重试机制:
uni.setBLEMTU({
deviceId: deviceId,
mtu: 128, // 尝试设置较大值
success: () => {
console.log('MTU设置成功');
// 延迟等待MTU生效
setTimeout(() => {
// 开始监听特征值
}, 200);
},
fail: () => {
// 即使失败也不影响分片接收
}
});