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

等级 674 0 0
标签: 蓝牙前端

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

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

说明: 我项目中的数据结构中05是帧头, FE是帧尾,所以需要判断接收到的这个数据是否是05开头,FE结尾, 我是将接收到的数据保存到了缓存中 前端使用低功耗蓝牙开发的坑1(分包操作之分包接收)

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

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

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

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

// 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 // 包的长度

            }
        })
    })

}

源码地址

https://github.com/menglin1997/BLEConn

收藏
评论区

相关推荐

【干货】Javascript千面之变幻莫测的this指向
相信很多前端人对“this”的指向是很懵逼的,因为this的指向总是变幻莫测,在不同的调用环境中,它的指向总是各不相同。 在面试中,this也是经常考的必考题之一,很多前端老鸟经常会在this这里掉坑。 接下来,看笔者来一层一层的揭开this指向的面纱。 1.事件调用环境中的this指向 <div class"b
Swift开发-OC与Swift混编以及纯Swift编码所遇到的问题(二)
上篇在介绍了Swift与OC混编开发所需要准备的一些必要条件 SwiftObjectiveC混编注意事项(https://www.jianshu.com/p/52ab6a316cbe),今天只说一下我在实际项目中所踩过的坑,希望你们以后绕过这些坑吧。 1、 使用cocopods管理Swift文件所遇到的问题: 我们在开发的过程中,各种优秀的框架
复盘node项目中遇到的13+常见问题和解决方案
笔者之前陆陆续续接手过几个nodejs项目, 也参与过几个有点意思的nodejs开源项目, 最近把其中遇到的一些问题和解决方案做一个梳理, 避免大家继续踩坑. 话不多说我们开始吧 1. window和mac下设置NODE_ENV变量的问题 我们都知道在前端项目中会根据不同的环境变量来处理不同的逻辑, 在nodejs中也一样, 我们需要设置本地开发环境, 测
前端使用低功耗蓝牙开发的坑1(分包操作之分包接收)
最近用uniapp开发微信小程序的一个项目中用到了低功耗蓝牙,但是其中收包 ,发包的时候不能超过20字节,所以就需要我们来进行分包操作了 接收蓝牙设备传过来的数据,并进行分包接收处理 说明: 我项目中的数据结构中05是帧头, FE是帧尾,所以需要判断接收到的这个数据是否是05开头,FE结尾, 我是将接收到的数据保存到了缓存中 image.png(h
Flask开发 经验技巧总结
Flask作为一个主流的Python Web框架之一,有比较广泛的应用,但是有经验的小伙伴可能知道,这里边其实也有很多坑,让你不得不防,在使用的过程中可以积累一些经验。 1.Flask中的Referer不是referer 做过爬虫的小伙伴都知道,referer是指页面的跳转,即从哪一个页面跳转到当前页,很多网站也通过该属性对爬虫采取了一定的限制。在Flas
iOS 支付宝支付开发(最新版)
1. 介绍 本文为以前做的项目总结,由于相关支付 SDK 迭代,原文已经不满足需求,故作如下更新,供大家参考,另外增加常见问题总结。 今天我们就主要介绍一下支付宝支付,其他支付介绍后面会尽快更新出来。 在做支付之前,在网上也查寻了资料,大多都说,支付接入坑太多,微信坑最多,银联文档太复杂。 其实如果接入的多的话,那些套路都可以绕着走。 网上的经验什么的
Flask开发 经验技巧总结
Flask作为一个主流的Python Web框架之一,有比较广泛的应用,但是有经验的小伙伴可能知道,这里边其实也有很多坑,让你不得不防,在使用的过程中可以积累一些经验。 1.Flask中的Referer不是referer做过爬虫的小伙伴都知道,referer是指页面的跳转,即从哪一个页面跳转到当前页,很多网站也通过该属性对爬虫采取了一定的限制。在Flas
小程序开发不得不爬的坑,我替你爬过了!
不得不说,目前这个项目做的真是够久,在开发过程中遇到了一些坑,解决了分享出来给大家。 在各方面综合考虑之下,鄙人抛弃了各大多端开发框架,使用了 原生 的小程序框架进行开发。前人掘坑、后人遭殃,祝各位早日成为大牛!!👻👻👻👻自定义动态Tabbar导航栏在默认的小程序开发中,定义tabbar,需要在app.json中配
推荐几个微信小程序开发小技巧
前段时间在下开发了个微信小程序,开发过程中总结了一些我觉得对我有用的小技巧,提炼出来,相当于一个总结复盘,也希望可以帮助到大家。如果对大家确实有帮助,别忘了点赞哦 🌟 ~1\. 开发中可能遇到的坑以及 Tips本来想写个小技巧的,结果我总结了一堆坑,没上手之前完全想象不到微信小程序的开发体验是如此之差、如此之烂,从微信
go语言坑之list删除所有元素
go提供了一个list包 类似python的list,可以存储任意类型的数据,并提供了相应的API,如下:type Element func (e Element) Next() Element func (e Element) Prev() Elementtype List func New() List func (l List)
前后端分离的情况下,vue保存cookie时碰到的坑! (axios.defaults.withCredentials = true;)
文章目录 一号坑问题描述当我们的项目是前后端分离的模式时,vue不会自动帮我们保存后端传来的cookie!解决方案我们需要在main中添加axios.defaults.withCredentials true 二号坑问题描述如果你之前处理过跨域方面的问题,应该会记得你曾经在后端请求头添加
Hadoop集群搭建避坑指南
环境 CentOS 6 hadoop2.7.2 jdk8u144linuxx64 新建虚拟机 三台主机分别命名为 master、slave01、slave02 第一个坑 为虚拟机新建用户的时候,三台用户都应该设置成一样的,不然后期会出问题,这里我将用户名统一设置为lixuan 踩坑之后补救措施 改下面4个地方的配置文件 将最后一行的旧用户名换成新用
这些常见的坑,90%的程序猿都踩过,来看看里面有没有你的脚印?
在学习python的过程中,相信大家都有踩过不少的坑,有些坑可能踩了不止一次,感觉就像是在坑与坑之间反复横跳。那么如何避免这些坑呢?看完这篇文章,你就知道了。我们来谈谈我们学习python的过程中,最常见的七大坑:1. 缩进,符号和空格不正确写代码时大家会使用缩进、对齐、空格等,这些是为了提高代码的可读性在python语言中,缩进是十分重要的比如在创建一个新
JAVA回调机制(CallBack)之小红是怎样买到房子的??
JAVA回调机制CallBack 序言最近学习java,接触到了回调机制(CallBack)。初识时感觉比较混乱,而且在网上搜索到的相关的讲解,要么一言带过,要么说的比较单纯的像是给CallBack做了一个定义。当然了,我在理解了回调之后,再去看网上的各种讲解,确实没什么问题。但是,对于初学的我来说,缺了一个循序渐进的过程。此处,将我对回调机制的个人理解,按
SpringCloud升级之路2020.0.x版-1.背景
本系列为之前系列的整理重启版,随着项目的发展以及项目中的使用,之前系列里面很多东西发生了变化,并且还有一些东西之前系列并没有提到,所以重启这个系列重新整理下,欢迎各位留言交流,谢谢!Spring Cloud 官方文档说了,它是一个完整的微服务体系,用户可以通过使用 Spring Cloud 快速搭建一个自己的微服务系统。那么 Spring Cloud 究竟是