微信小程序——藍牙應用小結

前言

經過幾個月的時間,斷斷續續的修改,終於完成了個人的第一個微信藍牙小程序,僅此做一個小結。

一、知識儲備

1.微信小程序API

藍牙部分的API可以到微信公衆平臺去找,都是官方文件。Android 從微信 6.5.7 開始支持藍牙程序,iOS 從微信 6.5.6 開始支持。

之前自己稍微整理過一個流程。

藍牙流程

2.BLE 4.0

 

BLE 4.0是現在流行的一種藍牙傳輸協議,其中 BLE 是 Bluetooth Low Energy 低功耗藍牙的簡寫。整個協議我也只是一知半解,就講點在應用過程中瞭解的東西。其餘大家感興趣可以直接搜索下。

先明確幾個概念:(個人理解,有問題歡迎指出)

MAC地址:(Media Access Control Address)藍牙設備的物理地址,每個設備只有一個唯一值。

UUID:(Universally Unique Identifier)通用唯一識別碼,一種軟件識別碼,一個設備中可以有  多個UUID,一個UUID對應一個軟件服務部分。

服務(service):有關特徵值的收集,用來操作特定功能,所以一個服務裏可以有多個特徵值。例如,“體溫計”服務包括一個溫度測量值,以及測量的時間間隔。

特徵值(characteristic):在藍牙設備之間傳遞的數據值,例如當前溫度測量值。

 

服務、特徵稱爲屬性(attributes),並以UUID標識。實現者可能會爲所用的專有格式挑選一個隨機或僞隨機UUID,但藍牙技術聯盟已預留一系列UUID(範圍xxxxxxxx-0000-1000-8000-00805F9B34FB))供標準屬性使用。

所以可以理解爲:

MAC地址:一個人的名字。

服務:一個人做了一件事情。

特徵性:考覈這件事情的幾個指標。

UIDD:用一串數字和字母表示事情或指標。

 

這些理解了,還要了解一下BLE 4.0和傳統藍牙的不同,在單模情況下無法通用傳統藍牙的設備。所以開發小程序前,你要了解你的手機和要連接的藍牙設備是否能滿足BLE 4.0的要求,否則硬件基礎都不支持,談何軟件實現。

3.vConsole

這是微信自帶一個真機調試工具,因爲藍牙程序部分無法在“微信web開發者工具”中仿真調試,需要大量的真機調試,所以好好應用vConsole,在後續的開發中至關重要。

vConsole簡要介紹

二、開發過程中的磕磕碰碰

1.console.log先打出錯誤信息

最開始按照藍牙流程編寫完小程序後,總是遇到各種錯誤,一個頭兩個大。

後來就在每段程序里加入:

console.log('連接藍牙:', res.errMsg + res.errCode);

將全部錯誤信息打印出來和下表對比,就慢慢有了方向。

錯誤信息部分截圖

2.不行就加延遲

如果在使用多個藍牙API且有先後或者參數傳遞關係,請加入適當延遲。

沒有加延遲的後果是前一個API還沒執行完成,後一個API就在執行了,這樣後一個API缺少了一些必要的準備或參數。

vConsole中表現出兩種情況,1中間狀態的參數未賦值,2錯誤提示前一個API操作的結果出錯

以wx.getBLEDeviceServices和wx.getBLEDeviceCharacteristics爲例,兩者之間有參數傳遞關係,所以需要延長。

wx.getBLEDeviceServices({
          deviceId: that.data.connectedDeviceId,
          success: function(res) {
            for (let i = 0; i < res.services.length; i++) {
              if (res.services[i].uuid.toUpperCase().indexOf("FFE0") != -1) {
                that.setData({
                  serviceUUID: res.services[i].uuid,
                }) 
                console.log("UUID1:" + that.data.serviceUUID);
                break;
              }
            } 
          },
          fail: function (res) {
          }
        })
        setTimeout(function () {
        wx.getBLEDeviceCharacteristics({
          deviceId: that.data.connectedDeviceId,
          serviceId: that.data.serviceUUID,
          success: function(res) {
            console.log('成功2:', res.errMsg + res.errCode);
            var notify_id, write_id, read_id;
            for (let i = 0; i < res.characteristics.length; i++) {
              if (res.characteristics[i].properties.notify) {
                notify_id = res.characteristics[i].uuid;
              }
              if (res.characteristics[i].properties.write) {
                write_id = res.characteristics[i].uuid;
              }
              if (res.characteristics[i].properties.read) {
                read_id = res.characteristics[i].uuid;
              }
            }
            that.setData({
              characteristicId_notify: notify_id,
              characteristicId_write: write_id,
              characteristicId_read: read_id,
            })  
          },
          fail: function (res) {
          }
        })
        }, 1000)//添加延遲

3.爲什麼iPhone比較難連

就一個原因iPhone比較矯情。

使用iPhone時,就算你知道服務的UUID和特徵值的UUID,與必須通過wx.getBLEDeviceServices和wx.getBLEDeviceCharacteristics兩個API獲得。就是上面寫道那段代碼。

服務的UUID和特徵值的UUID,iPhone只識別大寫字母,安卓大小寫沒關係。

安卓和iPhone還有一個不同點: Android 上獲取到的deviceId爲設備 MAC 地址,iOS 上則爲設備的 UUID。但是在實際應用中僅發現deviceId這個值不同,會影響界面佈局,其他倒是沒什麼感覺。

最後在梳理下安卓和iPhone的連接過程:

安卓:

wx.getBluetoothDevices——獲得MAC地址(deviceId)

wx.createBLEConnection——通過MAC地址創建連接

wx.getBLEDeviceServices——獲得服務的UUID(ServicesId)如果已知ServicesId,可將ServicesId設置爲常量,省略該步驟。

wx.getBLEDeviceCharacteristics——獲得特徵值的UUID(CharacteristicsId)如果已知CharacteristicsId,可將CharacteristicsId設置爲常量,省略該步驟。

wx.notifyBLECharacteristicValueChanged——通過deviceId、ServicesId、CharacteristicsId啓動notify模式

 

iPhone:

wx.getBluetoothDevices——獲得設備的 UUID(deviceId)

wx.createBLEConnection——通過設備的 UUID創建連接

wx.getBLEDeviceServices——獲得服務的UUID(ServicesId)不論是否已知ServicesId,都無法省略該步驟。

wx.getBLEDeviceCharacteristics——獲得特徵值的UUID(CharacteristicsId)不論是否已知CharacteristicsId,都無法省略該步驟。

wx.notifyBLECharacteristicValueChanged——通過deviceId、ServicesId、CharacteristicsId啓動notify模式

所以,當你想要兩者共用,就乖乖將wx.getBLEDeviceServices和wx.getBLEDeviceCharacteristics兩個API都寫進去。

4.如何獲得可用的服務UUID

通過wx.getBLEDeviceServices可以獲得所有服務的UUID,但是那個是你需要的?

比如我就篩選了含有“FFE0”的UUID。

 if (res.services[i].uuid.toUpperCase().indexOf("FFE0") != -1)

那麼怎麼獲得自己想要的UUID那?

我通過一個APP(在哪下載忘記了,紅框是它的logo),嘗試了哪些UUID可以使用。

APP界面

5.讀數據要用on,不能一口氣讀寫太多

比較坑的一點,讀取數據建議使用wx.onBLECharacteristicValueChange。

讀寫操作的buffer是有大小限制,印象中是20個字節大小,如果你沒有分段存儲,就只能讀取到頭20個字節。

大於 20 字節只能分包發送或讀取。微信小程序提供的 API 中沒有自動分包的功能,這就只能自己手動分包了。

6.關於波特率

暫時微信還沒有提供設置藍牙設備波特率的API,但是通過手機連接測試,波特率在9600-57600之間都可以連接。

後記

我已從坑中爬出,寫下此文,希望他人能爬的快點,哈哈哈哈!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章