微信小程序-蓝牙配网功能

605 阅读4分钟

转载自微信小程序-蓝牙配网功能

使用蓝牙功能去连接一个蓝牙设备,我们需要知道这个设备的名称,这个设备名称我是通过扫码得到的,得到这个设备的详细信息以后,我们就需要初始化蓝牙模块

1.0 初始化蓝牙模块

startBleAdapter() {
    var that = this
    wx.openBluetoothAdapter({
      success: function (res) {
        that.getBluetoothAdapterState()
      },
      fail: function (res) {
        if (res.errCode == 10001) {
          //手机蓝牙不可用
         console.log('手机蓝牙不可用: ' + res)
          wx.showToast({
            title: '手机蓝牙不可用,请开启蓝牙再试~',
            icon: 'none',
            duration: 2000
          })
        } else if (res.errCode == 103 || res.errno == 103) {
          //授权问题
          that.openConfirm()
        }
      }
    })
  },

  // 再次获取授权,引导客户手动授权
  openConfirm() {
    wx.showModal({
        content: '检测到您没打开此小程序的蓝牙权限,是否去设置打开?',
        confirmText: "确认",
        cancelText: "取消",
        success: (res) => {
            //点击“确认”时打开设置页面
            if (res.confirm) {
                wx.openSetting({
                    success: (res) => {}
                })
            } else {
                console.log('用户点击取消')
            }
        }
    })
  }

在初始化蓝牙模块的时候我遇到了第一个问题,可谓出师不利,在我初始化手机上蓝牙模块的时候,wx.openBluetoothAdapter这个api一直调用失败,说我手机没有打开蓝牙,可是我检查了好几遍,手机上的蓝牙我是开启了的,代码也没啥问题,手动狗头。最后面向百度编程,才得知,当你使用苹果手机的时候(安卓的没试过),光打开设置了里面的蓝牙是不够的,还得将设置–>微信–>蓝牙打开才OK

2.0 获取本机蓝牙适配器状态

  //检测本机蓝牙是否可用
  getBluetoothAdapterState() {
    var that = this
    //获取本机蓝牙适配器状态
    wx.getBluetoothAdapterState({
      success: function (res) {
        if (res.errMsg == 'getBluetoothAdapterState:ok') {
          //搜寻附近的蓝牙设备
          that.startBluetoothDevicesDiscovery()
        }
        //{errMsg: "getBluetoothAdapterState:ok", available: true, discovering: false}
      },
      fail: function (res) {
        // console.log('获取本机蓝牙适配器状态', res)
      },
    })
  },

3.0 获取本机蓝牙适配器状态

  getBluetoothAdapterState() {
    var that = this
    //获取本机蓝牙适配器状态
    wx.getBluetoothAdapterState({
      success: function (res) {
        if (res.errMsg == 'getBluetoothAdapterState:ok') {
          //搜寻附近的蓝牙设备
          that.startBluetoothDevicesDiscovery()
        }
      },
      fail: function (res) {
         console.log('获取本机蓝牙适配器状态', res)
      },
    })
  },
  

4.0 开始搜寻附近的蓝牙外围设备

startBluetoothDevicesDiscovery() {
    var that = this;
    console.log('开始搜寻附近的蓝牙外围设备')
    wx.startBluetoothDevicesDiscovery({
      powerLevel: "high",
      success: function (res) {
        console.log('开始搜寻附近的蓝牙外围设备: ', res)
        if (res.errCode == 0) {
        // 监听寻找到新设备的事件
          that.onBluetoothDeviceFound()
        }
      },
      fail: function (res) {
        console.log('开始搜寻附近的蓝牙外围设备,发生错误: ', res)
      }
    })
  },

5.0 监听寻找到新设备的事件

  onBluetoothDeviceFound() {
    var that = this
    wx.onBluetoothDeviceFound((res) => {
      res.devices.forEach(device => {
        if (!device.name && !device.localName) {
          return
        }
        const foundDevices = that.data.devices
          const idx = that.inArray(foundDevices, 'deviceId', device.deviceId)
          console.log(idx);
          
          const data = {}
          if (idx === -1) {
            data[`devices[${foundDevices.length}]`] = device
          } else {
            data[`devices[${idx}]`] = device
          }
          that.setData(data)
      })
    })
  },

6.0 连接蓝牙

 createBLEConnection(e) {
    var that = this
    const ds = e.currentTarget.dataset
    const deviceId = ds.deviceId
    const name = ds.name
    //连接蓝牙前先关闭已连接蓝牙
    wx.createBLEConnection({
      deviceId: deviceId,
      success: function (res) {
        console.log('连接蓝牙成功', res)
        //获取连接设备的service服务
        that.getBLEDeviceServices(deviceId);
        //停止搜寻附近的蓝牙外围设备
        wx.stopBluetoothDevicesDiscovery({
          success: function(res) {
            console.log('停止搜寻附近的蓝牙外围设备',res)
          },
          fail:function(res){

          }
        })
      },
      fail: function (res) {
        console.log('连接蓝牙失败', res)
      },
    })
  },

7.0 获取连接设备的service服务

  getBLEDeviceServices(deviceId) {
    var that = this
    wx.getBLEDeviceServices({
      deviceId: deviceId,
      success: function (res) {
        console.log('获取连接设备的service服务', res)
        for (let i = 0; i < res.services.length; i++) {
          if (res.services[i].isPrimary && res.services[i].uuid == serviceUUID) {
            that.setData({
              deviceId: deviceId,
              serviceId: res.services[i].uuid
            })
            //获取连接设备的所有特征值
            that.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
          }
        }
      },
      fail: function (res) {
        console.log('获取蓝牙失败', res)
      }
    })
  },

8.0 获取连接设备的所有特征值

  getBLEDeviceCharacteristics(deviceId, serviceId) {
    var that = this
    wx.getBLEDeviceCharacteristics({
      deviceId: deviceId,
      serviceId: serviceId,
      success: function (res) {
        console.log('获取连接设备的所有特征值', res);
        if (res.errCode == 0) {
          that.setData({
            lbeCharacteristics: res.characteristics
          })
          for (var i = 0; i < res.characteristics.length; i++) {
            console.log("readCharcteristicUUID: ",readCharcteristicUUID)
            if (that.data.lbeCharacteristics[i]['properties']['read'] && that.data.lbeCharacteristics[i]['uuid'] === readCharcteristicUUID) {
              that.setData({
                deviceReadCharcteristicUUID: that.data.lbeCharacteristics[i]['uuid']
              })
            } else if (that.data.lbeCharacteristics[i]['properties']['write'] && that.data.lbeCharacteristics[i]['uuid'] === writeCharcteristicUUID) {
              that.setData({
                deviceWriteCharcteristicUUID: that.data.lbeCharacteristics[i]['uuid']
              })
            }
            that.notifyBLECharacteristicValueChange(deviceId, serviceId, that.data.lbeCharacteristics[i]['uuid'])
          }
          
          //这里就可以去给蓝牙设备发送数据了
        } else {
          console.log('获取特征值失败')
        }
      },
    })
  },

9.0 启用低功耗蓝牙设备特征值变化时的 notify 功能

  notifyBLECharacteristicValueChange(deviceId, serviceId, characteristicId) {
    var that = this
    wx.notifyBLECharacteristicValueChange({
      deviceId: deviceId,
      serviceId: serviceId,
      characteristicId: characteristicId,
      state: true,
      success: function (res) {
        console.log('启用低功耗蓝牙设备特征值变化时的 notify 功能', res)
        that.onBLECharacteristicValueChange()
      },
      fail: function (res) {
        console.log('启用低功耗蓝牙设备特征值变化时的 notify 功能失败', res)
      }
    })
  },

10.0 监听低功耗蓝牙设备的特征值变化事件(必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification)。此方法是接收蓝牙设备返回数据的

  onBLECharacteristicValueChange() {
    var that = this
    wx.onBLECharacteristicValueChange(function (res) {
      console.log('监听低功耗蓝牙设备的特征值变化事件: ', res)
      console.log(`characteristic ${res.characteristicId} has changed, now is ${res.value}`)
      that.handleDeviceBleData(res.value)
    })
  },

BLE 4.0 中发送一个数据包只能包含 20 字节的数据,大于 20 字节只能分包发送。微信小程序提供的 API 中似乎没有自动分包的功能,这就只能自己手动分包了。调试中发现,在 iOS 系统中调用 wx.writeBLECharacteristicValue 发送数据包,回调 success 后紧接着发送下一个数据包,很少出现问题,可以很快全部发送完毕。而安卓系统中,发送一个数据包成功后紧接着发送下一个,很大概率会出现发送失败的情况,在中间稍做延时再发送下一个就可以解决这个问题(不同安卓手机的时间长短也不一致),照顾下一些比较奇葩的手机,大概需要延时 250 ms 。不太好的但是比较科学的办法是,只要成功发送一个数据包则发送下一个,否则不断重发,具体就是

wx.writeBLECharacteristicValue 回调 fail 则重新发送,直至发送完毕

下面这个链接是我一个前辈的博客,对我这个功能的开发帮组非常大,比我的更完善
www.cnblogs.com/guhonghao/p…