微信小程序连接蓝牙血压仪

微信小程序连接蓝牙血压仪

### 小程序连接血压仪是通过蓝牙进行通信

### 此款血压仪是通过indicate服务进行数据通信

##### 小程序通过监听蓝牙设备特征值的变化进行读取数据

具体操作直接上代码:

  1. 微信小程序需要首先打开蓝牙适配器 wx.openBluetoothAdapter
wx.openBluetoothAdapter({
  success: function (res) {
    console.log(res)
  },
  fail: function (res) {
      wx.showModal({
           content: '请开启手机蓝牙后再试'
       })
   }
}) 

此方法可以检测中心设备是否支持蓝牙功能,是否打开蓝牙开关,如不符合上述条件,返回失败建wx.openBluetoothAdapter(OBJECT)和wx.closeBluetoothAdapter(OBJECT)成对使用wx.closeBluetoothAdapter:关闭蓝牙模块,使其进入未初始化状态。调用该方法将断开所有已建立的链接并释放系统资源;

2.搜索指定设备
wx.startBluetoothDevicesDiscovery(OBJECT)开始搜寻附近的蓝牙外围设备
wx.getBluetoothDevices(OBJECT)获取在小程序蓝牙模块生效期间所有已发现的蓝牙设备
wx.onBluetoothDeviceFound(CALLBACK) 监听寻找到新设备的事件

注意: 搜索蓝牙wx.startBluetoothDevicesDiscovery(OBJECT)操作比较耗费系统资源,在搜索并连接到设备后调用 wx.stopBluetoothDevicesDiscovery(OBJECT) 方法停止搜索。

startBluetoothDevicesDiscovery() {
    if (this._discoveryStarted) {
      return
    }
    this._discoveryStarted = true
    wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: true,
      success: (res) => {
        console.log('startBluetoothDevicesDiscovery success', res)
        this.onBluetoothDeviceFound()
      },
    })
  },
  stopBluetoothDevicesDiscovery() {
    wx.stopBluetoothDevicesDiscovery()
  },
  onBluetoothDeviceFound() {
    wx.onBluetoothDeviceFound((res) => {
      res.devices.forEach(device => {
        if (!device.name && !device.localName) {
          return
        }
        const foundDevices = this.data.devices
        const idx = inArray(foundDevices, 'deviceId', device.deviceId)
        const data = {}
        if (idx === -1) {
          data[`devices[${foundDevices.length}]`] = device
        } else {
          data[`devices[${idx}]`] = device
        }
        this.setData(data)
      })
    })
  },
  createBLEConnection(e) {
    const ds = e.currentTarget.dataset
    const deviceId = ds.deviceId
    const name = ds.name
    wx.createBLEConnection({
      deviceId,
      success: (res) => {
        this.setData({
          connected: true,
          name,
          deviceId,
        })
        wx.setStorageSync('deviceId',deviceId);
        // this.getBLEDeviceServices(deviceId)
      }
    })
    this.stopBluetoothDevicesDiscovery()
  },
  1. wx.setStorageSync('deviceId',deviceId); 将页面的选择的服务的UUID放入缓存中,此时我将跳转下一个页面进行定时扫描蓝牙的广播
  2. 开发者工具和 Android 上获取到的deviceId为设备 MAC 地址,iOS 上则为设备 uuid。因此deviceId不能硬编码到代码中,如何连接蓝牙搜索我们可以拿到了设备的deviceId,通过deviceId去连接蓝牙Android 上获取到的deviceId为设备 MAC 地址,iOS 上获取到的deviceId则为设备 uuid,因此deviceId不能硬编码到代码中,那么可能就有机智的小伙伴说了,设置两个变量,一个为设备MAC,一个为设备uuid,在连接设备的之前判断下机型,ios设备deviceId取:设备uuid,android设备deviceId:MAC地址!!!
    我原本也是这样想的,因为我们做的这个小程序是扫码连接指定设备(就好像共享单车一样),所以本来是想在二维码中直接放入mac和uuid然后连接的时候去根据机型去取对应值
    但是!!!但是!!!但是!!!
    在实现过程中发现,ios不同手机搜索到的设备deviceId还是不同的.所以还是乖乖通过设备name(广播名),去获取deviceId去连接

正确的流程是
初始化蓝牙wx.openBluetoothAdapter(OBJECT)

开始搜索蓝牙 wx.startBluetoothDevicesDiscovery(OBJECT)

所有已发现的蓝牙设备wx.getBluetoothDevices(OBJECT)

监听寻找到新设备的事件wx.onBluetoothDeviceFound(CALLBACK)

连接低功耗蓝牙设备wx.createBLEConnection(OBJECT)

获取蓝牙设备所有 service(服务) wx.getBLEDeviceServices(OBJECT)

获取蓝牙设备某个服务中的所有 characteristic(特征值)wx.getBLEDeviceCharacteristics(OBJECT)

启用低功耗蓝牙设备特征值变化时的 notify 功能wx.notifyBLECharacteristicValueChange(OBJECT)

写入wx.writeBLECharacteristicValue(OBJECT)

    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function (options) {
        var that=this;
        that.setData({
                //动态压力值
                pressure: "",
                //收缩压
                SYS: "",
                //舒张压
                DIA: "",
                //脉搏
                PUL: ""
        })

    },
 pickUpOnce:function(){
        let that=this;
        let deviceId=wx.getStorageSync('deviceId');
        console.log("deviceId的值"+deviceId);
        that.data.inter=setInterval(function() {
            console.log('doSomething')
            wx.createBLEConnection({
                deviceId,
                success: (res) => {
                  that.getBLEDeviceServices(deviceId)
                }
              })
         }, 5000);
   
    },
  endInter:function(){
            var that =this;
            clearInterval(that.data.inter);
    },
 getBLEDeviceServices(deviceId) {
        wx.getBLEDeviceServices({
          deviceId,
          success: (res) => {
            for (let i = 0; i < res.services.length; i++) {
              if (res.services[i].isPrimary) {
                this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
                return
              }
            }
          }
        })
      },
      getBLEDeviceCharacteristics(deviceId, serviceId) {
        let self = this;
        console.log(deviceId,serviceId)
        wx.getBLEDeviceCharacteristics({
          deviceId,
          serviceId,
          success: (res) => {
            console.log('getBLEDeviceCharacteristics success', res.characteristics)
            console.log('获取服务的信息包括特征值', res)
            for (let i = 0; i < res.characteristics.length; i++) {
              let item = res.characteristics[i]
              if (item.properties.notify || item.properties.indicate) { 
                console.log(item.uuid)
              
                wx.notifyBLECharacteristicValueChange({
                  deviceId: deviceId,
                  serviceId: serviceId ,
                  characteristicId: item.uuid,
                  state: true,
                      success: (res) => {  
                            wx.onBLECharacteristicValueChange(function(res) {
                            console.log("ab2hex方法执行之前的value="+res.value);
                                var value = ab2hex(res.value);
                                console.log("ab2hex方法执行之后的value="+value);
                                // if (value.length === 14){
                                //  let result = parseInt(value.slice(10, 12), 16);
                                //  console.log("动态压力值:" + result);
                                //  // this.measureResult[0].pressure = result;
                                // }
                                if (value.length === 36){
                                    let sys = parseInt(value.slice(2, 4), 16);
                                    let dia = parseInt(value.slice(5, 8), 16);
                                    let pul = parseInt(value.slice(28, 30), 16);
                                    console.log("高压值 SYS:" + sys);
                                    console.log("低压值 DIA:" + dia);
                                    console.log("脉搏值 PUL:" + pul);
                                    if(value.substring(2,4)==="ff"){
                                        self.setData({
                                            //收缩压
                                            SYS: 'ERR',
                                            //舒张压
                                            DIA: 'ERR',
                                            //脉搏
                                            PUL: 'ERR'
                                                         })
                                    }else{
                                        self.setData({
                                            //收缩压
                                            SYS: sys,
                                            //舒张压
                                            DIA: dia,
                                            //脉搏
                                            PUL: pul
                                                         })
                                    }
                                    
                                    
                                }
                                console.log("----------------------------------------------");
                            });
      
                    } 
                })
              }
            }   
          },
// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
    var hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
    return hexArr.join('');
  }

你可能感兴趣的:(微信小程序连接蓝牙血压仪)