微信小程序 蓝牙通讯

server/2024/10/15 14:26:05/

客户的需求如下:通过小程序>微信小程序控制蓝牙ble设备(电子面膜),通过不同指令控制面膜的亮度和时间。

01.首先看下客户的ble设备服务文档:(本部分需要有点蓝牙基础,在调试过程中可以用安卓软件nRF Connect软件来执行测试命令)
在这里插入图片描述
0xFFF1灯控命令
命令格式:

在这里插入图片描述
命令类型:

0x01 – 常规模式,命令数据第一个字节为模式(1-3表示模式1-3),第二个字节为开关状态(0为暂停,1为启动)。

0x02 – 个性模式,命令数据第一个数据为强度百分比(1-100),第二个字节是时间低位,第三个字节是时间高位(单位秒)。

FFF2 灯状态
4个字节,数据同灯控命令的(命令类型+命令数据)。

FFF3验证码算法
通道用户连接时加密验证,该通道具有read/write 两种属性。

以下是手机端连接上设备后的加密流程。

手机连接SKLight(记录MAC地址) => 使能SKLight FFF2通道完成 => 读取(read) FFF3 新生成的4个字节的随机数 => 随机数结合设备的MAC地址计算出验证码=> FFF3 将验证码写给 SKLight (建议发3次) 读取验证结果(建议500-1000ms后读取,这时只有0x01一个字节正确,0x00则为失败)=>完成(失败请APP断开连接)

计算验证码的 C 函数:

// mac 为设备MAC地址 , rand为读到的随机数// auth_data 为计算得到的验证码,2个字节void getAuthenticationData(uint8_t *mac, uint8_t *rand,uint8_t *auth_data){auth_data [0] = mac[0]^ mac [1]^mac[2]^rand[0]^rand[1];auth_data [1] = mac[3]^mac[4]^mac[5]^rand[2]^rand[3];}

FFF4 电池状态
6个字节,字节1为电池电压高8位,字节2为电池电压低8位;字节3为电池电流高8位,字节4为电池电流低8位;字节5为电池电量(1-5),1表示低电量,5表示满电量;字节6为工作计时,为0时表示负载开路。

FFF8修改密码
验证成功后,可以通过该通道进行修改密码:

密码应为字符格式。

数据格式:共12字节:
在这里插入图片描述
修改密码应该在 500~1000ms 以后读取该通道,读到0x01 说明密码修改成功,否则失败。

FFF9修改设备名称
验证成功后,可以通过该通道进行修改设备广播名称:

数据格式:1~20字节:
修改密码应该在 500~1000ms 以后读取该通道,读到0x01 说明名称修改成功,否则失败。

名称修改完成后于断开连接时生效广播。

02.现在开始进行开发小程序端:

0201.蓝牙适配器开启

wx.openBluetoothAdapter({success: function (res) {//开启成功,继续搜索操作},fail:function(){//开启失败,后台监听状态处理,注意:在安卓系统中手动开启蓝牙可以监听,苹果在设置中开启监听不到,必须使用快捷图标开启(算是小程序蓝牙之坑)wx.onBluetoothAdapterStateChange(function (res) {if (res.available) {//后台监听到蓝牙适配器的状态变化,并且可用.}})       }
})

0202.搜索设备

//单纯的去搜索设备,并不会返回搜索列表
wx.startBluetoothDevicesDiscovery({success: function (res) {//已经执行搜索,查看搜索到的设备列表wx.getBluetoothDevices({success: function (res) {//打印获取到的设备列表,此处可以获取到设备的广播消息//设备的deviceId字段要非常注意,安卓返回的硬件mac地址,苹果返回的是uuid//当然无论返回什么都不影响你使用小程序蓝牙api//但是如果你的服务uuid需要你提供硬件mac地址交互的话需要做兼容处理//例如你可以要求蓝牙方在广播数据中保存硬件mac地址.(第2坑)console.log(res)}})    }
})

0203.连接ble设备

wx.createBLEConnection({//这里的deviceId就是上一步获取的设备列表的deviceId属性,不用关心这个字段的值,不关心是安卓还是苹果deviceId: deviceId,success: function (res) {console.log(res)}
})

0204.获得验证码

//上面的文档指示我通过FFF3服务uuid读取1个4位数字的验证码
//然后结合设备硬件mac地址通过C算法生成验证码发送给设备//002.读取后我拿来计算
wx.onBLECharacteristicValueChange(function (characteristic) {var macstring = deviceId;//设备mac地址,我处理过.不能直接用搜索列表的deviceIdvar randstring = ab2hex(characteristic.value);//设备给我的4位数字var verifycode = getAuthenticationData(macstring, randstring);//需要将C语言的算法转javascript})
//001.我来读取4位数字
wx.readBLECharacteristicValue({deviceId: deviceId,serviceId: '0000FFF0-0000-1000-8000-00805F9B34FB',characteristicId: '0000FFF3-0000-1000-8000-00805F9B34FB',success: function (res) {}
})//003.C语法转换的javascript
function getAuthenticationData(macstring, randstring) {var auth_data = new Array();//Macvar Tempmac = macstring.split(':');for (var i = 0; i < Tempmac.length; i++) {Tempmac[i] = '0x' + Tempmac[i];}var mac = new Uint8Array(Tempmac);//Mac-End//Randvar Temprand = new Array();var temprandj = 0;for (var i = 0; i < randstring.length; i++) {Temprand[temprandj] = '0x' + randstring.slice(i, i + 2);i++;temprandj++;}var rand = new Uint8Array(Temprand);//Rand-Endauth_data[0] = mac[0] ^ mac[1] ^ mac[2] ^ rand[0] ^ rand[1];auth_data[1] = mac[3] ^ mac[4] ^ mac[5] ^ rand[2] ^ rand[3];auth_data[0] = auth_data[0].toString(16);auth_data[1] = auth_data[1].toString(16);return auth_data;
}

0205.发送验证码

  sendverify(verifycode);//发送验证码。文档建议发送3次然后再读取值,如果值是1那么验证通过,其他的uuid指令也通过验证sendverify: function (verifycode) {var self = this;var deviceId =app.globalData.deviceId;for (var i = 0; i < 3; i++) {var hex =verifycode[0] + verifycode[1];var typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {return parseInt(h, 16)}))//console.log('本次执行命令:' + hex);var buffer = typedArray.bufferwx.writeBLECharacteristicValue({deviceId: deviceId,serviceId: '0000FFF0-0000-1000-8000-00805F9B34FB',characteristicId: '0000FFF3-0000-1000-8000-00805F9B34FB',value: buffer,success: function (res) {//console.log('writeBLECharacteristicValue success', res.errMsg)}})}//文档建议1000MS后读取验证码setTimeout(function () {wx.onBLECharacteristicValueChange(function (characteristic) {var rescode = parseInt(ab2hex(characteristic.value),10);if (rescode ==1) {//console.log('通过验证');wx.notifyBLECharacteristicValueChange({state: true, deviceId: deviceId,serviceId: '0000FFF0-0000-1000-8000-00805F9B34FB',characteristicId: '0000FFF4-0000-1000-8000-00805F9B34FB',success: function (res) {//读取电量信息wx.onBLECharacteristicValueChange(function (res) {var charge = ab2hex(res.value);console.log('原始数据:'+charge);app.globalData.bettery=parseInt('0x' + charge[8] + charge[9], 16);app.globalData.blecurrent = parseInt('' + charge[4] + charge[5] + charge[6] + charge[7]+'', 16)var dianya = parseInt('' + charge[0] + charge[1] + charge[2] + charge[3] + '', 16)console.log('电压:' + dianya);console.log('电量:' + app.globalData.bettery);console.log('电流:' + app.globalData.blecurrent);                  })//读取电量信息}})   return;                  }else {//验证码验证失败self.setData({ishow:0,showstatus: { text: 'Err,请尝试重新连接!', status: 1 }}); wx.closeBLEConnection({deviceId: deviceId})                            }})wx.readBLECharacteristicValue({deviceId: deviceId,serviceId: '0000FFF0-0000-1000-8000-00805F9B34FB',characteristicId: '0000FFF3-0000-1000-8000-00805F9B34FB',success: function (res) {}})}, 1000)},

0206.灯控测试,常规模式3启动

//指令构造要注意高位和低位的处理
var hex = 'fa010301000c22'var typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {
return parseInt(h, 16)
}))
var buffer = typedArray.buffer
//指令构造
wx.writeBLECharacteristicValue({
deviceId: deviceId,
serviceId: '0000FFF0-0000-1000-8000-00805F9B34FB',
characteristicId: '0000FFF1-0000-1000-8000-00805F9B34FB',
value: buffer,
success: function (res) {
//console.log('writeBLECharacteristicValue success', res.errMsg)
}
})

http://www.ppmy.cn/server/124873.html

相关文章

Git 工作区、暂存区和版本库

Git 工作区、暂存区和版本库 Git 是一个强大的版本控制系统&#xff0c;它帮助开发者管理代码历史&#xff0c;协作开发&#xff0c;以及跟踪和合并更改。为了更好地理解 Git 的工作流程&#xff0c;我们需要了解 Git 中的三个核心概念&#xff1a;工作区&#xff08;Workspac…

俄罗斯市场合格评定准入认证要求

前言 国内厂家想要把自己的产品顺利出口到俄罗斯市场&#xff0c;就需要基本了解俄罗斯的市场合格评定准入要求。俄罗斯主要实行的认证有EAC(TR-CU/CU-TR)认证、GOST R认证、计量认证和医疗产品国家注册。下面就分别简单介绍一下这几个产品认证。 一、EAC(TR-CU/CU-TR)认证介绍…

开源链动 2+1 模式 S2B2C 商城小程序:激活 KOC,开启商业新征程

摘要&#xff1a;本文深入探讨了 KOC 在立体连接中的重要性&#xff0c;以及如何通过开源链动 21 模式 S2B2C 商城小程序发现和找到更多的 KOC。强调了历史积累强关系和快速强化强关系的方法&#xff0c;并阐述了该商城小程序在推动商业发展中的关键作用。 一、引言 在当今竞争…

如何给文件夹里面的文件批量添加前缀和编号(利用C#写的小工具)

运行结果 将上面的文件编号效果 下载过后启动这个程序即可&#xff08;这个程序灵感来源是上次给美术资源分类和编号的时候给我干吐了&#xff0c;所以写了这个工具&#xff09; 体验链接&#xff1a;laozhupeiqia/批处理 --- laozhupeiqia/批处理 (github.com) 如果对你有帮助…

通信工程学习:什么是MAI多址干扰

MAI:多址干扰 MAI多址干扰(Multiple Access Interference)是无线通信领域,特别是在码分多址(CDMA)系统中,一个关键的干扰现象。以下是对MAI多址干扰的详细解释: 一、定义 多址干扰是指在CDMA系统中,由于多个用户的信号在时域和频域上是混叠的,从而导…

彩虹易支付最新版源码及安装教程(修复BUG+新增加订单投诉功能)

该系统也没版本号&#xff0c;此版本目前是比较新的版本&#xff0c;增加了订单投诉功能&#xff0c;和一个好看的二次元模板。 此版本是全开源版&#xff0c;无一处加密文件,系统默认是安装后是打不开的&#xff0c; 本站特别修复了BUG文件&#xff0c;在PHP7.4环境下也没问…

VUE 开发——AJAX学习(一)

一、AJAX入门和axios使用 1.AJAX定义&#xff1a; 异步的javascript和XML&#xff0c;就是使用XMLHttp Request对象与服务器通信&#xff0c;浏览器和服务器进行数据交换的技术。 2.使用axios 引入axios.js&#xff1a;https://unpkg.com/axios/dist/axios.min.js使用axios函…

SNMP和Syslog有啥区别

在网络管理的世界中&#xff0c;SNMP&#xff08;简单网络管理协议&#xff09;和 Syslog&#xff08;系统日志&#xff09;是两种关键技术&#xff0c;它们分别在监控和管理网络设备方面发挥着重要作用。选择合适的工具对于确保网络的高效运行、优化性能和增强安全性至关重要。…