关于微信小程序蓝牙连接 真实记录

1. 蓝牙初始化

searchDevice: function() {
     var that = this
    //蓝牙是否初始化
    wx.openBluetoothAdapter({
      success: function(res) {
        that.getBluetoothState();//获取本机蓝牙适配器状态
      },
      fail: function(res) {
        if (res.errCode != 0) {
        //自定义报错
          initTypes(res.errCode, res.errMsg)
        }
      }
    })
  },

2. 获取本机蓝牙适配器状态

getBluetoothState: function() {
    var that = this
    wx.getBluetoothAdapterState({
      success: function(res) {
        console.log("适配器初始化成功")
        that.findBleDevices();
      },
      fail: function(e) {
        console.log("适配器初始化失败")
        console.log(e.errMsg)
        if (e.errCode != 0) {
          initTypes(e.errCode);
        }
      }
    })
  },

3. 蓝牙搜索

findBleDevices: function() {
    //蓝牙搜索框
    wx.showLoading({
      title: '正在搜索设备'
    });
    var that = this
    wx.startBluetoothDevicesDiscovery({
      success: function(res) {
        that.onBluetoothDeviceFound()
      },
      fail: function(res) {
        console.log(res.errMsg)
        if (res.errCode != 0) {
          initTypes(res.errCode)
        }
      }
    })
  },

4. 发现外围设备

onBluetoothDeviceFound: function() {
    var that = this
    wx.onBluetoothDeviceFound(function(res) {
      console.log('开始监听寻找到新设备的事件');
      that.getBluetoothDevices()
    })
  },

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

getBluetoothDevices: function() {
    var that = this
    wx.getBluetoothDevices({
      success: function(res) {
        console.log('获取蓝牙设备成功:' + res.errMsg);
        console.log(res.devices);
        that.clearOtherDevices(res);
      },
      fail: function(res) {
        console.log('获取蓝牙设备错误,错误码:' + res.errMsg);
        if (res.errCode != 0) {
          initTypes(res.errCode);
        }
      }
    })
  },

6. 蓝牙连接
我在连接之前做了筛选蓝牙设备名称的操作,并遍历到模块,点击模块进入该方法

createBLEConnection: function(e) {
    //获取蓝牙地址
    let deviceId = e.currentTarget.id;
    app.globalData.deviceId = deviceId;//app.js  用之前要  const app = getApp()
    var bluename = e.target.dataset.bluename;
    app.globalData.bleName = bluename;
    var that = this;
    wx.showToast({
      title: '连接蓝牙...',
      icon: 'loading',
      duration: 99999
    });
    //蓝牙连接
    wx.createBLEConnection({
      deviceId: deviceId,
      success: function(res) {
        console.log('连接蓝牙成功:' + res.errMsg);
        //停止搜索
        that.stopBluetoothDevicesDiscovery();
        wx.hideToast();
        wx.showToast({
          title: '连接成功',
          icon: 'success',
          duration: 2000
        });
        that.getBLEDeviceServices();    //获取服务
      },
      fail: function(res) {
        console.log('连接低功耗蓝牙失败,错误码:' + e.errMsg);
        if (res.errCode != 0) {
          initTypes(res.errCode);
        }
        wx.hideLoading()
      }
    })
  },

7. 停止搜索
该停就停

stopBluetoothDevicesDiscovery: function() {
    wx.stopBluetoothDevicesDiscovery({
      success: function(res) {
        console.log('停止搜索蓝牙设备:' + res.errMsg);
      },
      fail: function(res) {
        console.log('停止搜索蓝牙设备失败,错误码:' + res.errMsg);
        if (res.errCode != 0) {
          initTypes(res.errCode);
        }
      }
    })
  },

8. 获取服务

getBLEDeviceServices: function() {
    let services = [];
    let serviceId = null;
    var that = this;
    wx.getBLEDeviceServices({
      deviceId: app.globalData.deviceId,
      success: function(res) {
        console.log('获取设备服务成功:' + res.errMsg);
        console.log(res.services)
        services = res.services;
        if (services.length <= 0) {
          toast('获取服务失败,请重试!');
          return
        }
        //循环获取serviceId
        for (var x in services) { //x = index
          if (services[x].uuid.indexOf("6E400001") >= 0) {
            //找到有效的UUID  
            app.globalData.serviceId = services[x].uuid;
            that.getBLEDeviceCharacteristics();
            break;
          }
        }
      },
      fail: function(res) {
        console.log('获取设备服务失败,错误码:' + res.errMsg);
        if (res.errCode != 0) {
          initTypes(res.errCode);
        }
      }
    })
  },

9.获取某个服务下的所有特征值

getBLEDeviceCharacteristics: function() {
    var charactArray = [];
    var that = this;
    wx.getBLEDeviceCharacteristics({
      deviceId: app.globalData.deviceId,
      serviceId: app.globalData.serviceId,  //这个是上面那个UUID
      success: function(res) {
        console.log('获取特征值成功:' + res.errMsg);
        console.log(res);
        charactArray = res.characteristics;
        if (charactArray.length <= 0) {
          toast('获取特征值失败,请重试!');
          return;
        }
        //charactArray  也就是  res.characteristics 这个里面有能读数据的 能写数据的 要分着用
        for (var x in charactArray) {
          //写数据   
          if (charactArray[x].properties.write) {
            app.globalData.characteristicWriteId = charactArray[x].uuid
          }
          //读数据
          if (charactArray[x].properties.notify) {
            app.globalData.characteristicNotifyId = charactArray[x].uuid
          }
        }
        //连接成功后设备列表隐藏  与连接蓝牙无关 我自己的操作
        that.setData({
          blueornot: true,
          list: null,
          bluename: app.globalData.bleName
        })
        //开始读取数据
        that.notifyBLECharacteristicValueChange();
      },
      fail: function(res) {
        console.log('获取特征值失败,错误码:' + res.errCode);
        if (res.errCode != 0) {
          initTypes(res.errCode);
        }
      }
    })
  },

10.读数据
订阅操作成功后需要设备主动更新特征值的 value,才会触发 wx.onBLECharacteristicValueChange 回调。

notifyBLECharacteristicValueChange: function() { 
    var that = this
    wx.notifyBLECharacteristicValueChange({
      deviceId: app.globalData.deviceId,
      serviceId: app.globalData.serviceId,
      characteristicId: app.globalData.characteristicNotifyId, 
      //这个characteristicId是上面9方法存的能读数据的uuid
      state: true,
      success: function(res) {
        console.log('notifyBLECharacteristicValueChange success:' + res.errMsg);
        console.log(JSON.stringify(res));
        that.onBLECharacteristicValueChange();
      },
    })
  },

11.监听蓝牙特征值变化
监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。

onBLECharacteristicValueChange: function() {
    var that = this;
    wx.onBLECharacteristicValueChange(function(res) {
      console.log('监听低功耗蓝牙设备的特征值变化事件成功');
      console.log(ab2hex(res.value));
      that.onBleDataAnalysic(ab2hex(res.value));
    })
  },

12.蓝牙写数据
传值给蓝牙指令

writeBLECharacteristicValue: function(buffer) {
    wx.writeBLECharacteristicValue({
      deviceId: app.globalData.deviceId,
      serviceId: app.globalData.serviceId,
      characteristicId: app.globalData.characteristicWriteId,
      //characteristicId:9方法中存的能写数据的UUID
      value: buffer,
      //value : 根据通信协议你要给蓝牙传的值 
      success: function(res) {
        console.log("发送指令成功")
      },
      fail: function(res) {
        console.log("发送指令失败" + res.errMsg)
      }
    })
  },

13.可能用到数据处理值方法
(1) 16进制转10进制

function hex2dex(str) {
  return parseInt(str, 16).toString(10)
}

(2)十六进制转ASCII码

function hexCharCodeToStr(hexCharCodeStr) {
  var trimedStr = hexCharCodeStr.trim();
  var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
  var len = rawStr.length;
  if (len % 2 !== 0) {
    alert("存在非法字符!");
    return "";
  }
  var curCharCode;
  var resultStr = [];
  for (var i = 0; i < len; i = i + 2) {
    curCharCode = parseInt(rawStr.substr(i, 2), 16);
    resultStr.push(String.fromCharCode(curCharCode));
  }
  return resultStr.join("");
}

(3)ArrayBuffer转16进度字符串示例

function ab2hex(buffer) {
  const hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function(bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('')
}

(4)字符串转为ArrayBuffer对象
参数为字符串

function str2ab(str) {
  var buf = new ArrayBuffer(str.length / 2);
  var bufView = new Uint8Array(buf);
  for (var i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = parseInt(str.slice(i * 2, i * 2 + 2),16);
  }
  return buf;
}

(5)buffer(这个是我最终传给蓝牙的值 也就是写数据方法中的value)

function systemCommand(){
  let buffer = new ArrayBuffer(5);
  //5 是位 
  let dataView = new DataView(buffer);
  dataView.setUint8(0, 0x05);
  //第一位  是  0x05
  dataView.setUint8(1, 0x02);
  //第二位  是  0x02     new ArrayBuffer(5);  有多少位写多少 dataView.setUint8(位,值)
  return buffer;
}