微信小程序蓝牙BLE实战开发(一)迟来的更新。从4月份以来项目中断续在对接好几个共享产品,关于蓝牙BLE设备,通过蓝牙与设备之间通信进行使用产品。
开发中也遇到不少问题哈,后面抽时间续篇。写得不好,请各位大神多多指教。此篇主要介绍一些API操作及一些返回数据结构, 项目已上线。后面抽时间上demo
ps: 如果有了解过蓝牙这块, 代码可直接复制使用
文章目录微信小程序蓝牙BLE实战开发(一)关于字节
流程图
使用步骤初始化数据
给变量赋值
1. `初始化蓝牙`模块
2. `监听寻找新设备`事件设备返回数据`效果图`
注意:
说明:
3. `开始`搜寻附近的蓝牙设备
4. `停止`搜寻附近的蓝牙设备
5. `连接`低功耗蓝牙设备
6. 获取蓝牙`所有服务`设备返回数据`效果图`
7. 获取某个服务中所有特征值返回数据结构`效果图`
注意:
8. 写入数据
9. 断开蓝牙设备的连接
10. 错误码判断
处理数据方法
关于下篇内容
关于字节字节(Byte):是计算机信息技术用于计量存储容量的一种计量单位,作为一个单位来处理的一个二进制数字串。
其中下发指令或处理数据时都可以应用到1B(byte,字节)= 8 bit(比特), 相当于一个字符
一个字节能表示的最大的整数就是255
例如: 数据为5d000001be5d理解为6个字节(6B)
流程图BLE执行大致流程,为了节省空间,画的比较乱哈。
使用步骤
微信小程序低功耗蓝牙API
微信小程序官方_蓝牙说明这里单独放在一个js文件中
初始化数据根据需求定义,个人在一个项目中开发好几个产品,同时对接不同蓝牙协议供应商,有些变量放全局,根据不同供应商来操作var serviceUUID = [] //主 service 的 uuid 列表var writeUUID = ""; //写读 UUIDvar notifyUUID = ""; //notify UUIDvar filterServiceUUID = ""; //过滤获取到的服务uuid(有些会返回多条数据)var filterDeviceName = ""; //设备名称var macAddress = ""; //保存得到mac地址var flagFromTypes = ''; //来源类型var _discoveryStarted = false;var deviceId = ''; //用于区分设备的 idvar _deviceId = '';var _serviceId = '';var _characteristicId = '';var status = false; //当前状态var action_type = ''; //操作类型var code = -1;var isnotExist = true
给变量赋值设备相关服务通常蓝牙协议文档上有说明,Read、Write、 Notify。如果没有说明可通过搜索设备看到
某些供应商读写通过统一用一个服务的serviceUUID[0] = "0000*E0-00*0-*0*0-*0*0-00**5F9**4*B"; //主 service 的 uuid 列表writeUUID = "00*0**E2-00*0-*0*0-*0*0-00**5F9**4*B"; //写读 UUIDnotifyUUID = "00*0**E1-00*0-*0*0-*0*0-00**5F9**4*B"; //notify UUIDfilterServiceUUID = "*E0";filterDeviceName = getNameMac(macAddress, 6, 'abc_'); //设备名称
1. 初始化蓝牙模块wx.openBluetoothAdapter(Object obj)
ps: 调用此方法initBle()就可以使用哦,【建议顺序查看,易理解】function initBle(fromMac, flagTypes, currentSerial) { //断开连接【每次初始化先断开连接】 closeBLEConnection(); // macAddress = clearSymbol(fromMac); macAddress = fromMac; //保存mac flagFromTypes = flagTypes //类型来源currentSerialVal = currentSerial //当前操作序号 wx.openBluetoothAdapter({ success: (res) = { console.log('openBluetoothAdapter 初始化蓝牙模块是否成功:', res) // 监听寻找新设备事件 onBluetoothDeviceFound(); //开始搜寻附近的蓝牙外围设备 startBluetoothDevicesDiscovery(); }, fail: (res) = { console.log('初始化蓝牙失败', res); //自行处理【可弹窗提示用户开启蓝牙】,这通过回调处理 asddErrorCallback(res.errCode, ""); //监听蓝牙适配器状态变化事件【根据需求是否执行】 // wx.onBluetoothAdapterStateChange(function (res) { // console.log('蓝牙适配器状态更改结果: ', res) // if (res.available) { // console.log('蓝牙可用,搜索设备:--》 ') // onBluetoothDeviceFound(); // startBluetoothDevicesDiscovery(); // } // }) } })}
2. 监听寻找新设备事件wx.onBluetoothDeviceFound(function callback)
说明: 广播数据: 可以得到当前蓝牙设备的相关数据,另外,如果设备有返回其他数据时在advertisData数据段中得到,【有些供应商是没有返回的】
设备返回数据效果图下图是两家供应商设备返回的数据, 左图advertisData返回8个字节数据【数据需转换】。右图则没有。同时可以看到返回name格式也是不一样的【自定义】
注意:安卓下部分机型需要有位置权限才能搜索到设备,需留意是否开启了位置权限
Android设备返回是mac地址, IOS返回是uuid,由32位字母和数据组成,并且是动态的。
说明:为了保证准确性建议通过mac地址匹配。mac地址正常是12位
假设:advertisData字段返回数据是0000365544332211。【可根据文档说明取需要数据】在advertisData得到数据(不一定有数据哦),截取mac地址匹配。【假如第4位至16位为mac(365544332211)】, 用变量保存下来。
如果advertisData没有返回其他数据,该如何匹配设备?通过设备name进行匹配设备, 供应商通常会以前缀+mac前/后几位,或12位。当前还有一些只有前缀的
比如 FIC_992f3e,其中992f3e是设备6位mac地址。【根据实际情况操作】
案例:以下demo提供两种匹配设备方式. 通过mac或name匹配设备【每个供应商返回的name格式不一样 】/** * 监听寻找新设备事件 * 搜索匹配设备后,自动连接设备 */function onBluetoothDeviceFound() { wx.onBluetoothDeviceFound((res) = { console.log('广播数据结果:', res); res.devices.forEach(device = { if (!device.name && !device.localName) { return } // 转换后, 得出相关数据 var hexStr = ab2hex(device.advertisData); console.log("广播数据中转换后:advertisData----" + hexStr); //通过获取mac匹配 if ((macAddress != "") && (macAddress == device.deviceId) && isnotExist) { isnotExist = false; deviceId = device.deviceId; console.log('android--tempDeviceId:' + deviceId); //停止搜寻附近的蓝牙外围设备 stopBluetoothDevicesDiscovery(); //连接设备 createBLEConnection(); } //通过name匹配设备 let deviceName = device.name.toUpperCase(); if ((deviceName.indexOf(filterDeviceName) != -1) && isnotExist) { isnotExist = false; deviceId = device.deviceId; console.log('ios or android--tempDeviceId:' + deviceId); //停止搜寻附近的蓝牙外围设备。 stopBluetoothDevicesDiscovery(); //连接设备 createBLEConnection(); } }) })}
3. 开始搜寻附近的蓝牙设备wx.startBluetoothDevicesDiscovery(Object object)
注意 此操作比较耗费系统资源,请在搜索并连接到设备后调用 wx.stopBluetoothDevicesDiscovery方法停止搜索function startBluetoothDevicesDiscovery() { console.log("执行连接蓝牙设备 回调空===" + _discoveryStarted); if (_discoveryStarted) { return; } _discoveryStarted = true wx.startBluetoothDevicesDiscovery({ services: serviceUUID, //如果设置此参数,则只搜索广播包有对应 uuid 的主服务的蓝牙设备。 allowDuplicatesKey: false, success: (res) = { console.log('启动搜索蓝牙设备, 结果 :', res) //onBluetoothDeviceFound() //先调用此方法再使startBluetoothDevicesDiscovery }, fail(res) { asddErrorCallback(res.errCode, ""); console.log('startBluetoothDevicesDiscovery fail', res); } })}
4. 停止搜寻附近的蓝牙设备wx.stopBluetoothDevicesDiscovery(Object object)//停止搜寻附近的蓝牙外围设备。function stopBluetoothDevicesDiscovery() { wx.stopBluetoothDevicesDiscovery()}
5. 连接低功耗蓝牙设备wx.createBLEConnection(Object object)/** * 连接蓝牙设备 */function createBLEConnection() { var that = this; wx.createBLEConnection({ deviceId: deviceId, success: (res) = { wx.showToast({ title: '设备连接成功', duration: 2000 }) getBLEDeviceServices(deviceId) }, fail: (res) = { console.log('createBLEConnection fail', res); asddErrorCallback(res.errCode, ""); } }) //停止搜索 stopBluetoothDevicesDiscovery();}
6. 获取蓝牙所有服务wx.onBLEConnectionStateChange(function callback)
wx.getBLEDeviceServices(Object object)
注意:有些供应商会返回多个服务,只要找自己需要的服务就好监听蓝牙连接状态,可以处理连接连接意外断开等情况
获取需要的蓝牙服务后,再调用获取蓝牙特征值方法
设备返回数据效果图假设: 需要的服务是包含EE0的,只需要过滤下就可以【这里通过indexOf】
function getBLEDeviceServices(deviceId) { //监听低功耗蓝牙连接状态的改变事件 wx.onBLEConnectionStateChange(function(res) { console.log("onBLEConnectionStateChange:", res); // 该方法回调中可以用于处理连接意外断开等异常情况 console.log(`device${res.deviceId}state has changed, connected:${res.connected}`) if (res.connected == false) { console.log("连接意外断开等****", _deviceId); _deviceId = ''; if (flagFromTypes == 1 && flagFromTypes == 2) { asddErrorCallback(1010, ""); } } }); //获取蓝牙所有service wx.getBLEDeviceServices({ deviceId: deviceId, success: (res) = { // console.log("获取蓝牙设备所有服务(service)", res); for (let i = 0; i res.services.length; i++) { let tmpUuid = res.services[i].uuid; if (