(photo by Marc Mathieu)
簡介
低功率藍芽通訊在商業產品與業餘應用上的使用大量爆發,主要歸功於它的低成本以及低功耗的要求。當您要從您的 Android 手機或平板與英特爾® Edison或英特爾® Galileo專案溝通時,這讓它成為一個最佳的選擇。
這份文件的目標是展示如何編寫程式,以及使用免費軟件、低成本、現成的硬件在英特爾 Edison 與配備藍芽4.0的安卓裝置之間建立藍芽通訊。
什麼是藍芽?
低功率藍芽,藍芽 LE ,或 BLE (即智慧藍芽)是由藍芽技術聯盟設計與銷售的無線個人區域網絡技術。它的主要目標是健康照顧、健身、安全、自動化和家庭娛樂工業上的應用。
低功率藍芽原先是諾基亞在 2006 年以名為 Wibree 的技術推出。它在 2010 年藍芽 4.0 版本的時候被加入藍芽的標準。
低功率藍芽可以使用明顯比標準藍芽更少的功耗來做連結,可是仍然提供標準藍芽的大部分的連接功能,而且可以達到近乎一半的連接距離(大約 15 米/ 50 英尺)。配備電池的裝置如果使用低功率藍芽,可以在不用充電或更換電池的情況下運行數年。例如 Estimote 的 Beacon 裝置已經宣稱 3 年的電池壽命 (www.estimote.com)。
硬件
我們將着重於英特爾 Edison,但是大部分的內容依舊適用於英特爾 Galileo 。就我們的物聯網專案而言,硬件感測器和控制來自於 Seeed Studio 的 Grove 系統。尤其是我將使用:
- 有着 Arduino breakout 板子的英特爾 Galileo
- Seeed Grove – Starter Kit Plus Intel® IoT Edition For Galileo GEN 2
- Seeed Grove BLE
- 執行 Android 3 或更新版本的 Android 裝置(我使用Lenovo TAB S8-50)
- 執行 Windows* 7 或 8 的個人電腦,以做開發使用(我使用Dell XPS12)
關於硬件的幾項說明:
- The Grove Starter Kit 標示為專為英特爾 Galileo 所設計,但它也適用於 Edison 。您也可以單獨購買 Grove 組件,但套件將會更將划算。
- 在開發過程我使用 Lenovo 平板電腦,但是任何其它執行 Android 3 並支援藍芽 4.0 的 Android 裝置也都可行。
- 我使用我的 Dell XPS12 為英特爾 Edison 和 Android 專案(以及本篇文章)編寫程式。也可以使用 Mac* 或 Linux* 系統來進行開發。
軟件
我使用下列幾項免費的軟件工具。如果要查看這個例子,您需要下載並安裝下列各項:
- 適用於英特爾® Edison的Arduino IDE: https://software.intel.com/en-us/get-started-arduino-install
- Android Studio: https://developer.android.com/sdk/installing/studio.html
- Android SDK: https://developer.android.com/sdk/index.html?hl=i
上述所有軟件在 Windows 、 Mac 和 Linux 皆有提供,但是我將特別着重於 Windows 上的安裝。
硬件詳細資訊
英特爾 ® Edison
英特爾 ®Edison 是低成本、通用型的運算平台系列計畫的第一個產品。它專為快速、輕巧的製造物聯網專案的雛形所設計,同時可以提供準商業化產品的途徑。
英特爾 ®Edison 使用 22 奈米英特爾 ® SoC ,它包含了雙核,並可達到 500 MHz的執行速度。它支援 40 個 GPIOs ,並包含了 1GB LPDDR3 RAM 、 4 GB EMMC 儲存,以及雙頻 Wi-Fi* 和藍芽於一身。
Edison 執行完整的 Linux 核心,並且為了發揮 Edison 的最佳效能,您可以編寫硬件層的 Linux 程式。
但是 Edison Linux 還以 Linux 程式的形式包含了 Arduino 的實做。簡而言之,這意謂著您可以編寫您所熟悉的Arduino sketches,並在Edison開發板上執行;而這正是我們將做的。
更多英特爾Edison 資訊: http://www.intel.com/content/www/us/en/do-it-yourself/edison.html
Arduino Breakout 板子
相容於英特爾 Galileo 的 Arduino breakout 板子有着兩個用途。首先,它提供一個大的雛型平台可以輕鬆的存取 IO 腳位。第二,它提供兼容 Arduino 的硬件平台,這意謂着我們可以使用 Arduino shields 和英特爾 Edison (類似英特爾 Galileo)。圖1展示 Edison 安裝在 Arduino breakout 板子上。
圖1展示Edison安裝在Arduino breakout板子上
Grove Starter Kit Plus
這個套件的全名是 「Grove Starter Kit Plus -- Intel® IoT Edition for Intel® Galileo Gen 2 Developer Kit」,它最初是專為英特爾 Galileo 第二代開發板所設計。幸運的是它可以透過 Arduino breakout 板子以完全兼容英特爾 Edison 板子。
這個套件 (如圖2所示)主要設計於簡化感測器、促動器和屏蔽器的工作與雛形。它包含一個可兼容Arduino的屏蔽器以及四個標準化的連接腳位。這些連接器供給可接線的IO埠,這些接線可以輕易的連接到套件內的感測器與控制端。這意謂著您可以輕鬆的建立專案,而不需要為了一大堆的線搞得一團亂,上拉/下拉電阻也不需要擔心極性的問題。
更多資訊或購買此套件: http://www.seeedstudio.com/depot/Grove-starter-kit-plus-Intel-IoT-Edition-for-Intel-Galileo-Gen-2-p-1978.html
Grove 套件生產商 Seeed Studios 提供了許多有用的線上資源。
具體而言,我推薦從下列連結拷貝或下載 Sketchbook Starter repo :http://Github.com/Seeed-Studio/Sketchbook_Starter_Kit_V2.0
並且收藏Grove Wiki頁面為書籤 :
http://www.seeedstudio.com/wiki/index.php?title=Main_Page#Grove
圖2. Grove Starter Kit Plus -- Intel® IoT Edition for Intel® Galileo Gen 2 Developer Kit
Grove BLE V1
我們將使用 Grove 低功率藍芽 v1 模組,該模組並不包含在入門套件中,但與 Grove 屏蔽器和連接器的接腳相容。它也是成本相對低廉的 BLE 附件,這是我在撰寫本文時所可找到最便宜的選擇。
The Grove BLE v1是基於工業標準Texas Instruments CC2540。許多其他設備接使用這個晶片。如果您也有其它的TI CC2540 BLE模組,例如RedBear BLE Mini,您應該可以輕鬆修改範例程式。
Grove BLE v1 詳情:
http://www.seeedstudio.com/wiki/index.php?title=Grove_BLE_v1&uselang=en
請注意英特爾® Edison 包含一個板上的無線模組,它可以支援 Wi-Fi 和藍芽 4.0/BLE;然而, Grove BLE 模組大大簡化了硬件與軟件的設定。使用 Grove BLE (圖 3) 也意味着這些專案可以簡單的適用於英特爾 Edison 。
在 Android 裝置上偵錯
BLE 支援被增加到 Androis 4.3 版 (API 級別 18)。您需要執行 4.3 或更新的版本來透過 BLE 溝通。
更多有關 Android 藍芽的資訊 :
https://developer.android.com/guide/topics/connectivity/bluetooth-le.html
如果您是 Android 開發的新手,則您需要在手機或平板電腦上啟用開發人員選項,然後用它來執行與偵錯您的軟件。打該設置 app ,捲動到底部並選擇 「About device」,然後點擊創建編號七 (7) 次,以解鎖開發人員選項。
設置的下方顯示開發人員選項;確認選取「USB debugging」。
更多有關 Android 開發者選項: http://developer.android.com/tools/device.html
安裝軟件並且準備開始編寫程式!
相容英特爾 ® Galileo 的 Arduino IDE
您需要專門給 Arduino IDE 的版本,以便將 Sketches 佈署到英特爾 Edison 或 Galileo 。撰寫本文之時版本為 1.5.3 並可從下列連結下載:
https://software.intel.com/en-us/get-started-arduino-install
英特爾® Edison 驅動程式
您也需要從上述連結下載並安裝英特爾Edison驅動程式。它應該位於 「Driver Software」下方頁面的最後一個連結。在撰寫本文的時候它的版本為1.0.0。
如果您需要更進一步的說明,以下是十分有用的入門指南:
software.intel.com/iot/getting-started
Android Studio
Android Studio 是一個基於 IntelliJ IDEA *〈https://www.jetbrains.com/idea/ 〉,針對 Android開發功能全新的 Java*IDE 。雖然在此階段還只是測試版,但它的性能穩定,功能健全。如果你習慣用針對 Android 開發的 Eclipse* 或是IntelliJ IDEA ,用下列這兩個程式對你來說應該都沒有問題。
Android Studio 包含 Android SDK,所以能簡化其安裝過程。簡化至只需下載、提取解壓縮檔案中的內容,並啟動在 bin 資料夾中的 studio.exe 程式。
更多有關 Android Studio:https://developer.android.com/sdk/installing/studio.html
Android SDK
點選在 Android Studio工具欄的 「SDK manager」,以下載你可能需要的附加 SDK 封包。配置 Android SDKs 等等介紹已超過我們這次的範圍,你可以在下列網址得到額外的資訊:
https://developer.android.com/sdk/installing/adding-packages.html
若你在之前就已安裝 Android SDKs ,你可以配置 Android Studio 指向正確的路徑,如圖4所示。
在 Android Studio 點選 Configure -> Project Defaults -> Project Structure ,並且設定路徑。
圖 4. 在 Android* Studio中設定SDK的路徑
測試英特爾® Edison
在開始以下步驟之前,請先確認你可以啟動 Blink 示範 sketch 。 Blink 示範 sketch 位於 examples -> 01.Basics -> Blink folder 的 Arduino IDE 下載封包之中。
更多資訊於 Edison 入門手冊:
https://communities.intel.com/community/makers/edison/getting-started
Android Hello World
安裝 Android Studio 之後,請確認可以創造新專案,並且在你的 Android 裝置上啟動。
- 連接你的 Android 裝置和個人電腦
- 開啟 Android Studio
- 選擇「New Project…」
- 選擇一個名稱和地點,點選「Next」3次 〈API 15/Blank Activity)
- 點選「Finish」等待程式製作專案 〈大約花費20秒以上的時間〉
- 按下在工具欄中綠色的「Play」按鈕
- 選擇你的裝置,並點選「OK」
如果按照步驟完成,你會看到「Hello world!」顯示在你的 Android 裝置螢幕上。〈圖5〉
圖 5. Android* Studio Hello World 應用程式
BLE如何運作?
BLE 提供必要的短數據,並關閉電路。這也是 Bluetooth LE 如何達成低效能的目標。比較於常見的傳統藍芽配對,BLE 裝置只在需要傳送或是接收訊息時連結。
BLE 在通訊方面有強力的結構。裝置提供傳送和接收訊號的服務。這些服務擁有其獨特的「特性」,這個「特性」決定分享的資訊。更詳細來說,「特性」擁有描述詞來定義數據。例如:一個命名為「心臟指數感測器」的服務包含着「心臟指數測量」特性。
大多數的藍芽 LE APIs 支援搜尋當地裝置,找到裝置的服務、特性和描述詞。
BLE 的關鍵和概念
以下是你在開始一個 BLE 專案前,必須要知道的 BLE 關鍵術語和概念的簡述:
通用屬性設定檔 (GATT)
GATT 設定檔是藍芽低耗能的連接中,傳送及接收屬性數據的通用規格。所有近期的LE應用程式設定檔都是基於GATT設定檔所編寫。藍芽技術聯盟〈SIG〉(https://www.bluetooth.org)先前就已經先定義出BLE裝置的設定檔數量。 這些設定檔是用於介紹裝置的使用方法。
屬性協定 (ATT)
屬性協定〈ATT〉是 GATT 遵從的原理。屬性協定〈ATT〉是一個特別設計給BLE裝置的完美協定。屬性協定〈ATT〉通訊會盡量發送最少量的位元數據。 每一個屬性都擁有一個通用唯一識別碼〈UUID〉。唯一識別碼〈UUID〉是一個用於唯一識別資訊的標準化128位元ID碼。經由屬性協定〈ATT〉傳送的屬性被格式化為特性和服務。〈定義如下〉
特性
特性包含了一個單值和0,或是更多的描述詞〈如下所示〉來描述特性的值。
描述詞
描述詞定義了描述特性值的屬性。這些可能是人可辨識的描述詞,指定單元、測量,或是定義一個可接受的值範圍。
服務
服務是一系列的特性。你可以在https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx找到一整列現有的 GATT 為基礎的設定檔。
從 Android 傳送資訊到英特爾® Edison
前提的必要條件
文章接下來的部分是假定你有設置一個針對英特爾Edison跟安卓配置的開發程式。請確認你已經完成以上步驟,若有需要請複習文章之前的部分。
- 安裝英特爾 Arduino IDE
- 安裝英特爾 Edison 驅動程式
- 安裝 Android Studio
- 安裝 Android SDK
- 打開並啟動在英特爾 Edison上的 Blink demo
- 打開並啟動空白的 Hello world Android 專案
Android 的 BLE
你可以在 GithHub 下載已完成的專案:
https://github.com/adrianstevens/Edison_to_Android_BLE/tree/master/Android/BLEConnect
但是我建議你製作自己的專案,並參考上面的連結逐行寫入代碼。
製作一個新專案
打開Android Studio 〈或你自行選擇的IDE〉,創造一個新的空白安卓應用程式,並且將其命名為BLEConnect。別忘記設定Minimum SDK到達至少API 18,不然無法使用BLE APIs。
下一步,打開 AndroidManifest.xml 並填入下列內容至
設置 UI
為了讓事情簡單一點,我們只會利用預設值設定。但是必須針對 TextView設定一個ID。打開 layout -> activity_main.xml,選擇 TextView 並設定 ID 為 mainText ,這樣我們才可以在代碼中引用ID。
MainActivity
在這個專案之中,剩餘的代碼都會進入 MainActivity 裏面。如果你正在逐行編寫代碼,請注意 Android Studio會自動的檢測出你代碼的缺失,並即時的要求你補充修改。
樣本代碼將會:
- 確認安卓裝置中的BLE支援
- 搜尋周圍的BLE裝置
- 認證並連接至Grove BLE 組件
- 搜尋已知傳訊服務的可用服務
- 在傳訊服務中找尋傳送特性
- 利用編寫特性值傳送訊息
我不會在這份文章中解說每一個代碼,但是我們會看到它們的核心概念。
Class 級變數和靜態變量
我們會在連接至 BLE 組件、搜尋服務、傳送訊息時保存一些數值。我們也會為 Grove BLE v1 (TI CC2540) 增加一些已知的靜態變量。若你使用不同的組件,你有可能要改變它們。我特別推薦定義傳送和接收的特性,如下:
CHARACTERISTIC_TX ="0000ffe1-0000-1000-8000-00805f9b34fb"
CHARACTERISTIC_RX ="0000ffe1-0000-1000-8000-00805f9b34fb"
狀態幫手方法
為了容易了解,我們在先前標記的 TextView 上來展示我們的進展。代碼包含了一個叫做 statusUpdate 的簡易幫手方法。我們利用 statusUpdate 編寫狀態訊息至螢幕和控制台。他也可以引領回 UI 線上,所以我們可以從任何線程呼叫它。
連接至BLE 裝置
首先確認 BLE 是否在我們的裝置中,呼叫 getSystemService 引用 Bluetooth Manager (BluetoothManager),然後用 getAdapter() 方法取得引用到 BluetoothAdapter 目標以引用Bluetooth Manager 。或者,你可以直接從 Bluetooth Manager class 利用靜態幫手方法 getDefaultAdapter 。
搜尋周圍的 BLE 裝置
我們利用計時器設定一段期間來搜尋裝置。我們可以呼叫在 Bluetooth manager 目標上的 startLeScan ,並交付至回傳目標以在找到裝置時得到通知。
API 持續的掃描裝置,所以我們會在 LeScanCallback 得到從不同裝置回傳的通知。我們在保存裝置之前會確認裝置入口的唯一性。我們也會確認我們的組件裝置名稱,並且保存引用。在以下例子之中,我們並不需要保存此裝置。
@Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord)
{
…
}
找尋傳訊服務
大多數的 BLE 裝置提供一個或更多的通訊 / 互動服務。在我們Grove BLE 中的TI CC2540 晶片擁有一個重要服務,ID為 「0000ffe0-0000-1000-8000-00805f9b34fb」。下一步我們會找出並保存引用至那個服務。
首先,我們必須連結至裝置。利用 BluetoothGattCallback 目標並推翻onConnectionStateChanged and onServicesDiscovered,才能在連接到裝置或是找到服務時得到通知。請特別注意在使用 onConnectionStateChanged方法時,當我們得到已連接的通知,就可以呼叫mBluetoothGatt.discoverServices() 以搜尋服務。在我們找到所要的服務後,就可以繼續程序並且傳送訊息。
@Override
public void onConnectionStateChange (BluetoothGatt gatt, int status, int newState)
{
…
}
@Override
public void onServicesDiscovered (BluetoothGatt gatt, int status)
{
…
}
觀看下列文件,其他還有許多方法可以被推翻:https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback.html
傳送一個訊息
在範例代碼中有一個 sendMessage 方法。我們利用其 UDID 認證特性,並呼叫該特性上的 setValue 。最後,我們呼叫在 BluetoothGatt 引用中的 writeCharacteristic,傳送特性值,傳送數據。
有許多的 setValue 過載,其實可以使用一個較輕易的過載傳送符號串。但是大多數BLE溝通傳送回報時是使用位元,所以這是一個相對來說比較實用的例子。
現在,是時候設定英特爾 Edison了。
使用 Grove Breakout Board和BLE 組件設定英特爾® Edison
第一步始於組裝基本硬件。如果你還沒完成,請將英特爾Edison安裝到Arduin的分線版。
第二步,在安裝Grove擴充版時,將擴充版底部的針狀物對準Arduino的分線版。再連接Grove BLE v1 至UART串列埠。
圖8. 英特爾® Edison啟動於 Grove 擴充版和 BLE 組件連接
我們的第一個Sketch
我們正在做 Android 裝置和英特爾 Edison 之間的簡單串行通信。但是我們也希望看見有那些東西正在被傳輸和接收,所以我們利用Arduino IDE內建的串行感測器來觀察。
觀看Sketch完整版本:
https://github.com/adrianstevens/Edison_to_Android_BLE/tree/master/Sketches/SimpleSerial
打開英特爾 Arduino IDE 並創造一個全新的 Sketch。儲存它之後,將其命名為「SimpleSerial」。英特爾Edison擁有兩個串列埠可以使用,和其他的 Arduino相容面板不同。因為兩個串列埠允許我們在Edison 經由 Grove BLE 收發數據時,同時連接我們的個人電腦,所以非常的實用。你可以利用 microUSB 連結主 UART 串列埠至個人電腦。我們使用在 Grove 擴充版上已連結至 BLE 組件的 UART 串列埠連接器。若已經在英特爾 Edison 上配置完成,我們的 Sketch 就會自動啟動。它將會先啟動 setup() 功能,然後繼續的無限呼叫 loop() 功能。這個功能可以讓我們讀取並命令從串行連結的輸入。
初始化串行連結
Grove BLE 的初始連結速度是 9600 baud rate,所以我們就從這個開始。我們必須配置兩個串列埠以利用此速度。我們也必須向 Grove BLE 傳送數個 AT 命令,重新設定,使其在一個乾淨的狀態。你可以在 sketch 的 setup() 功能之中看到這些動作。
請注意到我們第一個配置的「Serial」是 microUSB UART 串列埠。第二個「Serial 1」是 UART 串列埠和 Grove BLE 的連結。
迴圈
我們在這個sketch中所做的都是讀取從別的串列埠來的數據,並將其傳送至另一個串列埠。為了達成這個動作,必須呼叫在串列埠的 read() 功能,此功能會給我們一個單一特性。接下來呼叫另一個串列埠的 print() 功能。
Edison 迴圈夠快,我們可以輕鬆達到 9600 baud rate。
配置 Sketch
現在,點選在 Arduino IDE 〈打勾處〉的核對〈verify〉按鈕,並修正所有的打字錯誤。在核對之後,請確認你的英特爾 Edison 已連結至你的個人電腦,並上傳你的 sketch 〈點選右箭〉。上傳完畢後, sketch 將會開始循環迴圈,就準備可以從安卓應用程式連結。現在開啟在 Arduino IDE 的串行感測器〈右上方放大鏡〉,我們就可以收發數據。
在 sketch 開始在英特爾 Edison 上運行後,啟動 Android BLEConnect 應用程式。你應該可以看見訊息:「Hello Grove BLE」出現在串行感測器上。
如果這個方法行不通,那問題應該出在 Android 應用程式上。確認顯示的狀態,它會告訴你問題在哪裡。
在 GitHub repo 中有一個 sketch 也會在 Grove LCD 顯示訊息。確認你的 Grove 擴充版已設定在 5V,並連接 LCD 顯示器至任何一個 I2C 連結。
圖 9. 在 Android 手機上運行的 BLEConnect
圖10. 正在接收BLEConnect 訊息的Adruino IDE 串行感測器
展望未來
製作一個更複雜的專案意指將建築學放入 Android 代碼和 Sketch的編寫之中。我建議將大部分的Android BLE 代碼移入服務之中,從 UI 抽象化代碼,讓其更容易在多樣的活動和專案中操作。當你製作更高級的 sketch 時,你將會需要 Arduino Time Library ,讓你可以一邊接收檔案,一邊模擬更多不同的迴圈(http://playground.arduino.cc/Code/Time) 。我會持續的在GitHub 存庫中增加範例(https://github.com/adrianstevens/Edison_to_Android_BLE),我也會在之後的文章中討論這些概念。
關於作者
Adrian Stevens 擁有 14 年以上的開發移動裝置應用程式的資歷;善於 C# 和 C++ 的跨平台開發。Adrian的專業包含建構使用者介面、音頻 / 信號程序、感測器和數理。 Adrian 長期任職於加拿大的溫哥華,擁有對科技的熱情和創業家的精神。他同時在 Meetup上進行 C# 跨平台開發。
Adrian 為 Palm Pilot 、 Pocket PC 等等平台在 2001 年首次開發移動裝置應用程式。他成功地創立並帶領一個精品移動裝置開發工作室。Adrian最近任職移動裝置和跨平台應用程式的指導員,指導建構和開發的策略。