關於藍牙開發,你必須知道的知識

http://geek.csdn.net/news/detail/160652

簡介

2017年1月18日,我進行了一次知乎live的活動,主題是: ”知乎live:一小時藍牙應用開發科普“,感謝微信公衆號,qq Babybluetooth開發羣的同學們參加了活動,現在活動已經結束,我把活動中語音內容整理了文字,就是下面的內容 ~

什麼是藍牙4.0, 藍牙其他標準又是什麼

低功耗藍牙(Low Energy; LE),又視爲Bluetooth Smart或藍牙核心規格4.0版本。其特點具備節能、便於採用,是藍牙技術專爲物聯網(Internet of Things; IOT)開發的技術版本。

所以它最主要的特點是低功耗,普及率高。現在所說的藍牙設備,大部分都是在說4.0設備,ble也特指4.0設備。 在4.0之前重要的版本有2.1版本-基本速率/增強數據率(BR/EDR)和3.0 高速藍牙版本,這些統稱爲經典藍牙,

4.0還有4.1101和4.2的小版本,其中4.2版本對傳輸速率做了進一步他提升,提高了2.5倍,蘋果從iphone6開始使用4.2,

圖片描述

最新的藍牙標準爲藍牙5.0

其中最大的特點連接範圍擴大了4倍,速度又提高了2倍,無連接數據廣播能力提高了8倍,增加了藍牙組網的能力。2017年纔開始有芯片出廠,我和Ti,nordic工程師有聊過,他們的5.0芯片都已經完成,準備量產。

應用側iOS,android操作系統支持的藍牙協議

蘋果從iphone4s,ipad3,pod touch 5開始支持藍牙4.0,android從4.3以上系統開始支持4.0,此外,蘋果從iphone 6開始,支持藍牙4.2協議,提高了數據傳輸速度。就如前面所說的,提高大約2.5倍。

藍牙5.0很期待,不過要普及到手機和其他智能設備上,可能還需要等上幾年。

藍牙開發必須知道的概念

central和peripheral

藍牙應用開發中,存在兩種角色,分別是central和peripheral(pə’rɪfərəl) ,中文就是中心和外設。比如手機去連接智能設備,那手機就是central,智能設備就是peripheral。大多時候都是central去連接peripheral的場景,所以我們就來說他的流程

廣播和連接

peripheral會發出廣播(advertisement:ædvɚ’taɪzmənt),central掃描到廣播後,可以對設備進行連接,發出connect請求,peripheral接收到請求後,同意連接後,central和peripheral就建立了連接。

連接後的操作

write,read,notify,indecate, response or not … 這個在後面詳細說

indecate和notify的區別就在於,indecate是一定會收到數據,notify有可能會丟失數據(不會有central收到數據的迴應),write也分爲response和noresponse,如果是response,那麼write成功回收到peripheral的確認消息,但是會降低寫入的速率。

協議

每個具體的智能設備,都約定了一組數據格式,這個就是數據協議,例如手環中獲取到數據0X001023,其中第2位到第5位表示步數,那麼就2310就是步數的16進制的數據,轉換成10進制就是8976步,需要注意的是,設備端都是小端模式,所以取4位時候,高字節在前低字節在後

藍牙應用的一般開發流程

已iOS爲例,android也和這個是類似的。

  1. 建立中心角色
  2. 掃描外設(discover)
  3. 連接外設(connect)
  4. 掃描外設中的服務和特徵(discover) 
    • 4.1 獲取外設的services
    • 4.2 獲取外設的Characteristics,獲取Characteristics的值,獲取Characteristics的Descriptor和Descriptor的值
  5. 與外設做數據交互(explore and interact)
  6. 訂閱Characteristic的通知
  7. 斷開連接(disconnect)

藍牙的數據交互

write,read,notify,indecate, response or not … 讀寫大家都是容易理解的,indecate和notify對應的是長連接,建立indecate後,peripheral可以隨時往central發送數據。

indecate和notify的區別就在於,indecate是一定會收到數據,notify有可能會丟失數據(不會有central收到數據的迴應),write也分爲response和noresponse,如果是response,那麼write成功回收到peripheral的確認消息,但是會降低寫入的速率。

對於一個charateristic,他的讀寫訂閱的權限是peripheral決定的,熟悉可以被同時設置,一般會根據外設的功能來決定。

藍牙ota DFU

藍牙ota,DFU(Device Firmware Update)指的是藍牙設備的固件升級,其實是一整套流程,不同的藍牙芯片,ota的流程有不同之處,我這裏用ti的芯片舉例。步驟爲:切系統(bootloader mode),重啓,傳輸數據,驗證數據,切系統,重啓,完成。

其中數據傳輸也會分成很多節去發送,沒法送一段數據,做一次數據校驗。

ota存在的問題

以TI的芯片舉例,他需要可以存2個image,數據傳輸時候需要的空間比較大,而每個智能設備的速率,功耗,存儲都會有很多限制,導致很多設備會自己去實現ota的功能,自定義流程和數據傳輸方式,導致許多設備都是有自己私有的ota模式和協議,所以在做開發的時候,要仔細閱讀設備協議中對ota的描述。

藍牙開發中的常見的問題和坑

應用如何做自動重連

其實自動重連比想象的要簡單許多,無論是android還是ios端,只需要在設備斷開連接的委託方法中,重新調用gatt.connet或者是centralManager.connet方法就可以了,無論當時設備是否有點,是否在周圍,當設備再次開會或者連接到可連接範圍內,都會自動被連上,就是這麼簡單。

連接失敗處理

分兩個平臺來說,iOS端也有連接失敗的委託,但是好像幾乎不會發生這種情況,至少我從來沒遇見過,而對於同款設備,android常常會出現連接失敗的情況,status != BluetoothGatt.GATT_SUCCESS ,android端開發請不要把連接失敗和斷開連接放在一塊處理,因爲斷開連接可以直接嘗試重新連接,而連接失敗後嘗試重新連接,需要加一些延時,並且需要gatt.close,清空一下狀態,否則會把gatt阻塞導致手機不重啓藍牙就再也無法連接任何設備的情況。

後臺運行

iOS後來運行,需要設備中info.Plist權限,key:Required background modes ,value: bluetooth-central(手機作爲central) , bluetooth-peripheral(手機作爲外設) 參考鏈接

同時連接多個設備

android很簡單,創建多個gattCallback,每個gattCallback單獨管理設備連接後的操作,而iOS也最好不要創建多個CBCentralManager,多個CBCentralManager理論上可以用,但是會存在多個手機版本存在不同的行爲,還有一些很容易出錯的問題,這塊內容不細說了。使用同一個CBCentralManager,通過進入委託的peripheral的identifier區分不同的設備,進行不同的操作和處理。 在阿里的smurfs藍牙模塊中,我使用了一個dispatcher去分發每個連接設備的事件到不同實例中進行處理。

掃描廣播包

所有外設,只有在發出廣播包的情況下,才能被central發現,絕大多數情況下,外設被連接後就不會發出廣播(也有例外),很多人遇到無法找到設備的問題,大多屬於這種情況。 重複掃描問題——————

提高藍牙連接速度

無論是iOS,還是android,都可以通過已綁定的設備,在不開啓掃描的情況下進行快速連接,iOS需要的參數是peripheral的identifier,android需要mac地址。但android和iOS還是有一些區別的,比如iOS不能拿到已綁定的設備list,但是可以通過UUID去拿到peripheral的實例。而android可以拿到已綁定的設備list。android綁定過程需要手動調用createBond的方法,而iOS在連接成功一次後會自動綁定。 android在處理createBond時,常常會應爲不同手機平臺,不同設備,會產生兼容性的問題,這點需要注意。

定向掃描

在掃描時候可以傳入serviceUUID,這樣可以掃描到特定條件的設備,提高掃描的速度,排除干擾。

如何獲取mac地址

android可以直接通過getAddress得到mac地址,而iOS出於蘋果的安全策略問題,無法直接獲得mac地址,只能得到一個mac地址換算出來的identifier。不過在智能設備開發時,一般都會考慮到這個問題,大多數智能設備會把mac地址保存在廣播數據中,不同設備可能會存在不同的位置。

Babybluetooth藍牙庫的使用

Babybluetooth是iOS的藍牙庫的封裝,iOS藍牙委託層級特別討厭,一個委託接着一個委託,比如先進入掃描的委託,在進入鏈接的委託,在進入連接成功,發現服務,發現特徵,讀寫操作,一套操作被拆分的很散,容易出錯,代碼不易維護,上手慢等缺點,Babybluetooth對CoreBluetooth進行了封裝,把委託回調進行方法調用的方式,改成了鏈式方法順序調用,直接調用baby.enjoy()方法,完成一整套操作。簡化了上手難度和代碼維護成本。現在開源在github上,有2300個star,藍牙庫中排名第一。

由於時間關係,這裏不會詳細介紹BabyBluetooth的使用,想連接的可以看github bady的主頁

作者:劉彥瑋,80後,一個全棧工程師,github開源作者,目前就職於阿里巴巴,從事iot智能藍牙設備應用端和基礎框架開發。 
原文:知乎live:一小時藍牙科普 文字整理版 
聲明:本文首發於作者博客,轉載已經作者授權。


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