一、前言
最近刚入职,boss让做一个微信小程序用蓝牙跟硬件进行数据交互。拿到测试的板子功能不是很完善,只能接收和发送一个字节,而且发送也是循环发送,也就是一直发送存储的那个字节数据。
现在假设的报文交互是:接受一条请求报文,发送一条相应报文。
当我在模拟控制机器开关机的时候时,当用户开启设备时,要发送一条set报文,控制机器开机,而同时也发送set报文后,要发送一条get报文以查询机器当前绑定的模块。
二、问题
在刚开始的时候,我的请求流程是这样的:
其中发送的报文数据都是模拟的
console.log("发送开机报文")
//发送开机报文
that.StrGroup("fe5005")
console.log("已经设置设备开机")
//获取已经绑定的模块
that.getBindingModules()
其中
//获取绑定模块函数
getBindingModules:function(res){
bindingModules ={}
console.log("当前已经绑定的模块(检测是否为空)= "+bindingModules)
console.log("获取当前已绑定的模块")
//改变当前操作类型,读取已经绑定的模块
action_type = OptionEnum.ReadBindingModules
this.StrGroup("ffe5005")
bindingModules = [1,2];
console.log("当前绑定的模块有"+bindingModules)
//发送报文,获取绑定传感器
//获得传感器已绑定的
},
我们可以看到,成功发送了两次报文,一次是set报文,一次是get报文,但是onBLECharacteristicValueChange() 只检测到了后面一个返回的数据(板子是发送什么报文就返回什么报文),这就不对了,正确的顺序应该是
成功发送报文(set)4=》检测到特征值变化4=》成功发送报文(get)50=》检测到特征值变化50
然而程序却遗漏了第二个步骤(第一次检测特征值变化)
这是我百思不得其解,明明板子是接受什么发送什么,为什么在连续接收到小程序发送的数据后却只是发送后一个?是没有接收到第一个报文还是小程序连续写的速度太快而导致机器在接收到第一个报文后还没来得及发送就立马接收到第二个报文,所以只发送第二个报文呢?
三、处理过程
1、检查是否接收到了报文
我将两个发送函数分别执行
console.log("发送开机报文")
//发送开机报文
that.StrGroup("fe5005")
console.log("已经设置设备开机")
//获取已经绑定的模块
//that.getBindingModules()
结果:单独执行两个函数都可以顺利收发报文,因此,排除该问题
2、是否是连续发送太快,导致异常?
刚开始我是设置延迟时间,当执行完第一个发送函数后,停等1s后在继续执行第二个函数,然而还是不行,依然只能检测到特征值变化。
后来我想起了这个流程跟报文分组转发相类似,因为小程序与BLE(低功耗蓝牙)一次只能传递20个字节的数据,报文如果大于20字节,那么就必须分组发送。
在经过一系列查询后,终于
function writeTest(msg){
let buffer = hexStringToArrayBuffer(msg);
let pos = 0;
let bytes = buffer.byteLength;
console.log("bytes", bytes)
while (bytes > 0) {
let tmpBuffer;
if (bytes > 20) {
return delay(0.25).then(() => {
tmpBuffer = buffer.slice(pos, pos + 20);
pos += 20;
bytes -= 20;
console.log("tmpBuffer", tmpBuffer)
wx.writeBLECharacteristicValue({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: writeId,
value: tmpBuffer,
success(res) {
console.log('第一次发送', res)
}
})
})
} else {
return delay(0.25).then(() => {
tmpBuffer = buffer.slice(pos, pos + bytes);
pos += bytes;
bytes -= bytes;
wx.writeBLECharacteristicValue({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: writeId,
value: tmpBuffer,
success(res) {
console.log('第二次发送', res)
},
fail: function (res) {
console.log('发送失败', res)
}
})
})
}
}
}
function delay(ms, res) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(res);
}, ms);
});
}
这边有个关键点就是delay(0.25),一定要间隔相应的时间再发送,不然即使分包也接收不到正确的数据,回调数据可在onBLECharacteristicValueChange中查看。
原文连接