樹莓派軟件更新
依次執行如下命令:
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get dist-upgrade -y
以上指令如不成功,在指令後添加--fix -mising
安裝藍牙
sudo apt-get install pi-bluetooth bluez bluez-firmware blueman
系統默認安裝的是pi-bluetooth bluez bluezfirmware
.
如果安裝blueman
,界面上會出現兩個藍牙程序,新出現的是用來輔助藍牙操作的。
添加pi用戶到藍牙組
sudo usermod -G bluetooth -a pi
,重啓sudo reboot
卸載藍牙
sudo apt autoremove bluez bluez-firmware blueman
和串口通訊會出現衝突
詳見串口開發,因爲更改了樹莓派硬件上的串口映射關係。
Bluez
首先要在樹莓派上安裝必要的工具。BlueZ是Linux官方的藍牙協議棧。你可以通過BlueZ提供的接口,進行豐富的藍牙操作。Raspbian中已經安裝了BlueZ。我使用的版本是5.43.
bluetoothd -v
用下面的命令檢查BlueZ的運行狀態:
systemctl status bluetooth
結果:
● 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
用下面命令手動啓動或關閉藍牙服務:
sudo systemctl start bluetooth
sudo systemctl stop bluetooth
讓藍牙服務隨系統啓動:
sudo systemctl enable bluetooth
樹莓派上的藍牙
在Raspbian
中:
- 基本的藍牙操作可以通過
bluez
中的bluetoothctl
命令進行。 - 該命令運行後,將進入到一個新的Shell。在這個shell中輸入:
list
。
將顯示樹莓派上可用的藍牙模塊:
Controller B8:27:EB:72:47:5E raspberrypi [default]
. - 運行scan命令,開啓掃描:
scan on
。 - 掃描啓動後,用
devices
命令,可以打印掃描到藍牙設備的MAC地址和名稱,例如:Device 00:9E:C8:62:AF:55 MiBOX3 Device 4D:CE:7A:1D:B8:6A vamei
- 此外,你還可以用help命令獲得幫助。
- 使用結束後,你可以用
exit
命令推出bluetoothctl
。
除了bluetoothctl
,在Raspbian
是shell
中可以通過hciconfig
來控制藍牙模塊。比如開關藍牙模塊:
sudo hciconfig hci0 up #啓動hci設備
sudo hciconfig hci0 down #關閉hci設備
命令中的hci0指的是0號HCI設備,即樹莓派的藍牙適配器。
與此同時,你可以用下面命令來查看藍牙設備的工作日誌: hcidump
。
bluez本身還提供了連接和讀寫工具。但不同版本的bluez相關功能的差異比較大,而且使用起來不太方便,所以我下面使用Node.js的工具來實現相關功能。
樹莓派作爲BLE外設
把一個樹莓派改造成BLE外設,同時它也將充當連接建立後的服務器。這個過程較爲複雜。可以借用Node.js
下的bleno
庫。
- 安裝
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
- 運行pizza的例子
sudo node node_modules/bleno/examples/pizza/peripheral
可以在node_modules/bleno/examples/pizza/
看到源代碼,或者到github查看。這個例子提供了一個Service
,它的UUID是1333-3333-3333-3333-3333-333333333337。Service中包含了三個Characteristics,分別是用於披薩餅參數、配料參數和烤披薩。
樹莓派作爲BLE中心設備
用另一個作爲BLE的中心設備進行掃描,併發起連接請求。連接建立後,該服務器將充當客戶。和bleno
對應,Node.js
下有一個叫noble
的項目,可以便捷地完成這一任務。首先,安裝noble
:
mkdir ble-test-central
cd ble-test-central
npm install noble
noble
中有一個同樣名爲pizza
的例子,不過這個例子實現的是客戶端。運行該例子:
sudo node node_modules/noble/examples/pizza/peripheral
這個例子將自動執行掃描、連接、服務發現、數據傳輸的全過程。如果你把bleno
和noble
部署到兩個樹莓派上,就可以在這兩個樹莓派之間進行藍牙通信了。如果你想自定義開發,那麼可以在node_modules/noble/examples/pizza/參考源代碼
,或者到github查看。
樹莓派作爲Beacon
蘋果在BLE
的基礎上推出了iBeacon
協議。iBeacon
使用了BLE
的廣播部分,但不建立連接。一個遵守iBeacon
協議的外設稱爲Beacon
。Beacon
會廣播自己的身份信息和發射信號的強度。中心設備接收到廣播之後,除了可以獲知Beacon
的身份之外,還能通過信號的衰減算出自己與Beacon
的距離。
在一個典型的超市應用場景中,每件商品可以帶上一個Beacon
。消費者可以用手機看到自己周圍有哪些商品,工作人員也可以用手機來清點貨物。商家還可以在服務器上提供商品相關的質保、促銷等信息。用戶可以根據Beacon
的編號,獲得這些附加信息。
我們把配備了藍牙模塊的樹莓派改造成一個Beacon
。既然Beacon
只使用了藍牙中的廣播,那麼應該關閉樹莓派的掃描,打開廣播,並且不接受藍牙連接:
sudo hciconfig hci0 noscan # 不再掃描
sudo hciconfig hci0 leadv 3 # 開始廣播,並且不接受連接
下一步,把廣播信息改爲符合iBeacon
協議的內容:
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進制信息。其中0x08
說明了整條信息是藍牙命令,0x0008
說明後面的內容將作爲廣播信息。
1E
是廣播信息開始的標誌。按照藍牙通信的規定,廣播信息最多有31個字節。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
每一組一開始的一個字節說明了該組信息的長度。02
說明了2個字節,1A
說明是26個字節。隨後一個字節說明了改組信息的類型。
第一組的01說明了該組信息是藍牙控制標誌,第二組的FF說明了該組是藍牙製造商相關信息。
我們來看第二組信息的細節:
4C 00
是製造商信息,即蘋果。02 15
是iBeacon
協議標識。63 6F 3F 8F 64 91 4B EE 95 F7 D8 CC 64 A8 63 B5
部分是設備的UUID,通常是用戶編號。- UUID後面的
00 01
是主編號(Major)。 - 再往後的
00 02
是次編號(Minor)。通過UUID、主編號、次編號的組合,我們可以唯一地確定iBeacon
設備。 - 最後的
C5
說明了藍牙信號強度,即在1米處測得的該Beacon
的RSSI
值。 - 中心設備把接收到的信號強度和該信號強度對比,就可以知道信號衰減了多少,從而推算出自己與
Beacon
的距離。由於我這裏寫入的C5
沒有經過校準,所以距離測量很可能不準確。
使用結束後,可以用下面命令來恢復掃描和停止廣播:
sudo hciconfig hci0 piscan # 恢復掃描
sudo hciconfig hci0 noleadv # 停止廣播