樹莓派3和樹莓派2相比較,除了主頻的提升外,還添加了WIFI和藍牙模塊,大大的增強了無線連接功能,因而也更適合IoT平臺應用。
可穿戴設備大多都是通過藍牙來進行數據通信,實現設備間的數據交換。與Bluetooth Classic相比較而言,BLE的低功耗特性對於可穿戴設備而言,在電池消耗上更具優勢。某種程度上可以說,BLE成就了今天的可穿戴市場,反過來,可穿戴市場的崛起,讓BLE更具生命力了!
在RASPBIAN中,默認已提供了對藍牙的一些支持,提供了bluetoothctl等命令來進行基本的藍牙操作,通過命令行的方式來對BLE設備進行操作當然可行,不過用程序來控制的話,一則更靈活,另一方面也顯得高大上。
RPI上對藍牙的開發,大多以bluez為主,不過說實話,bluez看上去還是比較複雜的。考慮到js的使用者比較多,另外nodejs對硬體的要求也不算高,很適合在RPI上使用。下面的操作結合nodejs及mraa硬體庫來操作RPI3,至於BLE部分的操作,則使用的是nodejs的bleno來操作。
只點一個燈,為的是了解基本操作步驟。
硬體使用的是RPI3,如果是RPI2或更老的版本,需要準備一個Bluetooth Dongle,就是讓RPI具有藍牙通信功能就是了。
RPI3的系統下載及燒寫就不說了,漫天都是。
先準備好nodejs環境,在PI上執行如下命令
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install nodejs npm
nodejs是必須的,這是JS解釋器,非WEB端的那個解釋器,npm是用來安裝依賴組件的。
bleno是一個nodejs模塊,用來實現BLE外設功能,官方github地址為https://github.com/sandeepmistry/bleno,如果想要在PI上實現central功能,則要使用noble。
bleno依賴其它一些軟體框架,主要包括bluetooth及bluez。執行如下命令安裝這些依賴
sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev
安裝完成後,可以使用hciconfig命令來查看設備信息,如下
pi@raspberrypi:~/iot $ hciconfig dev
hci0: Type: Primary Bus: UART
BD Address: B8:27:EB:93:37:B8 ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING
RX bytes:10076 acl:287 sco:0 events:589 errors:0
TX bytes:12302 acl:287 sco:0 commands:363 errors:0
pi@raspberrypi:~/iot $
可以看到設備hci0,這個就是RPI3上的藍牙設備,另外也可以看到BD地址,BUS等其它硬體信息。
注意UP RUNNING信息,表明藍牙已啟用,否則需要使用命令hciconfig hci0 up來啟用藍牙設備。
接下來使用npm init命令來建立一個空的工程,package.json內容如下
{
"name": "iot",
"version": "1.0.0",
"description": "iot for raspberry pi 3",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"iot",
"nodejs",
"rpi3"
],
"author": "netlhx",
"license": "ISC",
"dependencies": {
"bleno": "^0.4.2",
"mraa": "^1.8.0"
}
}
這裡的模塊依賴主要有兩個,一個是bleno,實現BLE PERIPHERAL的功能由該模塊來實現,另一個模塊是mraa,這是intel推出的一個低級硬體庫,包括C/PYTHON/NODEJS等實現,除了支持intel自家的galileo及edison等硬體外,其它還支持包括RPI在內的許多硬體。另外還有一個upm庫,支持大量的傳感器及輸出外設。
基本的環境準備就緒,可以使用bleno自帶的測試腳本來測試硬體是否工作正常。測試方法見下圖
上圖輸出表明硬體工作正常,開始藍牙廣播並開啟相關的服務
使用nordic nrf connect應用可以來連接並實現簡單的通信
這是掃描並連接到RPI3的情況,可以對各種預設的Characteristic進行讀/寫操作並加以驗證。
這個test.js程序也可以做為我們點燈程序的藍本,稍加修改就可以用來實現BLE點燈程序了。
先看基本的信息配置
var led = new mraa.Gpio(36);
led.dir(mraa.DIR_OUT);
var name = 'RPI3';
var service_rpi3_uuid = '98860000ca0011e7b3fcf714f9f939b3';
var charact_led_uuid = '98860001ca0011e7b3fcf714f9f939b3';
試驗用到的LED燈連接在PIN36上面,注意使用了mraa庫來進行操作,另外這裡還定義了一些常量,其中包括設備名,服務及characteristic的UUID值,注意這是用戶自定義的服務類型,所以要使用128位的UUID值。
接下來是控制LED燈的代碼,如下
LedCharacteristic.prototype.onWriteRequest = function(data, offset, withoutResponse, callback) {
console.log('LedCharacteristic write request: ' + data.toString('hex') + ' ' + offset + ' ' + withoutResponse);
if(data.readUInt8(0) == 0) {
console.log('led off');
led.write(0); //led off
} else {
console.log('led on');
led.write(1);
}
callback(this.RESULT_SUCCESS);
};
當手機端通過藍牙向LedCharacteristic寫入一個0值的時候,關閉LED燈;反之,當用戶寫入非0值,則點亮LED燈。注意這裡的data,這是一個byte型數組,這裡也沒有檢測數組的長度,簡單的取第一個字節值並進行判斷,然後使用mraa庫來控制GPIO輸出狀態。
就是這麼簡單。
看看實際測試的結果,控制臺輸出如下
NRF CONNECT的掃描結果如下
注意這裡的UUID值,與代碼中的UUID值是一致的。
向LedCharacteristic寫入0x01值,代表點亮LED燈。
RPI上的LED燈顯示效果
測試沒有問題,就可以寫個簡單的APP來控制RPI3了。
雖然現在還只有GPIO操作,不過藉助mraa庫及upm庫,可以為RPI添加大量的外設,包括氣壓計、溫溼度計、LCD屏等等,只限於你的想像力。
不過在使用其它外設之前,記得打開相關的驅動支持,使用raspi-config命令就可以實現,如下圖
只點個燈,是有點太簡單了,不過只要燈點亮了,各種應用也就不遠了!