【微信小程序】BLE蓝牙控制

微信小程序的BLE蓝牙控制小结

0x00 微信文档

    -  官方文档链接 

0x01 微信BLE蓝牙控制流程

    - 初始化蓝牙设备 

    wx.openBluetoothAdapter({
      success (res) {
        console.log(res)
        // 初始化成功,检索设别
        this.startBlueToothDiscovery();
      },
      fail (res) {
        console.log(res)
        Toast.fail('蓝牙设备启动异常,请检查是否开启蓝牙或者微信是否有使用蓝牙的权限');
      }
    })

    - 寻找附近的蓝牙设备  

    wx.startBluetoothDevicesDiscovery({
      services: ['FEE3'],//匹配只有主服务为FEE3的设备,减少判断数量
      success (res) {
        console.log(res)
        // 在这里面判断是否自己需要的蓝牙设备,根据自己实际需要修改位置
        var operate_mac = this.data.operate_mac
        var mac= that.buf2hex(res.devices[0].advertisData).substr(4, 12).toUpperCase();
        if ( mac = defined_mac ){
            // 匹配到己方的设备,停止搜索,尝试连接己方设备
            wx.stopBluetoothDevicesDiscovery({
               success(res) {
                  console.log("停止匹配附近设备");
                  this.startLinkBluetooth()
               }
            })

        }else{
            // 匹配不到己方设备
            console.log('匹配失败,继续匹配');
        }
        //
    }})

    创建蓝牙链接

    wx.createBLEConnection({
      deviceId : this.data.operate_mac,
      success (res) {
        console.log(res)
        // 链接成功,开始获取设备的服务 service_id 
        this.getBlueToothServices();
      },
      fail (res) {
          console.log('蓝牙链接失败');
          Toast.fail('设备链接失败');
      }
    })

    -  获取蓝牙服务列表

    wx.getBLEDeviceServices({
      deviceId : this.data.operate_mac,
      success (res) {
          var all_UUID = service.services;
          // 开始获取设备的特征值 characteristics
          this.getBlueToothCharacteristics();
          console.log('device services:', res.services)
      }})

    -  获取蓝牙服务中的特征值

    wx.getBLEDeviceCharacteristics({
      deviceId : this.data.operate_mac,
      serviceId : this.data.service_id,
      success (res) {
        that.setData({
            characteristics: res.characteristics, //需确定要的使能UUID
        });
        console.log('device getBLEDeviceCharacteristics:', res.characteristics)
      }})

    - 【可选流程】监听回调数据

    1.监听数据必须先开启notify功能,才能监听到蓝牙设备发送的数据
    2.如果有多个特征值需要监听,就开启多个监听事件
    wx.notifyBLECharacteristicValueChange({
      state: true, // 启用 notify 功能
      deviceId : this.data.operate_mac,
      serviceId : this.data.service_id,
      characteristicId : this.data.characteristics[1],
      success (res) {
        console.log('notifyBLECharacteristicValueChange success', res.errMsg)
        wx.onBLECharacteristicValueChange(function(res) {
          // 蓝牙设备回调处理逻辑
          console.log(`characteristic ${res.characteristicId} has changed, now is ${res.value}`)
          console.log(buf2hex(res.value))
        })
      }
    })

    - 【可选流程】发送数据

    var that = this;
    let buffer = new ArrayBuffer(1)
    let dataView = new DataView(buffer)
    dataView.setUint8(0, 0x01)
    
    console.log("当前发送的数据:")
    for (let i = 0; i < dataView.byteLength; i++) {
        console.log("0x" + dataView.getUint8(i).toString(16))
    }
    wx.writeBLECharacteristicValue({
        deviceId : this.data.operate_mac,
        serviceId : this.data.service_id,
        characteristicId : this.data.characteristics[1],
        value: buffer,
        success: function (res) {
            console.log("success  指令发送成功");
        },
        fail: function (res) {
            console.log(res);
        }
    });
    // 安卓系统需要在写完数据后读一次,才能触发回调变化,但是苹果系统如果出现这个,会有两次回调
    wx.readBLECharacteristicValue({
        deviceId : this.data.operate_mac,
        serviceId : this.data.service_id,
        characteristicId : this.data.characteristics[1],
        success: function (res) {
            console.log('readBLECharacteristicValue: success', res)
        }
    })

0x02 微信BLE蓝牙控制的一些小细节

    - 1. 在匹配到需要的蓝牙设备后,记录好 device_mac ,然后关闭搜索功能,防止过度消耗使用者手机电量

    - 2. 蓝牙链接中常用的函数  buf2hex 将 buffer 数据转换成容易识别的16进制数据

      buf2hex: function(buffer) { // buffer is an ArrayBuffer
        return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
      }

    - 3. hex2buf 将文字数据转换成可以传送的buffer数据

      hex2buf: function(hex) {
        var count = hex.length / 2;
        let buffer = new ArrayBuffer(count);
        let dataView = new DataView(buffer);
        for (var i = 0; i < count; i++) {
          var curCharCode = parseInt(hex.substr(i * 2, 2), 16);
          dataView.setUint8(i, curCharCode);
        }
        return buffer;
      }

    - 4. 如果设备只接受ASCII编码的话,需要先将数据转成ASCII编码

      valueToASCII: function(value) {
          value_split = value.split('');
          for(var i = 0; i < value_split.length; i++) {
              value_ascii = value_ascii + value_split[i].charCodeAt().toString(16); //转为Ascii字符后连接起
          }
          return value_ascii;
      }

    - 5. 一步到位,直接将buffer数据转为string

        buf2string: function (buffer) {
            var arr = Array.prototype.map.call(new Uint8Array(buffer), x => x)
            var str = ''
            for (var i = 0; i < arr.length; i++) {
                str += String.fromCharCode(arr[i])
            }
            return str
        }


0x03 结语

    - 文档不是万能的,官方文档也不是标准的,多考虑人家如果文档写错的话,正常是什么样子的。。

    - 关于错误代码的,能BD的就不要GOOGLE,或者在搜索时加入前缀:微信小程序。

    - 蓝牙设备如果是开发状态中的,要相信自己的逻辑,坚定点,甩锅。

    - 微信的错误提示信息,参考就好,千万别一直当真,一直当真你就陷进去了。