微信小程序BLE踩坑記錄

小程序BLE踩坑記錄

前往官方文檔

項目描述

手機小程序通過BLE向android設備發(fā)送WIFI名稱/密碼等信息,設備收到后自動聯(lián)網(wǎng)。

項目流程

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

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

初始化藍牙、掃描BLE、獲取掃描到的設備、點擊連接BLE設備、獲取該設備的所有服務UUID、

獲取目標服務UUID的所有特征值、根據(jù)設備ID,特定服務UUID,特定特征值UUID寫入數(shù)據(jù)。

寫入數(shù)據(jù)特殊部分
  • IOS:不需要分包發(fā)送,發(fā)送數(shù)據(jù)無限制,數(shù)據(jù)多傳送時間削微變長。
  • Android:單次最大發(fā)送20字節(jié),所以需要分包發(fā)送,且需要自己實現(xiàn)。
踩坑記錄
  • 掃描

掃描成功后,不要立馬調(diào)用停止掃描,不然在遠程調(diào)試的時候一切正常,預覽或者發(fā)布之后顯示搜索到的結(jié)果列表長度為0。

  • 獲取掃描結(jié)果

該項目掃描場景是已進入頁面自動掃描,測試時wx.getBluetoothDevices每次都是一進入時搜不到,點擊重新掃描便可以立馬搜索到。建議使用wx.onBluetoothDeviceFound獲取掃描結(jié)果,但需要自行去重和過濾。掃描時間持續(xù)比較長,可以在點擊連接時先用wx.stopBluetoothDevicesDiscovery停止掃描。

//去重及過濾
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,這里的原因很多,官方的討論也很多,這里我重啟了一次設備就好了,因此可能是設備問題,也可能是連接實例太多導致,最好發(fā)送完數(shù)據(jù)后用wx.closeBLEConnection關閉連接。

  • 寫數(shù)據(jù)

寫數(shù)據(jù)是需要用到deviceId,serviceUUID,characteristicUUID,這三個值都必須通過Api獲取,我試過不走Api,直接填入serviceUUID,characteristicUUID,結(jié)果寫入失敗。也可能是大小寫和分隔符“-”的問題,不過最好是通過Api去拿值。還有,發(fā)送的數(shù)據(jù)需要轉(zhuǎn)為ArrayBuffer格式。

//字符串轉(zhuǎn)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
}
  • 分包

整體思路為:

將發(fā)送的數(shù)據(jù)分為多條數(shù)據(jù),保存到一個全局數(shù)組中,循環(huán)發(fā)送每一條數(shù)據(jù),發(fā)送一條后在發(fā)送成功的回調(diào)中進行下一條數(shù)據(jù)發(fā)送,若其中一條失敗,則從頭重新開始。這里發(fā)送用的遞歸。特別注意的是,android每次發(fā)送后必須延時一段時間再發(fā)送下一條數(shù)據(jù),不然會寫入失敗,推薦延時250ms。

一個包數(shù)據(jù)為20字節(jié),但實際上單次可供發(fā)送的只有18字節(jié),所以按照18去分包。

還需要對數(shù)據(jù)進行分割,這里每種數(shù)據(jù)使用||分割,使用#end作為結(jié)束標識符。設備監(jiān)測到有此標識符則開始聯(lián)網(wǎng)。

//遞歸
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: '發(fā)送成功',
        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,若數(shù)據(jù)中含有此類字符會導致設備端接收數(shù)據(jù)錯誤。此處不再深究。

項目地址

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容