前端使用低功耗蓝牙开发的坑1(分包操作之分包接收)

2021-01-21

3158 0 0

最近用uniapp开发微信小程序的一个项目中用到了低功耗蓝牙,但是其中收包 ,发包的时候不能超过20字节,所以就需要我们来进行分包操作了

接收蓝牙设备传过来的数据,并进行分包接收处理

说明: 我项目中的数据结构中05是帧头, FE是帧尾,所以需要判断接收到的这个数据是否是05开头,FE结尾, 我是将接收到的数据保存到了缓存中 image.png

思路: 根据协议中的帧头帧尾和数据长度来进行处理 符合条件的就可以接收处理 不符合条件的就丢掉

    1. 如果开头结尾和帧头帧尾一致并且长度一致就保留(说明长度完整)
    1. 如果帧头对 帧尾不对 则为前边部分
    1. 如果帧头不对 帧尾不对 则为中间部分
    1. 如果帧头不对 帧尾对 则为最后一部分

根据以上四个步骤基本可以得到一串正常的数据,但是此时还有一个很重要的步骤 需要根据接收到的数据的长度判断一下实际的长度,因为很有可能接收到的帧头帧尾之间还有一个帧尾,此时需要我们把进行截取操作得到我们真正想要的数据

以下是我项目中处理分包接收数据的全部代码:

1// 11 监听notify功能 2var packData = '' // 分包操作 3var first = '' // 开始部分 4var center = '' // 中间拼接部分 5var last = '' // 结尾部分 6var len = 0 // 包的长度 7// var flag = true // flag判断是否进行了分包操作 如果分包需要清空开始部分 中间部分 结尾部分 8export function watchNotify(isHeart) { 9 // ArrayBuffer转16进度字符串示例 10 function ab2hex(buffer) { 11 const hexArr = Array.prototype.map.call( 12 new Uint8Array(buffer), 13 function (bit) { 14 return ('00' + bit.toString(16)).slice(-2) 15 } 16 ) 17 return hexArr.join('') 18 } 19 20 return new Promise((resolve, reject) => { 21 uni.onBLECharacteristicValueChange(function (res) { 22 console.log(res) 23 // 监听帧头帧尾 24 var resCode1 = ab2hex(res.value) 25 var resCode = resCode1.toUpperCase() 26 console.log(resCode, '收到的') 27 28 // 1. 如果开头结尾和帧头帧尾一致并且长度一致就保留(说明长度完整) 29 if (resCode.substring(resCode.length - 2, resCode.length) == 'FE' && resCode.substring(0, 2) == '05') { 30 let lenTo10 = parseInt(resCode.substring(2,resCode.length - 2).length)/2 31 // 1.1找出内容16进制 32 let lengthTo16 = lenTo10.toString(16) + '' 33 // 2.1 对16进制进行大小写转换并且补零操作 34 lengthTo16 = lengthTo16.length == 1 ? '0' + lengthTo16.toUpperCase() : lengthTo16.toUpperCase() 35 let length1 = resCode.substring(2,4) 36 console.log(lengthTo16, length1) 37 if (lengthTo16 == length1) { 38 if (resCode.substring(8,12) == 'F020') { 39 uni.setStorageSync('RESCODE', resCode) 40 console.log(resCode, 'F020') 41 } else { 42 uni.setStorageSync('RESPARAMS', resCode) 43 } 44 } 45 46 } else if (resCode.substring(resCode.length - 2, resCode.length) != 'FE' && resCode.substring(0, 2) == '05') { 47 // 2. 如果帧头对 帧尾不对 则为前边部分 48 first = resCode 49 50 console.log(first, '这个是开头部分first') 51 } else if (resCode.substring(resCode.length - 2, resCode.length) != 'FE' && resCode.substring(0, 2) != '05') { 52 // 3. 如果帧头不对 帧尾不对 则为中间部分 53 center = center + resCode 54 console.log(center, '中间部分center') 55 } else if (resCode.substring(resCode.length - 2, resCode.length) == 'FE' && resCode.substring(0, 2) != '05') { 56 // 4. 如果帧头不对 帧尾对 则为最后一部分 57 last = resCode 58 console.log(last, '最后一部分last') 59 60 // 得到实际内容 61 62 var content = first + center + last 63 console.log(content, '实际的内容') 64 // 4.1找出内容16进制 65 var resLen = (content.length - 4) / 2 // 减去4是剪掉帧头和帧尾,除以2是为了得到字节 66 console.log(resLen, '实际的长度10进制') 67 var lenTo16 = resLen.toString(16) + '' 68 // 4.2 对16进制进行大小写转换并且补零操作 69 lenTo16 = lenTo16.length == 1 ? '0' + lenTo16.toUpperCase() : lenTo16.toUpperCase() 70 console.log(lenTo16, 'lenTo16') 71 // 得到包的长度 72 len = content.substring(2,4) 73 console.log(len, 'len') 74 // 判断是否得到长度和实际长度相等 75 if (lenTo16 == len) { 76 if (content.substring(8,12) == 'F020') { 77 uni.setStorageSync('RESCODE', content) 78 console.log(content, 'F020') 79 } else { 80 uni.setStorageSync('RESPARAMS', content) 81 console.log(content, '!F020') 82 } 83 } else { 84 // 如果不相等, 找一下字符串中间有没有FE 然后再进行长度 帧头帧尾判断 85 86 // 1.截取帧尾的FE 求出帧尾之前是否有FE 87 let substrFE = content.substring(0, content.length - 2) 88 console.log(substrFE, 'substrFE') 89 // 2.判断是否还有FE 90 // 2.1 转换为两个字符一起的数组 91 let hasFEArr = strToArr(substrFE, 2) 92 // 2.2 找出是否有FE 并确定位置 93 let hasFE = hasFEArr.indexOf('FE') 94 95 console.log(hasFEArr, 'hasFEArr') 96 console.log(hasFE, 'hasFE') 97 // 如果有FE,截取到FE之处 判断帧头帧尾长度 98 if (hasFE != -1) { 99 // 将最后的数据保存到这个数组里面 100 let lastConArr = [] 101 // 得到05-FE的内容 102 hasFEArr.forEach((item, index) => { 103 if (index <= hasFE) { 104 lastConArr.push(item) 105 } 106 }) 107 console.log(lastConArr, 'lastConArr') 108 // 判断是否是05开头FE结尾 109 console.log(lastConArr[lastConArr.length - 1], 'lastConArr[lastConArr.length - 1]') 110 console.log(lastConArr[0], 'lastConArr[0]') 111 if (lastConArr[0] == '05' && lastConArr[lastConArr.length - 1] == 'FE') { 112 // 判断得到的长度与实际长度 113 let getLen = lastConArr[1] 114 console.log(getLen, 'getLen') 115 // 实际长度 并且转换为十六进制字符串 116 let resLen = (lastConArr.length - 2).toString(16) + '' 117 console.log(resLen, 'resLen1') 118 // 实际长度补零操作 119 resLen = resLen.length == 1 ? '0' + resLen : resLen, 120 console.log(resLen, 'resLen2') 121 // 判断得到的长度与实际长度相等之后才是实际的结果 122 if (getLen == resLen.toUpperCase()) { 123 // 数组转换为字符串 124 let lastStr = lastConArr.join('') 125 console.log(lastStr, 'lastStr') 126 if (lastStr.substring(8,12) == 'F020') { 127 uni.setStorageSync('RESCODE', lastStr) 128 console.log(lastStr, 'F020') 129 } else { 130 uni.setStorageSync('RESPARAMS', lastStr) 131 console.log('!f') 132 } 133 } 134 } 135 } 136 } 137 // 清空内容和收到的数据 138 first = '' // 开始部分 139 center = '' // 中间拼接部分 140 last = '' // 结尾部分 141 len = 0 // 包的长度 142 143 } 144 }) 145 }) 146 147}

源码地址

https://github.com/menglin1997/BLEConn

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )