微信小程序连接蓝牙并分包发送接收数据
初始化蓝牙初始化蓝牙设备搜索蓝牙设备连接蓝牙设备获取蓝牙设备所有service(支持读写的)向蓝牙发送数据断开蓝牙停止搜索蓝牙转16进制ArrayBuffer转16进度字符串示例总结初始化蓝牙
//初始化蓝牙适配器wx.openBluetoothAdapter({success: function (res) {//获取本机蓝牙适配器状态wx.getBluetoothAdapterState({success: function (res) {//蓝牙可用 console.log('蓝牙可用 ')},fail: function (res) {//蓝牙不可用console.log('蓝牙不可用')}})},fail: function (res) {console.log('请打开蓝牙和定位功能')}})
初始化蓝牙设备
//初始化蓝牙设备wx.openBluetoothAdapter({success: (res) => {console.log('初始化成功,接下来搜索蓝牙设备') },fail: (res) => {}})
搜索蓝牙设备
//搜索蓝牙设备wx.startBluetoothDevicesDiscovery({allowDuplicatesKey: true,success: async (res) => {console.log('startBluetoothDevicesDiscovery success', res)// 监听寻找到新设备的事件wx.onBluetoothDeviceFound((res) => {res.devices.forEach(device => {if (!device.name && !device.localName) {return}const foundDevices = this.data.devices//页面存储蓝牙列表的数组const idx = inArray(foundDevices, 'deviceId', device.deviceId)const data = {};if (idx === -1) {data[`devices[${foundDevices.length}]`] = device} else {data[`devices[${idx}]`] = device}this.setData(data)})})},})
连接蓝牙设备
//获取被点击连接蓝牙 页面设置的deviceId 用于连接蓝牙const deviceId = e.currentTarget.dataset.deviceIdwx.createBLEConnection({deviceId: deviceId,success: (res) => {this.setData({connected: true,name,//保存蓝牙设备名称deviceId,//保存蓝牙设备ID})// 如果有读写操作则下面进行 获取蓝牙设备所有service}})
获取蓝牙设备所有service(支持读写的)
//获取蓝牙设备所有servicevar deviceId=this.data.deviceIdwx.getBLEDeviceServices({deviceId:deviceId,//蓝牙设备id 连接成功时保存在data中的success: (res) => {for (let i = 0; i < res.services.length; i++) {var serviceId=res.services[i].uuidif (res.services[i].isPrimary) {//判断该服务是否为主服务//获取蓝牙设备某个服务中所有特征值wx.getBLEDeviceCharacteristics({deviceId:deviceId,serviceId:serviceId,success: (res2) => {for (let j = 0; j < res2.characteristics.length; j++) {let item = res2.characteristics[j]if (item.properties.notify) {//判断该特征值是否支持 notify 操作if (item.properties.read) {//读取低功耗蓝牙设备的特征值的二进制数据值。//注意:必须设备的特征值支持 read 才可以成功调用。wx.readBLECharacteristicValue({deviceId:deviceId,serviceId:serviceId,characteristicId: item.uuid,})}if (item.properties.write) {this.setData({//在这里this已经不能指向data了,可以在方法的最开始用this指向自定义变量在这里代替this使用canWrite: true,//是否可以写入w_deviceId = deviceId,w_serviceId = serviceId})if (_characteristicId == undefined) {this.setData({w_characteristicId = item.uuid})}}//监听设备 characteristicValueChange 事件if (item.properties.notify || item.properties.indicate) {//启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值。//注意:必须设备的特征值支持 notify 或者 indicate 才可以成功调用。//另外,必须先启用 notifyBLECharacteristicValueChange 才能监听到设备 characteristicValueChange 事件wx.notifyBLECharacteristicValueChange({deviceId,serviceId,characteristicId: item.uuid,state: true,success: function (e) {console.log('success: ' + JSON.stringify(e));// 操作之前先监听,保证第一时间获取数据},fail: function (e) {console.log('error: ' + JSON.stringify(e));}})}}}}})}}}})
向蓝牙发送数据
//向蓝牙发送数据var sendData = "12345f6ewaffew15f6ew4fewf4d2sa1554ew4a5fd5ef1d5s4few5few"//需要发送的数据let buffer = hexStringToArrayBuffer(sendData );//转16进制let pos = 0;let bytes = buffer.byteLength;var result = ''while (bytes > 0) {let tmpBuffer;if (bytes > 20) {tmpBuffer = buffer.slice(pos, pos + 20);pos += 20;bytes -= 20;wx.writeBLECharacteristicValue({deviceId: this.data.w_deviceId,serviceId: this.data.w_serviceId,characteristicId: this.data.w_characteristicId,value: tmpBuffer,success(res) {console.log('发送成功!', res)}})sleep(0.02)} else {tmpBuffer = buffer.slice(pos, pos + bytes);pos += bytes;bytes -= bytes;wx.writeBLECharacteristicValue({deviceId: this.data.w_deviceId,serviceId: this.data.w_serviceId,characteristicId: this.data.w_characteristicId,value: tmpBuffer,success(res) {console.log('最后次发送', res)//发送完成获取返回值//注:蓝牙有可能会分包给你返回也有可能一次性返回wx.onBLECharacteristicValueChange(function (characteristic) {//判断是否已经接收完返回值//根据自己蓝牙硬件返回的格式判断是否接收完成,如果没接收完继续接收//ab2hex 是16进制转10进制result = result + ab2hex(characteristic.value)//比如硬件返回给你参数指定了长度,你就可以根据长度判断if (result.length == 18) {console.log("返回值为:"+result)}})},fail: function (res) {console.log('发送失败', res)}})}}
断开蓝牙
//断开蓝牙wx.closeBLEConnection({deviceId: this.data.deviceId})
停止搜索蓝牙
//停止搜寻附近的蓝牙外围设备wx.stopBluetoothDevicesDiscovery()
转16进制
//转16进制function hexStringToArrayBuffer(command) {if (!command) {return new ArrayBuffer(0);}var buffer = new ArrayBuffer(command.length);let dataView = new DataView(buffer)let ind = 0;for (var i = 0, len = command.length; i < len; i += 2) {let code = parseInt(command.substr(i, 2), 16)dataView.setUint8(ind, code)ind++}return buffer;}
ArrayBuffer转16进度字符串示例
// ArrayBuffer转16进度字符串示例function ab2hex(buffer) {var hexArr = Array.prototype.map.call(new Uint8Array(buffer),function (bit) {return ('00' + bit.toString(16)).slice(-2)})return hexArr.join('');}
function inArray(arr, key, val) {for (let i = 0; i < arr.length; i++) {if (arr[i][key] === val) {return i;}}return -1;}
总结
微信小程序连接蓝牙坑还是挺多的,连接蓝牙根据文档可以自己完成,但是在找一个能写入读取蓝牙数据的特征值是一般很多刚接触的朋友可能都不会去观察他的特征值为什么这个能行那个不行之类的,其次就是分包发送数据这个应该大家一查就知道了,最后分包接收数据根据自己硬件返回值的特定格式做判断接收完成即可,这个就是一个完整的微信小程序连接蓝牙并读写数据的功能了,欢迎大家交流。如果对你有帮助希望能给个关注,我会继续分享更多的内容!
注:初学者在使用的时候出现this指向报错,在当前方法第一行把this赋值给你的自定义变量然后用自定义变量代替this就行了!