微信小程序对接蓝牙设备连接

1.小程序初始化蓝牙设备(查看手机蓝牙是否打开)

initBlue:function(){
  wx.openBluetoothAdapter({
     success: (res) => {
       console.log('初始化蓝牙设备成功')
       this.findBlue();//2.0
     },
     fail: (res)=> {//如果手机上的蓝牙没有打开,可以提醒用户
      console.log('手机蓝牙未打开')
    }
 })
},

2.手机蓝牙初始化成功之后,搜索周边的蓝牙设备

findBlue(){
  wx.startBluetoothDevicesDiscovery({
    allowDuplicatesKey: false,
    interval: 0,
    success:(res) => {
      wx.showLoading({
        title: '正在搜索设备',
      })
      this.getBlue()
    },
    fail: (res) => {
      wx.hideLoading()
      console.log('搜索附近的蓝牙设备失败')
    }
  })
},

3.搜索蓝牙设备之后,需要获取搜索到的蓝牙设备信息
微信小程序提供了两个方法可以获取搜索到的蓝牙设备信息,分别是:

1)wx.onBluetoothDeviceFound
监听寻找到新设备的事件 ——表示只要找到一个新的蓝牙设备就会调用一次该方法

2)wx.getBluetoothDevices
获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备

两个方法的区别:

第一次我使用的是wx.onBluetoothDeviceFound方法进行联调,发现一切正常,由于调试的时候就只有一台设备,发现第二次重新扫码这个蓝牙设备的时候,找不到这个设备了,因为对这个方法来说,这不是一个新的设备,以前连接上过;或者当你因为某些原因蓝牙传送数据指令的时候出错了需要重新连接,再次连接的时候也找不到当前设备,还是同样的原因,因为当前设备对这个方法来说不是一个新设备,

getBlue(){
  wx.getBluetoothDevices({
    success: (res) => {
      wx.hideLoading();
      // 如果搜索到设备列表为空的话
      if (res.devices.length == 0) {
         // 监听搜索到新设备
         wx.onBluetoothDeviceFound((bres) => {
           for (var i = 0; i < bres.devices.length; i++) {
           let device = bres.devices[i]
           if (device.name == this.data.inputValue || device .localName == this.data.inputValue){
                this.getBlue()
              }
            }
          })
          return
      } else {
        for (var i = 0; i < res.devices.length; i++){
          // 判断里面是否有我想要的蓝牙设备
          if (res.devices[i].name == this.data.inputValue || res.devices[i].localName == this.data.inputValue){
            this.setData({
              deviceId: res.devices[i].deviceId
            })
            this.connetBlue(res.devices[i].deviceId);//4.0
            return;
          }
        }     
      }
    },
    fail: () =>{
      console.log("搜索蓝牙设备失败")
    }
  })
},

4.找到指定蓝牙之后,通过蓝牙设备的id进行蓝牙连接

connetBlue(deviceId){                    
  wx.createBLEConnection({
    deviceId: deviceId,//设备id
    success: (res) => {
      console.log("连接蓝牙成功!")
      // 连接成功后关闭蓝牙搜索
      wx.stopBluetoothDevicesDiscovery({
         success: (res) => {
           console.log('连接蓝牙成功之后关闭蓝牙搜索');
         }
      })
      this.getServiceId()//5.0
    }
  })
},

5连接上需要的蓝牙设备之后,获取这个蓝牙设备的服务uuid

getServiceId(){
  wx.getBLEDeviceServices({
    deviceId: this.data.deviceId,
    success: (res) => {
      var model = res.services[0]
      this.setData({
        services: model.uuid
      })
      this.getCharacteId()//6.0
    }
  })
},

6.如果一个蓝牙设备需要进行数据的写入以及数据传输,就必须具有某些特征值,所以通过上面步骤获取的id可以查看当前蓝牙设备的特征值

getCharacteId(){
  wx.getBLEDeviceCharacteristics({
   deviceId: this.data.deviceId,
   serviceId: this.data.services,
   success: (res) => {
     for (var i = 0; i < res.characteristics.length; i++) {//2个值
       var model = res.characteristics[i]
       if (model.properties.notify == true) {
         this.setData({
           notifyId: model.uuid//监听的值
         })
         this.startNotice(model.uuid)//7.0
       }
       if (model.properties.write == true){
         this.setData({
           writeId: model.uuid//用来写入的值
         })
       }
     }
    }
  })
},

7.创建连接,发送指令

startNotice(uuid){
  wx.notifyBLECharacteristicValueChange({
    state: true, // 启用 notify 功能
    deviceId: this.data.deviceId,
    serviceId: this.data.services,
    characteristicId: uuid,  //第一步 开启监听 notityid  第二步发送指令 write
    success: (res) => {
      // 设备返回的方法
      wx.onBLECharacteristicValueChange((res) => {
        // 此时可以拿到蓝牙设备返回来的数据是一个ArrayBuffer类型数据,
        //所以需要通过一个方法转换成字符串
        var nonceId = this.ab2hex(res.value) 
    //拿到这个值后,肯定要去后台请求服务(当前步骤根据当前需求自己书写),
    //获取下一步操作指令写入到蓝牙设备上去
     wx.request({
           method: "POST",
      data: {
             xx:nonceId
           },
           url: url,
           success: (res) => {
             //res.data.data.ciphertext:我这边服务返回来的是16进制的字符串,
             //蓝牙设备是接收不到当前格式的数据的,需要转换成ArrayBuffer
             this.sendMy(this.string2buffer(res.data.data.ciphertext))//8.0
           // 服务器返回一个命令  我们要把这个命令写入蓝牙设备
           }
        })
     }
  })
},

8.将从后台服务获取的指令写入到蓝牙设备当中

sendMy(buffer){
  wx.writeBLECharacteristicValue({
      deviceId: this.data.deviceId,
      serviceId: this.data.services,
      characteristicId: this.data.writeId,//第二步写入的特征值
      value: buffer, // 这里的value是ArrayBuffer类型
      success: (res) => {
        console.log("写入成功")
      },
      fail: () => {
        console.log('写入失败')
      },
      complete:() => {
        console.log("调用结束");
      }
   })
},

下面是需要使用到的两个格式相互转换的方法

// 将字符串转换成ArrayBufer
string2buffer(str) {
  let val = ""
  if(!str) return;
  let length = str.length;
  let index = 0;
  let array = []
  while(index < length){
    array.push(str.substring(index,index+2));
     index = index + 2;
  }
  val = array.join(",");
  // 将16进制转化为ArrayBuffer
  return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) {
    return parseInt(h, 16)
  })).buffer
},

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

你可能感兴趣的:(微信小程序,微信小程序,前端)