微信小程序-藍牙鏈接

最近的項目須要使用小程序的藍牙功能與硬件設備進行鏈接相互傳送數據指令,聯調過程當中發現一些問題,因而想着記錄下來,方便之後查看!小程序

1.0通常使用藍牙功能確定是想鏈接某一個藍牙設備,因此須要知道這個藍牙設備的名稱,通常來講都是掃描二維碼鏈接,那麼當你掃描這個設備二維碼的時候,就須要去初始化你手機上的藍牙模塊了微信小程序

/**
   * 初始化藍牙設備
   */
  initBlue:function(){
    var that = this;
    wx.openBluetoothAdapter({//調用微信小程序api 打開藍牙適配器接口
      success: function (res) {
        // console.log(res)
        wx.showToast({
          title: '初始化成功',
          icon: 'success',
          duration: 800
        })
        that.findBlue();//2.0
      },
      fail: function (res) {//若是手機上的藍牙沒有打開,能夠提醒用戶
        wx.showToast({
          title: '請開啓藍牙',
          icon: 'fails',
          duration: 1000
        })
      }
    })
  },
 

 

2.0 手機藍牙初始化成功以後,就會去搜索周邊的藍牙設備
 
/**
  *開始搜索藍牙設備
*/
findBlue(){
    var that = this
    wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: false,
      interval: 0,
      success: function (res) {
       
        wx.showLoading({
          title: '正在搜索設備',
        })
        that.getBlue()//3.0
      }
    })
  },

 

3.0搜索藍牙設備以後,須要獲取搜索到的藍牙設備信息,微信小程序提供了兩個方法能夠獲取搜索到的藍牙設備信息,分別是:api

  wx.onBluetoothDeviceFound(監聽尋找到新設備的事件 ——表示只要找到一個新的藍牙設備就會調用一次該方法)服務器

  wx.getBluetoothDevices(獲取在藍牙模塊生效期間全部已發現的藍牙設備。包括已經和本機處於鏈接狀態的設備)微信

看兩個方法的介紹咱們知道他們的區別,可是不瞭解他們的區別會形成什麼樣的問題?網絡

第一次我使用的是wx.onBluetoothDeviceFound方法進行聯調,發現一切正常,因爲調試的時候就只有一臺設備,發現第二次從新掃碼這個藍牙設備的時候,找不到這個設備了,由於對這個方法來講,這不是一個新的設備,之前鏈接上過;或者當你由於某些緣由藍牙傳送數據指令的時候出錯了須要從新鏈接,再次鏈接的時候也找不到當前設備,仍是一樣的緣由,由於當前設備對這個方法來講不是一個新設備ide

因此後來我就用了wx.getBluetoothDevices方法網站

/**
  * 獲取搜索到的設備信息
 */
  getBlue(){
    var that = this
    wx.getBluetoothDevices({
      success: function(res) {
        wx.hideLoading();
        for (var i = 0; i < res.devices.length; i++){
   //that.data.inputValue:表示的是須要鏈接的藍牙設備ID,簡單點來講就是我想要鏈接這個藍牙設備,因此我去遍歷我搜索到的藍牙設備中是否有這個ID
          if (res.devices[i].name == that.data.inputValue || res.devices[i].localName == that.data.inputValue){
            that.setData({
              deviceId: res.devices[i].deviceId,
              consoleLog: "設備:" + res.devices[i].deviceId,
            })
            that.connetBlue(res.devices[i].deviceId);//4.0
            return;
          }
        }
      },
      fail: function(){
        console.log("搜索藍牙設備失敗")
      }
    })
  },

 

 
4.0經過3.0步驟找到這個藍牙以後,經過藍牙設備的id進行藍牙鏈接
/**
  * 獲取到設備以後鏈接藍牙設備
 */
  connetBlue(deviceId){                    
    var that = this;
    wx.createBLEConnection({
      // 這裏的 deviceId 須要已經經過 createBLEConnection 與對應設備創建連接
      deviceId: deviceId,//設備id
      success: function (res) {
        wx.showToast({
          title: '鏈接成功',
          icon: 'fails',
          duration: 800
        })
        console.log("鏈接藍牙成功!")
        wx.stopBluetoothDevicesDiscovery({
          success: function (res) {
            console.log('鏈接藍牙成功以後關閉藍牙搜索');
          }
        })
        that.getServiceId()//5.0
      }
    })
  },

 

 
5.0鏈接上須要的藍牙設備以後,獲取這個藍牙設備的服務uuid
getServiceId(){
    var that = this
    wx.getBLEDeviceServices({
      // 這裏的 deviceId 須要已經經過 createBLEConnection 與對應設備創建連接
      deviceId: that.data.deviceId,
      success: function (res) {
        var model = res.services[0]
        that.setData({
          services: model.uuid
        })
        that.getCharacteId()//6.0
      }
    })
  },

 

 
6.0若是一個藍牙設備須要進行數據的寫入以及數據傳輸,就必須具備某些特徵值,因此經過上面步驟獲取的id能夠查看當前藍牙設備的特徵值
getCharacteId(){
    var that = this 
    wx.getBLEDeviceCharacteristics({
      // 這裏的 deviceId 須要已經經過 createBLEConnection 與對應設備創建連接
      deviceId: that.data.deviceId,
      // 這裏的 serviceId 須要在上面的 getBLEDeviceServices 接口中獲取
      serviceId: that.data.services,
      success: function (res) {
        for (var i = 0; i < res.characteristics.length; i++) {//2個值
          var model = res.characteristics[i]
          if (model.properties.notify == true) {
            that.setData({
              notifyId: model.uuid//監聽的值
            })
            that.startNotice(model.uuid)//7.0
          }
          if (model.properties.write == true){
            that.setData({
              writeId: model.uuid//用來寫入的值
            })
          }
        }
      }
    })
  },

 

 
7.0
startNotice(uuid){
    var that = this;
    wx.notifyBLECharacteristicValueChange({
      state: true, // 啓用 notify 功能
      // 這裏的 deviceId 須要已經經過 createBLEConnection 與對應設備創建連接 
      deviceId: that.data.deviceId,
      // 這裏的 serviceId 須要在上面的 getBLEDeviceServices 接口中獲取
      serviceId: that.data.services,
      // 這裏的 characteristicId 須要在上面的 getBLEDeviceCharacteristics 接口中獲取
      characteristicId: uuid,  //第一步 開啓監聽 notityid  第二步發送指令 write
      success: function (res) {
      
          // 設備返回的方法
          wx.onBLECharacteristicValueChange(function (res) {
              // 此時能夠拿到藍牙設備返回來的數據是一個ArrayBuffer類型數據,因此須要經過一個方法轉換成字符串
              var nonceId = that.ab2hex(res.value) 
      //拿到這個值後,確定要去後臺請求服務(當前步驟根據當前需求本身書寫),獲取下一步操做指令寫入到藍牙設備上去
      
     wx.request({
                    method: "POST",
         
                    data: {
                      xx:nonceId
                    },
                    url: url,
                    success: (res) => {
                      //res.data.data.ciphertext:我這邊服務返回來的是16進制的字符串,藍牙設備是接收不到當前格式的數據的,須要轉換成ArrayBuffer
                      that.sendMy(that.string2buffer(res.data.data.ciphertext))//8.0
                      // 服務器返回一個命令  咱們要把這個命令寫入藍牙設備
                    }
                   })
  }
    })
  },

 

 
8.0 將從後臺服務獲取的指令寫入到藍牙設備當中
sendMy(buffer){
    var that = this 
    wx.writeBLECharacteristicValue({
      // 這裏的 deviceId 須要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中獲取
      deviceId: that.data.deviceId,
      // 這裏的 serviceId 須要在上面的 getBLEDeviceServices 接口中獲取
      serviceId: that.data.services,
      // 這裏的 characteristicId 須要在上面的 getBLEDeviceCharacteristics 接口中獲取
      characteristicId: that.data.writeId,//第二步寫入的特徵值
      // 這裏的value是ArrayBuffer類型
      value: buffer,
      success: function (res) {
        console.log("寫入成功")
      },
      fail: function () {
        console.log('寫入失敗')
      },
      complete:function(){
        console.log("調用結束");
      }
    })
  },

 

 
//ps:下面是須要使用到的兩個格式相互轉換的方法
/**
* 將字符串轉換成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('');
  },
 

 

 
//PS:以上是藍牙鏈接的所有流程,可是咱們在實際使用中確定不會這麼順暢,並且藍牙發送指令的設備都會有一個特性,就是當前藍牙設備有人鏈接上以後,其餘人是搜索不到這個藍牙設備的,因此你須要考慮在某些個特殊狀況,代碼裏須要主動斷開藍牙鏈接把設備釋放出來供其餘用戶使用,還有就是將指令寫入藍牙設備的時候很容易出問題,因此要寫個回調去屢次寫入,保證成功性!第一次寫博客,不正確的地方,歡迎你們討論,謝謝!
 
有些人會用小程序藍牙功能去連接另外的手機藍牙,可是發現搜索不到藍牙信息,因此說明一下:微信小程序官方文檔上說:支持低功耗藍牙設備

BLE低功耗藍牙具備如下要求的應用:ui

1.通訊距離長達100米左右。不少低功耗藍牙須要使用鈕釦電池運行。不少的物聯網設備須要使用標準鈕釦電池運行不少年。BLE低功耗藍牙可實現超低的峯值、均衡和空閒模式的功耗。另外,低佔空比設備還能節省更多電能。this

2.多智能廠商互操做性。做爲一個標準協議,BLE低功耗藍牙與此前的藍牙版本同樣,也獲得了主設備製造商的普遍採用。也有不少的物聯網從設備也支持BLE低功耗藍牙。安卓、iOS、Windows 十、Linux等主流操做系統均原生支持BLE低功耗藍牙。預測,到2020年,95%的智能手機都將支持BLE低功耗藍牙。而這個生態系統將有助於實現多廠商互操做性。

3.BLE低功耗藍牙是搭建集體、家庭、我的網絡的最佳選擇,可經過無線方式將供電型智能設備鏈接至手機或計算機。所以,愈來愈多的智能穿戴設備、計算機/手機外設和醫療監測設備將BLE低功耗藍牙視爲了首選通訊協議。在藍牙技術聯盟的網站上也列出了不少不一樣支持智能藍牙協議的產品和藍牙智能設備產品。這直接代表了BLE低功耗藍牙通訊協議在物聯網應用領域的重要性。

相關文章
相關標籤/搜索