微信小程序使用蓝牙通信协议连接硬件整理总结(蓝牙连接、获取设备UUID、开水器notify及关闭蓝牙)

简介: 微信小程序使用蓝牙通信协议连接硬件整理总结(蓝牙连接、获取设备UUID、开水器notify及关闭蓝牙)

前言

书接前文,上篇文章我们主要介绍了初始化蓝牙、以及搜索附近蓝牙设备以及展示搜索到的蓝牙设备,但是我们在真实的业务场景中,肯定是需要将搜到的设备“用”起来的,所以本文我们就介绍一下如何使用小程序连接蓝牙设备以及后续的操作。

进行蓝牙连接

连接蓝牙设备主要使用wx.createBLEConnection方法,若小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需再次进行搜索操作。
实现代码如下:

//通过蓝牙设备的id进行蓝牙连接
      const createBLEConnection = () => {
        wx.createBLEConnection({
          deviceId: ConnectedDeviceRelated.deviceId,
          success: function (res) {
            wx.stopBluetoothDevicesDiscovery({
              success: function (res) {
                console.log('连接成功,关闭蓝牙搜索')
                ConnectedDeviceRelated.isSearchBluetooth_detectionBoard = false
              }
            })
            getBLEDeviceServices()
          },
          fail: function (res) {
            //连接失败后重连
            if (that.data.isconnect == 'false') {
              createBLEConnection()
            }
          }
        })
      }

其中,deviceId就是我们搜索到的蓝牙设备的id

注意:

  1. 请尽量成对的调用wx.createBLEConnectionwx.closeBLEConnection接口,安卓如果重复调用wx.createBLEConnection创建连接,有可能导致系统对同一设备持有多个连接实例,会导致调用closeBLEConnection的时候并不能真正的断开与设备的连接。
  2. 蓝牙连接随时有可能断开,可以调用wx.onBLEConnectionStateChange来监听设备断开,当设备断开时根据连接需求进行重连操作。

到这里蓝牙设备就连接上了(因为安卓和iOS的区别,iOS连接上蓝牙后,可以在通知栏看到蓝牙图标显示或者在控制中心看到蓝牙设备连接的名称来判断是否已经连接;安卓只能通过小程序提供的API回调参数来判断),如果想要获取蓝牙设备的数据或向蓝牙设备写入指令,就需要下面的步骤:

获取蓝牙设备的UUID

我们需要使用wx.getBLEDeviceServices来获取蓝牙设备的UUID

获取蓝牙低功耗设备所有服务 (service),代码如下:

 //获取蓝牙设备的uuid
      const getBLEDeviceServices = () => {
        wx.getBLEDeviceServices({
          deviceId: ConnectedDeviceRelated.deviceId,
          success: function (res) {
            for (var i = 0; i < res.services.length; i++) {
              if (res.services[i].uuid.includes('xxxxx')) {
                ios_uuid.push({
                  'notify': res.services[i].uuid
                })
              } else if (res.services[i].uuid.includes('xxxx')) {
                ios_uuid.push({
                  'write': res.services[i].uuid
                })
              }
            }
            getBLEDeviceCharacteristics()
          }
        })
      }

其中deviceId为搜索蓝牙设备时获取的设备id;这里按照蓝牙设备的不同,会获取到一个或多个服务id
在这里插入图片描述
这个时候只需获取最关键的两个服务idnotifywrite,怎么判断呢?一般对接这些设备都会给你协议文档,里面会提及用到的服务id,以及他们的作用,那如果没有文档或者文档里面没有说呢?那你就要一个一个去试了.......

获取UUID中的特征值

我们需要通过wx.getCLEDeviceCharacteristics方法来获取UUID的特征值。
代码如下:

//获取蓝牙设备uuid的notify特征值
      const getBLEDeviceCharacteristics = () => {
        var notify = null;
        for (var i = 0; i < ios_uuid.length; i++) {
          if (ios_uuid[i].hasOwnProperty('notify')) {
            notify = ios_uuid[i].notify
          }
        }
        wx.getBLEDeviceCharacteristics({
          deviceId: ConnectedDeviceRelated.deviceId,
          serviceId: notify,
          success: function (res) {
            ios_uuidEigenvalues.push(res.characteristics[0].uuid)
            setTimeout(() => (
              startNotice(notify)
            ), 800)
          },
          fail: function (res) {
            console.log('获取uuid的notify特征值失败', res)
          }
        })
      }

其中deviceId为前面搜索到的蓝牙设备的idserviceId为获取的支持开启notifyuuid
在这里插入图片描述
上图为获取服务中特征值成功的回调参数,其中在properties属性中就可以判断获取的uuid的作用,图示的是 只支持开启notifyuuid。部分蓝牙设备只会包含一个uuid,但会有同时开启notifywrite的能力。

开启notify

开启notify需要调用wx.notifyBLECharacteristicValueChange方法,启用蓝牙低功耗设备特征值变化时的 notify 功能,订阅特征。注意:必须设备的特征支持 notify 或者 indicate 才可以成功调用。
代码如下:

const startNotice = notify => {
        wx.notifyBLECharacteristicValueChange({
          state: true,
          deviceId: ConnectedDeviceRelated.deviceId,
          serviceId: notify,
          characteristicId: ios_uuidEigenvalues[0],
          success: function (res) {
            console.log("开启notify成功")
            //获取蓝牙设备uuid的write特征值
            getBLEDeviceCharacteristics_write()
          },
          fail: function (res) {
            console.log("notity失败", res)
          }
        })
      }

其中,state为是否启用notifydeviceId为步骤3中获取的设备idserviceId为获取的uuidcharacteristicIduuid特征值.

还是因为设备的不同,有的设备不需要主机(你的设备)主动触发从机(蓝牙设备)的功能,所以直接在开启notify的方法中 监听蓝牙设备返回的数据就可以了
代码如下:

    wx.onBLECharacteristicValueChange(function (characteristic) {
              isOk = true
              if (that.ab2hex(characteristic.value).substring(0, 4) == 'xxxxx') {
                that.judgingElectricity(that.ab2hex(characteristic.value))
              } else if (that.ab2hex(characteristic.value) == ConnectedDeviceRelated.turnSuccess_notify) {
                sendMy(ConnectedDeviceRelated.approve)
              } else if (that.ab2hex(characteristic.value) == 'xxxx') {
                console.log('认证成功')
                ConnectedDeviceRelated.disconnect = true
                app.globalData.isturn = 'true'
                app.globalData.isconnect = 'true'
                that.setData({
                  isturn: 'true',
                  isconnect: 'true',
                  BluetoothNotConnected_icon: that.data.BluetoothIsConnected_icon,
                  electricityNotConnected_icon: that.data.electricityIsConnected_icon
                })
                that.isDeviceUnique(0)
              }
            })

注意:
这里蓝牙设备返回的数据格式是arraybuffer需要再转一下字符串,代码如下:

// arraybuffer转字符串
  ab2hex: function (buffer) {
    var hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
    return hexArr.join('');
  },

如果你对接的蓝牙设备需要被动的触发功能(比如主机发送对应的功能指令),就要通过步骤中获取支持writeuuid,通过上面的方法获取UUID特征值,然后向蓝牙设备写入`,写入成功,触发了成功的回调后,接着调用wx.onBLECharacteristicValueChange`监听蓝牙设备返回的数据:
代码如下:

 wx.writeBLECharacteristicValue({
          deviceId: ConnectedDeviceRelated.deviceId,
          serviceId: ConnectedDeviceRelated.services_write,
          characteristicId: ConnectedDeviceRelated.write,
          value: arrayBuffer,
          success: function (res) {
            wx.showToast({
              title: '正在连接中...',
              icon: 'none',
              duration: 2000
            })
            //检测板子自己关闭 再打开后自动连接 如果写入后没反应,就再写入
            setTimeout(function (params) {
              if (isOk == false) {
                sendMy('notify')
              }
            }, 1500)
            //监听设备返回的值
            wx.onBLECharacteristicValueChange(function (characteristic) {
              isOk = true
              if (that.ab2hex(characteristic.value).substring(0, 4) == 'fdf4') {
                that.judgingElectricity(that.ab2hex(characteristic.value))
              } else if (that.ab2hex(characteristic.value) == ConnectedDeviceRelated.turnSuccess_notify) {
                sendMy(ConnectedDeviceRelated.approve)
              } else if (that.ab2hex(characteristic.value) == 'xxxx') {
                console.log('认证成功')
                ConnectedDeviceRelated.disconnect = true
                app.globalData.isturn = 'true'
                app.globalData.isconnect = 'true'
                that.setData({
                  isturn: 'true',
                  isconnect: 'true',
                  BluetoothNotConnected_icon: that.data.BluetoothIsConnected_icon,
                  electricityNotConnected_icon: that.data.electricityIsConnected_icon
                })
                that.isDeviceUnique(0)
              }
            })
            //监听连接断开
            that.disconnect()
          },
          fail: function (res) {
            console.log('写入失败', res)
          },
        })

注意:
这里的value需要的是arraybuffer格式的数据指令,所以需要把字符转成arraybuffer

关闭蓝牙

断开与蓝牙低功耗设备的连接,代码如下:

wx.showModal({
            title: '提示',
            content: '要关闭蓝牙吗?',
            success: function (res) {
              if (res.confirm) {
                if (app.globalData.bluetooth == 'W8') {
                  deviceId = ConnectedDeviceRelated.deviceId_sphygmomanometer
                } else if (app.globalData.bluetooth == 'Yuwell BP-YE8900A') {
                  deviceId = ConnectedDeviceRelated.deviceId_YYSphygmomanometer
                }
                wx.closeBLEConnection({
                  deviceId: deviceId,
                  success(res) {
                    console.log("关闭蓝牙成功")
                    ConnectedDeviceRelated.disconnect = false
                    app.globalData.isconnect_bloodPressure = false
                    that.setData({
                      isconnect_bloodPressure: false,
                      SphygmomanometerBluetoothNotConnected_icon: config.ImageAddr_url + 'applets/images/jiance/YRSphygmomanometerBluetoothNotConnected.png',
                    })
                  }
                })
              }
            }
          })
目录
相关文章
|
6月前
|
小程序 安全 API
社区每周丨小程序基础API新增获取设备、系统等多个接口
社区每周丨小程序基础API新增获取设备、系统等多个接口
152 11
|
5月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的小型医院医疗设备管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的小型医院医疗设备管理系统附带文章源码部署视频讲解等
60 6
|
3月前
|
小程序 安全 前端开发
支付宝小程序究竟藏着怎样的秘密?竟能成为连接亿万用户的桥梁!
【8月更文挑战第27天】随着移动互联网的发展,小程序已成为连接用户和服务的关键桥梁。支付宝小程序凭借其庞大的用户群和丰富的生态场景,为开发者提供了巨大的发展空间。本文提供了一份支付宝小程序开发者指南,帮助开发者从开发准备、开发流程、最佳实践到示例代码全面掌握支付宝小程序开发技能,从而连接亿万用户。开发者需先注册支付宝开发者账号,安装小程序开发者工具,并了解小程序架构;然后按步骤创建项目、编写代码、调试预览直至发布。此外,还需注重优化用户体验,充分利用支付宝生态资源,关注安全合规问题,以实现小程序的成功。
48 0
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的实验室设备管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的实验室设备管理系统附带文章和源代码部署视频讲解等
49 9
|
5月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的农业设备租赁系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的农业设备租赁系统附带文章源码部署视频讲解等
43 0
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的工厂生产设备维护管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的工厂生产设备维护管理系统附带文章和源代码部署视频讲解等
32 0
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的电脑硬件库存管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的电脑硬件库存管理系统附带文章和源代码部署视频讲解等
32 0
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的学生宿舍设备报修管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的学生宿舍设备报修管理系统附带文章和源代码部署视频讲解等
44 0
|
6月前
|
JavaScript Java 测试技术
基于小程序的设备故障报修管理系统+springboot+vue.js附带文章和源代码设计说明文档ppt
基于小程序的设备故障报修管理系统+springboot+vue.js附带文章和源代码设计说明文档ppt
44 0
|
6月前
|
小程序 JavaScript Java
基于SpringBoot+Vue+uniapp微信小程序的设备故障报修管理系统的详细设计和实现
基于SpringBoot+Vue+uniapp微信小程序的设备故障报修管理系统的详细设计和实现
63 1