前台使用低功耗蓝牙开发的坑(分包操作之分包发送)
最近用uniapp开发微信小程序的一个项目中用到了低功耗蓝牙,但是其中收包 ,发包的时候不能超过20字节,所以就需要我们来进行分包操作了
接收蓝牙设施穿过来的数据,并进行分包接收解决
说明: 我项目中的数据结构中05是帧头, FE是帧尾,所以需要判断接收到的这个数据能否是05开头,FE结尾, 我是将接收到的数据保存到了缓存中
image.png
思路: 根据协议中的帧头帧尾和数据长度来进行解决 符合条件的即可以接收解决 不符合条件的就丢掉
- 假如开头结尾和帧头帧尾一致并且长度一致就保留(说明长度完整)
- 假如帧头对 帧尾不对 则为前边部分
- 假如帧头不对 帧尾不对 则为中间部分
- 假如帧头不对 帧尾对 则为最后一部分
根据以上四个步骤基本可以得到一串正常的数据,但是此时还有一个
很重要的步骤
需要根据接收到的数据的长度判断一下实际的长度,由于很有可能接收到的帧头帧尾之间还有一个帧尾,此时需要我们把进行截取操作得到我们真正想要的数据
以下是我项目中解决分包接收数据的一律代码:
// 11 监听notify功能var packData = '' // 分包操作var first = '' // 开始部分var center = '' // 中间拼接部分var last = '' // 结尾部分var len = 0 // 包的长度// var flag = true // flag判断能否进行了分包操作 假如分包需要清空开始部分 中间部分 结尾部分export function watchNotify(isHeart) { // ArrayBuffer转16进度字符串示例 function ab2hex(buffer) { const hexArr = Array.prototype.map.call( new Uint8Array(buffer), function (bit) { return ('00' + bit.toString(16)).slice(-2) } ) return hexArr.join('') } return new Promise((resolve, reject) => { uni.onBLECharacteristicValueChange(function (res) { console.log(res) // 监听帧头帧尾 var resCode1 = ab2hex(res.value) var resCode = resCode1.toUpperCase() console.log(resCode, '收到的') // 1. 假如开头结尾和帧头帧尾一致并且长度一致就保留(说明长度完整) if (resCode.substring(resCode.length - 2, resCode.length) == 'FE' && resCode.substring(0, 2) == '05') { let lenTo10 = parseInt(resCode.substring(2,resCode.length - 2).length)/2 // 1.1找出内容16进制 let lengthTo16 = lenTo10.toString(16) + '' // 2.1 对16进制进行大小写转换并且补零操作 lengthTo16 = lengthTo16.length == 1 ? '0' + lengthTo16.toUpperCase() : lengthTo16.toUpperCase() let length1 = resCode.substring(2,4) console.log(lengthTo16, length1) if (lengthTo16 == length1) { if (resCode.substring(8,12) == 'F020') { uni.setStorageSync('RESCODE', resCode) console.log(resCode, 'F020') } else { uni.setStorageSync('RESPARAMS', resCode) } } } else if (resCode.substring(resCode.length - 2, resCode.length) != 'FE' && resCode.substring(0, 2) == '05') { // 2. 假如帧头对 帧尾不对 则为前边部分 first = resCode console.log(first, '这个是开头部分first') } else if (resCode.substring(resCode.length - 2, resCode.length) != 'FE' && resCode.substring(0, 2) != '05') { // 3. 假如帧头不对 帧尾不对 则为中间部分 center = center + resCode console.log(center, '中间部分center') } else if (resCode.substring(resCode.length - 2, resCode.length) == 'FE' && resCode.substring(0, 2) != '05') { // 4. 假如帧头不对 帧尾对 则为最后一部分 last = resCode console.log(last, '最后一部分last') // 得到实际内容 var content = first + center + last console.log(content, '实际的内容') // 4.1找出内容16进制 var resLen = (content.length - 4) / 2 // 减去4是剪掉帧头和帧尾,除以2是为了得到字节 console.log(resLen, '实际的长度10进制') var lenTo16 = resLen.toString(16) + '' // 4.2 对16进制进行大小写转换并且补零操作 lenTo16 = lenTo16.length == 1 ? '0' + lenTo16.toUpperCase() : lenTo16.toUpperCase() console.log(lenTo16, 'lenTo16') // 得到包的长度 len = content.substring(2,4) console.log(len, 'len') // 判断能否得到长度和实际长度相等 if (lenTo16 == len) { if (content.substring(8,12) == 'F020') { uni.setStorageSync('RESCODE', content) console.log(content, 'F020') } else { uni.setStorageSync('RESPARAMS', content) console.log(content, '!F020') } } else { // 假如不相等, 找一下字符串中间有没有FE 而后再进行长度 帧头帧尾判断 // 1.截取帧尾的FE 求出帧尾之前能否有FE let substrFE = content.substring(0, content.length - 2) console.log(substrFE, 'substrFE') // 2.判断能否还有FE // 2.1 转换为两个字符一起的数组 let hasFEArr = strToArr(substrFE, 2) // 2.2 找出能否有FE 并确定位置 let hasFE = hasFEArr.indexOf('FE') console.log(hasFEArr, 'hasFEArr') console.log(hasFE, 'hasFE') // 假如有FE,截取到FE之处 判断帧头帧尾长度 if (hasFE != -1) { // 将最后的数据保存到这个数组里面 let lastConArr = [] // 得到05-FE的内容 hasFEArr.forEach((item, index) => { if (index <= hasFE) { lastConArr.push(item) } }) console.log(lastConArr, 'lastConArr') // 判断能否是05开头FE结尾 console.log(lastConArr[lastConArr.length - 1], 'lastConArr[lastConArr.length - 1]') console.log(lastConArr[0], 'lastConArr[0]') if (lastConArr[0] == '05' && lastConArr[lastConArr.length - 1] == 'FE') { // 判断得到的长度与实际长度 let getLen = lastConArr[1] console.log(getLen, 'getLen') // 实际长度 并且转换为十六进制字符串 let resLen = (lastConArr.length - 2).toString(16) + '' console.log(resLen, 'resLen1') // 实际长度补零操作 resLen = resLen.length == 1 ? '0' + resLen : resLen, console.log(resLen, 'resLen2') // 判断得到的长度与实际长度相等之后才是实际的结果 if (getLen == resLen.toUpperCase()) { // 数组转换为字符串 let lastStr = lastConArr.join('') console.log(lastStr, 'lastStr') if (lastStr.substring(8,12) == 'F020') { uni.setStorageSync('RESCODE', lastStr) console.log(lastStr, 'F020') } else { uni.setStorageSync('RESPARAMS', lastStr) console.log('!f') } } } } } // 清空内容和收到的数据 first = '' // 开始部分 center = '' // 中间拼接部分 last = '' // 结尾部分 len = 0 // 包的长度 } }) }) }说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 前台使用低功耗蓝牙开发的坑(分包操作之分包发送)
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 前台使用低功耗蓝牙开发的坑(分包操作之分包发送)