溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

用樹莓派玩轉(zhuǎn)藍(lán)牙

發(fā)布時(shí)間:2020-06-14 10:15:05 來源:網(wǎng)絡(luò) 閱讀:639 作者:余凱力 欄目:建站服務(wù)器

藍(lán)牙是一個(gè)使用廣泛的無線通信協(xié)議,這兩年又隨著物聯(lián)網(wǎng)概念進(jìn)一步推廣。我將介紹藍(lán)牙協(xié)議,特別是低功耗藍(lán)牙,并用樹莓派來實(shí)踐。樹莓派3中內(nèi)置了藍(lán)牙模塊。樹莓派通過UART接口和該模塊通信。樹莓派1和樹莓派2中沒有內(nèi)置的藍(lán)牙模塊,不過你可以通過USB安裝額外的藍(lán)牙適配器。

 

藍(lán)牙介紹 

藍(lán)牙最初由愛立信創(chuàng)制,旨在實(shí)現(xiàn)可不同設(shè)備之間的無線連接。藍(lán)牙無線通信的頻率在2.4GHz附近,和WiFi一樣,都屬于特高頻。相對(duì)于低頻信號(hào)來說,高頻傳輸?shù)乃俣缺容^快,穿透能力強(qiáng),但傳輸距離比較受限。在沒有遮蔽和干擾的情況下,藍(lán)牙設(shè)備的最大通信距離能達(dá)到30米。但在大多數(shù)情況下,藍(lán)牙的實(shí)際通信距離在2到5米。相比之下,低頻433MHz設(shè)備的通信距離很容易超過百米。因此,藍(lán)牙常用于近距離的無線設(shè)備,比如無線鼠標(biāo)和鍵盤。

用樹莓派玩轉(zhuǎn)藍(lán)牙

藍(lán)牙的標(biāo)志 

 

藍(lán)牙的基本工作流程如下:

  1. 廣播/掃描:通信的一方向外廣播自己的信息。另一方通過掃描知道自己周邊有哪些藍(lán)牙設(shè)備在廣播,這些設(shè)備的地址是什么,以及是否可以連接。

  2. 連接:通信的一方向另一方發(fā)起連接請(qǐng)求。雙方通過一系列的數(shù)據(jù)交換建立連接。

  3. 數(shù)據(jù)通信

根據(jù)細(xì)節(jié)上的差別,藍(lán)牙通信又細(xì)分為兩種:經(jīng)典藍(lán)牙和低功耗藍(lán)牙。早期的藍(lán)牙通信方式稱為經(jīng)典藍(lán)牙(classic bluetooth)。經(jīng)典藍(lán)牙中的數(shù)據(jù)傳輸協(xié)議是串行仿真協(xié)議RFCOMM。RFCOMM仿真了常見的串口連接。數(shù)據(jù)從一端輸入,從另一端取出。經(jīng)典藍(lán)牙的開發(fā)非常簡(jiǎn)單?;诖陂_發(fā)的有線鍵鼠程序,就可以直接用于RFCOMM連接的無線鍵鼠。此外,經(jīng)典藍(lán)牙可以快速傳輸數(shù)據(jù)。因此,諾基亞N95這樣的早期智能手機(jī),也用RFCOMM來互傳圖片和文件。

用樹莓派玩轉(zhuǎn)藍(lán)牙

RFCOMM通信

 

經(jīng)典藍(lán)牙的缺點(diǎn)是比較耗電。后來,諾基亞發(fā)明了一種可以降低功耗的藍(lán)牙通信方式。2010年出臺(tái)的藍(lán)牙4.0把這種通信方式規(guī)范為“低功耗藍(lán)牙”(BLE,Bluetooth Low Energy)。BLE把通信雙方分為非對(duì)稱的雙方,盡量讓其中的一方承擔(dān)主要的開銷,減少另一方的負(fù)擔(dān)。舉例來說,手環(huán)電量少,而且需要長(zhǎng)時(shí)間待機(jī)。BLE通信的主要負(fù)擔(dān)可以放在電量較充裕且充電方便的手機(jī)一側(cè),從而減少手環(huán)的能耗。

用樹莓派玩轉(zhuǎn)藍(lán)牙

手環(huán)作為外設(shè)

BLE通信一般也包含廣播/掃描的步驟。主動(dòng)發(fā)起廣播的設(shè)備稱為外設(shè)(Peripheral),掃描設(shè)備稱為中心設(shè)備(Central)。BLE連接成功之后,就可以開始數(shù)據(jù)傳輸。BLE的數(shù)據(jù)傳輸協(xié)議是ATT和GATT協(xié)議。ATT是GATT的基礎(chǔ)。ATT協(xié)議把通信雙方分為服務(wù)器(server)和客戶(client)。客戶主動(dòng)向服務(wù)器發(fā)起讀寫操作。需要注意的是,ATT中的服務(wù)器和客戶,與廣播階段的外設(shè)和中心設(shè)備相互獨(dú)立。當(dāng)然,在手環(huán)這樣的應(yīng)用場(chǎng)景下,外設(shè)通常也是服務(wù)器。ATT協(xié)議以屬性(attribute)為單位進(jìn)行該數(shù)據(jù)傳輸。一個(gè)屬性的格式如下:

用樹莓派玩轉(zhuǎn)藍(lán)牙

ATT屬性

我們分別來理解屬性的不同部分:

  1. handle:屬性的唯一編號(hào),長(zhǎng)度為16位。

  2. type:屬性的類型。每種類型用一個(gè)UUID編號(hào)。

  3. value:屬性的值。

  4. permission:屬性的權(quán)限,分為無、可讀、可寫、可讀寫。

服務(wù)器儲(chǔ)存了多個(gè)屬性。當(dāng)客戶向服務(wù)器請(qǐng)求時(shí),服務(wù)器會(huì)把自己的屬性列表發(fā)給客戶。隨后,客戶可以向服務(wù)器讀取或?qū)懭肽骋粋€(gè)屬性值。用讀寫的方式,通信雙方實(shí)現(xiàn)了雙向通信。

用樹莓派玩轉(zhuǎn)藍(lán)牙

以智能手表為例。智能手表和手機(jī)配對(duì)后,手機(jī)可以用讀的方式獲得智能手表中某個(gè)屬性下保存的步數(shù),也可以用寫的方式寫入另一個(gè)屬性負(fù)責(zé)的時(shí)間。在讀寫操作中,都是由客戶采取主動(dòng),服務(wù)器只能被動(dòng)應(yīng)答。ATT還提供了通知(notification)的工作方式。當(dāng)服務(wù)器改變了某個(gè)屬性值時(shí),可以主動(dòng)通知訂閱了該屬性值的客戶。智能手表中的手勢(shì)識(shí)別,就可以通過通知的方式告知手機(jī)。這樣的話,手機(jī)就可以實(shí)時(shí)地獲知手勢(shì)改變信息。

用樹莓派玩轉(zhuǎn)藍(lán)牙

GATT協(xié)議構(gòu)建在ATT協(xié)議之上,為屬性提供了組織形式。GATT的最小組織單元是Characteristic,可以由數(shù)條屬性組成。下圖中就是一個(gè)Characteristic,用于傳輸紅外測(cè)溫獲得的數(shù)據(jù)。這個(gè)例子來自TI的SensorTag:

用樹莓派玩轉(zhuǎn)藍(lán)牙

 從左到右:handle(16進(jìn)制),handle(10進(jìn)制),type(16進(jìn)制),type(文字說明),value(16進(jìn)制),permission,備注

 

Characteristc的第一條屬性用于聲明屬性,其類型總是0x2803。這條聲明的value部分又可以細(xì)分為三部分。第一個(gè)部分是0x12,稱為Characteristic Properties,是GATT協(xié)議層面上的權(quán)限控制。其具體含義可參考資料。第二部分0x0025,是Characteristic值的handle。找到handle為0x0025的屬性,就在聲明屬性的下面一行。0x0025的value部分就是紅外溫度的真正數(shù)值。剩下的部分是該Characteristic的UUID,總共128位:

F000-AA01-0451-4000-B000-000000000000

檢查Characteristic值的那一行屬性,也就是0x0025屬性。它的類型也是該Characteristic UUID。除了128位的UUID,藍(lán)牙官方還提供了16位的UUID可供使用,可參考資料。

 

可以看到,一個(gè)Characterstic至少需要兩個(gè)屬性,一個(gè)用于聲明,一個(gè)用于儲(chǔ)存它的數(shù)據(jù)。除此之外,Characteristic還有稱為Descriptor的額外描述信息。每個(gè)Decriptor占據(jù)一行。比如0x0027這個(gè)Descriptor,其屬性值是54:65:6D:70:7E:20:44:61:74:61,翻譯成ASCII就是:

Temp~ Data

此外,溫度單位、測(cè)量頻率等描述信息也經(jīng)常會(huì)以Descriptor的形式放入到Characteristic中。在下一個(gè)Characteristic聲明出現(xiàn)前的屬性,都是該Characteristic的Descriptor。

 

我們?cè)賮砜锤呒?jí)的組織單位Service。一個(gè)Service也有行屬性作為聲明,其類型UUID是0x2800。聲明屬性的值就是該Service的128位UUID。藍(lán)牙官方也提供了16位的UUID,預(yù)留給特定的Service,可參考資料。在下一個(gè)Service聲明出現(xiàn)前的屬性,都屬于該Service,比如下圖中從0x0023到0x002D的屬性:

用樹莓派玩轉(zhuǎn)藍(lán)牙

圖中包含了一個(gè)與紅外溫度計(jì)相關(guān)的Service。Service里又有三個(gè)Characteristic,分別0x0024-0x0027、0x0028-0x002A、0x002B-0x002D。我已經(jīng)介紹過第一個(gè)Characteristic。第二個(gè)Characteristic用于傳輸溫度計(jì)參數(shù),第三個(gè)用于設(shè)置測(cè)溫頻率。

 

Service和Characteristic都是屬性的組織形式??蛻艨梢韵蚍?wù)器請(qǐng)求Service和Characteristic列表,然后對(duì)其進(jìn)行操作。GATT還提供了Profile,可以包括多個(gè)Service。不過,Profile并不像前面兩者那樣存在于服務(wù)器。Profile是一種標(biāo)準(zhǔn),用于說明一個(gè)特型設(shè)備應(yīng)該有哪些Service。比如說,HID(Human Interface Device)這種Profile,就說明了藍(lán)牙輸入設(shè)備應(yīng)該提供的Service。藍(lán)牙官方定義的Profile可參考資料。

 

BlueZ

我們用樹莓派來深入實(shí)踐上面學(xué)到的藍(lán)牙知識(shí)。首先要在樹莓派上安裝必要的工具。BlueZ是Linux官方的藍(lán)牙協(xié)議棧。你可以通過BlueZ提供的接口,進(jìn)行豐富的藍(lán)牙操作。Raspbian中已經(jīng)安裝了BlueZ。我使用的版本是5.43。你可以檢查自己的BlueZ版本:

bluetoothd -v

低版本的BlueZ對(duì)低功耗藍(lán)牙的支持有限。如果你的使用版本低于5.43,那么我建議你升級(jí)BlueZ。

 

你可以用下面的命令檢查BlueZ的運(yùn)行狀態(tài):

systemctl status bluetooth

我的返回結(jié)果是:

用樹莓派玩轉(zhuǎn)藍(lán)牙

● bluetooth.service - Bluetooth service
   Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled)
   Active: active (running) since Sun 2017-04-23 19:03:08 CST; 1 day 6h ago
     Docs: man:bluetoothd(8)
 Main PID: 709 (bluetoothd)
   Status: "Running"
   CGroup: /system.slice/bluetooth.service
           └─709 /usr/lib/bluetooth/bluetoothd -C

用樹莓派玩轉(zhuǎn)藍(lán)牙

可以看到,藍(lán)牙服務(wù)已經(jīng)打開,并在正常運(yùn)行。

 

你可以用下面命令手動(dòng)啟動(dòng)或關(guān)閉藍(lán)牙服務(wù):

sudo systemctl start bluetoothsudo systemctl stop bluetooth

 

此外,你還可以讓藍(lán)牙服務(wù)隨系統(tǒng)啟動(dòng):

sudo systemctl enable bluetooth

 

了解樹莓派上的藍(lán)牙

在Raspbian中,基本的藍(lán)牙操作可以通過bluez中的bluetoothctl命令進(jìn)行。該命令運(yùn)行后,將進(jìn)入到一個(gè)新的Shell。在這個(gè)shell中輸入:

 

list

 

將顯示樹莓派上可用的藍(lán)牙模塊,例如:

Controller B8:27:EB:72:47:5E raspberrypi [default]

 

運(yùn)行scan命令,開啟掃描:

scan on

掃描啟動(dòng)后,用devices命令,可以打印掃描到藍(lán)牙設(shè)備的MAC地址和名稱,例如:

Device 00:9E:C8:62:AF:55 MiBOX3
Device 4D:CE:7A:1D:B8:6A vamei

此外,你還可以用help命令獲得幫助。使用結(jié)束后,你可以用exit命令推出bluetoothctl。

 

 

除了bluetoothctl,在Raspbian是shell中可以通過hciconfig來控制藍(lán)牙模塊。比如開關(guān)藍(lán)牙模塊:

sudo hciconfig hci0 up   #啟動(dòng)hci設(shè)備
sudo hciconfig hci0 down #關(guān)閉hci設(shè)備

命令中的hci0指的是0號(hào)HCI設(shè)備,即樹莓派的藍(lán)牙適配器。 

 

與此同時(shí),你可以用下面命令來查看藍(lán)牙設(shè)備的工作日志: 

hcidump

bluez本身還提供了連接和讀寫工具。但不同版本的bluez相關(guān)功能的差異比較大,而且使用起來不太方便,所以我下面使用Node.js的工具來實(shí)現(xiàn)相關(guān)功能。

 

樹莓派作為BLE外設(shè) 

下一步,我們嘗試用樹莓派進(jìn)行BLE通信。我們先把一個(gè)樹莓派改造成BLE外設(shè),同時(shí)它也將充當(dāng)連接建立后的服務(wù)器。這個(gè)過程較為復(fù)雜。你可以借用Node.js下的bleno庫(kù)。首先,安裝Node.js: 

curl -sL https://deb.nodesource.com/setup_5.x | sudo bash -
sudo apt-get install nodejs

第一行的命令是為了確保安裝高版本的Node.js。

 

安裝bleno: 

mkdir ble-test-peripheral
cd ble-test-peripheral
npm install bleno

 

運(yùn)行pizza的例子: 

sudo node node_modules/bleno/examples/pizza/peripheral

你可以在node_modules/bleno/examples/pizza/看到源代碼,或者到github查看。這個(gè)例子提供了一個(gè)Service,它的UUID是1333-3333-3333-3333-3333-333333333337。Service中包含了三個(gè)Characteristics,分別是用于披薩餅參數(shù)、配料參數(shù)和烤披薩:

功能權(quán)限UUID
披薩餅選項(xiàng)讀/寫13333333333333333333333333330001
配料讀/寫13333333333333333333333333330002
烤披薩寫/通知13333333333333333333333333330003

 

通過這些Characteristic,我們可以對(duì)樹莓派進(jìn)行BLE讀寫。讀寫操作會(huì)作用于一個(gè)代表比薩的對(duì)象。披薩餅選項(xiàng)有:

數(shù)值描述
0x00正常
0x01
0x02

 

配料是一個(gè)8位的參數(shù),每一位代表了一種配料。當(dāng)這一位是1時(shí),那么說明添加該配料:

第n位76543210
描述SAUSAGEBELL_PEPPERSPINEAPPLECANADIAN_BACONBLACK_OLIVESEXTRA_CHEESEMUSHROOMSPEPPERONI

 

因此,0x1A代表了添加MUSHROOMS、BLACK_OLIVES、CANADIAN_BACON,感覺味道還不錯(cuò)。

 

對(duì)于烤披薩來說,寫操作設(shè)定了烘烤的溫度和時(shí)間。時(shí)間到了之后,中心設(shè)備會(huì)發(fā)出通知,告訴客戶端烘烤完成。我們下一步將用另一個(gè)樹莓派作為BLE中心設(shè)備。不過,即使你沒有額外的樹莓派,你可以用iPhone上LightBlue這樣的App來測(cè)試這一部分完成的BLE外設(shè)。

 

樹莓派作為BLE中心設(shè)備

我們拿另一個(gè)作為BLE的中心設(shè)備進(jìn)行掃描,并發(fā)起連接請(qǐng)求。連接建立后,該服務(wù)器將充當(dāng)客戶。和bleno對(duì)應(yīng),Node.js下有一個(gè)叫noble的項(xiàng)目,可以便捷地完成這一任務(wù)。首先,安裝noble:

mkdir ble-test-central
cd ble-test-central
npm install noble

  

noble中有一個(gè)同樣名為pizza的例子,不過這個(gè)例子實(shí)現(xiàn)的是客戶端。運(yùn)行該例子:

sudo node node_modules/noble/examples/pizza/peripheral

這個(gè)例子將自動(dòng)執(zhí)行掃描、連接、服務(wù)發(fā)現(xiàn)、數(shù)據(jù)傳輸?shù)娜^程。如果你把bleno和noble部署到兩個(gè)樹莓派上,就可以在這兩個(gè)樹莓派之間進(jìn)行藍(lán)牙通信了。如果你想自定義開發(fā),那么可以在node_modules/noble/examples/pizza/參考源代碼,或者到github查看。

 

樹莓派作為Beacon

蘋果在BLE的基礎(chǔ)上推出了iBeacon協(xié)議。iBeacon使用了BLE的廣播部分,但不建立連接。一個(gè)遵守iBeacon協(xié)議的外設(shè)稱為Beacon。Beacon會(huì)廣播自己的身份信息和發(fā)射信號(hào)的強(qiáng)度。中心設(shè)備接收到廣播之后,除了可以獲知Beacon的身份之外,還能通過信號(hào)的衰減算出自己與Beacon的距離。在一個(gè)典型的超市應(yīng)用場(chǎng)景中,每件商品可以帶上一個(gè)Beacon。消費(fèi)者可以用手機(jī)看到自己周圍有哪些商品,工作人員也可以用手機(jī)來清點(diǎn)貨物。商家還可以在服務(wù)器上提供商品相關(guān)的質(zhì)保、促銷等信息。用戶可以根據(jù)Beacon的編號(hào),獲得這些附加信息。

用樹莓派玩轉(zhuǎn)藍(lán)牙

 

我們把配備了藍(lán)牙模塊的樹莓派改造成一個(gè)Beacon。既然Beacon只使用了藍(lán)牙中的廣播,那么應(yīng)該關(guān)閉樹莓派的掃描,打開廣播,并且不接受藍(lán)牙連接:

sudo hciconfig hci0 noscan    # 不再掃描sudo hciconfig hci0 leadv 3   # 開始廣播,并且不接受連接

 

下一步,把廣播信息改為符合iBeacon協(xié)議的內(nèi)容:

sudo hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 63 6F 3F 8F 64 91 4B EE 95 F7 D8 CC 64 A8 63 B5 00 01 00 02 C5

上面的命令附加了一串16進(jìn)制信息。其中0x08說明了整條信息是藍(lán)牙命令,0x0008說明后面的內(nèi)容將作為廣播信息。

 

1E是廣播信息開始的標(biāo)志。按照藍(lán)牙通信的規(guī)定,廣播信息最多有31個(gè)字節(jié)。1E后面的廣播信息分為兩組:

02 01 1A
1A FF 4C 00 02 15 63 6F 3F 8F 64 91 4B EE 95 F7 D8 CC 64 A8 63 B5 00 01 00 02 C5

每一組一開始的一個(gè)字節(jié)說明了該組信息的長(zhǎng)度。02說明了2個(gè)字節(jié),1A說明是26個(gè)字節(jié)。隨后一個(gè)字節(jié)說明了改組信息的類型。第一組的01說明了該組信息是藍(lán)牙控制標(biāo)志,第二組的FF說明了該組是藍(lán)牙制造商相關(guān)信息。

 

我們來看第二組信息的細(xì)節(jié):

  • 4C 00是制造商信息,即蘋果。

  • 02 15是iBeacon協(xié)議標(biāo)識(shí)。

  • 63 6F 3F 8F 64 91 4B EE 95 F7 D8 CC 64 A8 63 B5部分是設(shè)備的UUID,通常是用戶編號(hào)。

  • UUID后面的00 01是主編號(hào)(Major)。

  • 再往后的00 02是次編號(hào)(Minor)。通過UUID、主編號(hào)、次編號(hào)的組合,我們可以唯一地確定iBeacon設(shè)備。

  • 最后的C5說明了藍(lán)牙信號(hào)強(qiáng)度,即在1米處測(cè)得的該Beacon的RSSI值。中心設(shè)備把接收到的信號(hào)強(qiáng)度和該信號(hào)強(qiáng)度對(duì)比,就可以知道信號(hào)衰減了多少,從而推算出自己與Beacon的距離。由于我這里寫入的C5沒有經(jīng)過校準(zhǔn),所以距離測(cè)量很可能不準(zhǔn)確。

 

在iPhone上安裝應(yīng)用Locate Beacon來測(cè)試。當(dāng)我進(jìn)入到樹莓派的廣播范圍時(shí),該應(yīng)用就會(huì)顯示出手機(jī)距離樹莓派的距離。

用樹莓派玩轉(zhuǎn)藍(lán)牙

 

使用結(jié)束后,可以用下面命令來恢復(fù)掃描和停止廣播:

sudo hciconfig hci0 piscan   # 恢復(fù)掃描sudo hciconfig hci0 noleadv  # 停止廣播

 

總結(jié)

這里簡(jiǎn)單介紹了藍(lán)牙協(xié)議,特別是低功耗藍(lán)牙。我以樹莓派的藍(lán)牙模塊為基礎(chǔ),實(shí)現(xiàn)了BLE通信。

 

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI