微信小程序BLE踩坑記錄

小程序BLE踩坑記錄

前往官方文檔javascript

項目描述

手機小程序經過BLE向android設備發送WIFI名稱/密碼等信息,設備收到後自動聯網。html

項目流程

設備首先添加自定義服務UUID和特徵UUID。java

用戶預先鏈接WiFi、自動獲取當前WiFi名稱、用戶填寫當前WiFi密碼、android

初始化藍牙、掃描BLE、獲取掃描到的設備、點擊鏈接BLE設備、獲取該設備的全部服務UUID、git

獲取目標服務UUID的全部特徵值、根據設備ID,特定服務UUID,特定特徵值UUID寫入數據。github

寫入數據特殊部分
  • IOS:不須要分包發送,發送數據無限制,數據多傳送時間削微變長。
  • Android:單次最大發送20字節,因此須要分包發送,且須要本身實現。
踩坑記錄
  • 掃描

掃描成功後,不要立馬調用中止掃描,否則在遠程調試的時候一切正常,預覽或者發佈以後顯示搜索到的結果列表長度爲0。小程序

  • 獲取掃描結果

該項目掃描場景是已進入頁面自動掃描,測試時wx.getBluetoothDevices每次都是一進入時搜不到,點擊從新掃描即可以立馬搜索到。建議使用wx.onBluetoothDeviceFound獲取掃描結果,但須要自行去重和過濾。掃描時間持續比較長,能夠在點擊鏈接時先用wx.stopBluetoothDevicesDiscovery中止掃描。api

//去重及過濾
wx.onBluetoothDeviceFound(function (obj) {
  var temp = _this.data.scanDevices
  if (obj.devices[0].name) {
    obj.devices.map(dev => {
      let pDev = temp.find((it) => {
        return it.deviceId == dev.deviceId
      })
      if (!pDev) {
        temp.push(dev)
      }
    })
  }
  _this.setData({
    scanDevices: temp
  })
})
複製代碼
  • 鏈接設備

遇到過鏈接一直操做超時,errCode10003,這裏的緣由不少,官方的討論也不少,這裏我重啓了一次設備就行了,所以多是設備問題,也多是鏈接實例太多致使,最好發送完數據後用wx.closeBLEConnection關閉鏈接。數組

  • 寫數據

寫數據是須要用到deviceId,serviceUUID,characteristicUUID,這三個值都必須經過Api獲取,我試過不走Api,直接填入serviceUUID,characteristicUUID,結果寫入失敗。也多是大小寫和分隔符「-」的問題,不過最好是經過Api去拿值。還有,發送的數據須要轉爲ArrayBuffer格式。ide

//字符串轉ArrayBuffer
char2buf(str) {
  var out = new ArrayBuffer(str.length)
  var u8a = new Uint8Array(out)
  var strs = str.split("")
  for (var i = 0; i < strs.length; i++) {
    u8a[i] = strs[i].charCodeAt()
  }
  return out
}
複製代碼
  • 分包

總體思路爲:

將發送的數據分爲多條數據,保存到一個全局數組中,循環發送每一條數據,發送一條後在發送成功的回調中進行下一條數據發送,若其中一條失敗,則從頭從新開始。這裏發送用的遞歸。特別注意的是,android每次發送後必須延時一段時間再發送下一條數據,否則會寫入失敗,推薦延時250ms。

一個包數據爲20字節,但實際上單次可供發送的只有18字節,因此按照18去分包。

還須要對數據進行分割,這裏每種數據使用||分割,使用#end做爲結束標識符。設備監測到有此標識符則開始聯網。

//遞歸
writeData: function (devId, serviceId, charaId) {
    var _this = this
    if (_this.data.sendNum >= _this.data.sendDataList.length) {
      wx.closeBLEConnection({
        deviceId: devId,
        success: function (res) {
          console.log(res)
        }
      })
      wx.hideLoading()
      wx.showToast({
        title: '發送成功',
        icon: 'success',
        duration: 2000
      })
      return
    }
    wx.writeBLECharacteristicValue({
      deviceId: devId,
      serviceId: serviceId,
      characteristicId: charaId,
      value: _this.data.sendDataList[_this.data.sendNum],
      success: function (res) {
        console.log('寫入成功', res.errMsg)
        setTimeout(function () {
          _this.data.sendNum++
          console.log(_this.data.sendNum)
          _this.writeData(devId, serviceId, charaId)
        }, 250)
      },
      fail: function (res) {
        console.log(res)
        _this.setData({
          sendNum: 0
        })
      }
    })
  }
複製代碼

完整BLE代碼

實際上#end和||分割存在bug,若數據中含有此類字符會致使設備端接收數據錯誤。此處再也不深究。

項目地址

相關文章
相關標籤/搜索