使用 LinkIt Remote

LinkIt Remote 能讓開發者透過手機程式去遙控 LinkIt 7697。它主要由兩個部分構成:

  • LinkIt 7697 上面的 Arduino LRemote 程式庫,讓開發者指定手機上面的遙控器程式的介面外觀,並接收處理來自手機的遙控指令。
  • 在 iOS 與 Android 上面的 LinkIt Remote 程式,它可以掃描附近有執行 LRemote 程式庫的 LinkIt 7697,並連線遙控它們。
    請點擊下面的連結下載手機程式:

上述的兩個部分,中間是透過低功耗藍牙來進行資料與指令的傳輸。

範例程式

  1. 打開 Arduino IDE 的選單,並選擇 File > Examples > LRemote > RemoteControl,然後上傳此範例程式到 LinkIt 7697
  2. 打開 Arudino IDE 的 Serial Monitor。請維持 LinkIt 7697 的電源,讓他持續運作。
  3. 用 iOS 或是 Android 手機,從下面的 app store 的連結下載並安裝 LinkIt Remote
  4. 在手機上面打開 LinkIt Remote 程式。程式會開始掃描附近有運行 LRemote 程式庫的裝置。應該會在手機程式的介面上面看到一個名叫 "LinkIt 7" 或是 "LinkIt 7697" 的裝置。

    為什麼名字會不一樣?

    因為低功耗藍牙的裝置在廣播資訊時的長度非常有限,所以在廣播的時候,"LinkIt 7697"這樣的裝置名稱可能會被裁剪成 "LinkIt 7"。某些手機,比如 iOS,會在連線到低功耗藍牙裝置時,查詢並且暫存完整的裝置名稱,並再下一次的掃描時,自動顯示完整的裝置名稱。

  5. 點擊顯示的「LinkIt 7697」項目,程式會花一些時間連接到 LinkIt 7697,然後顯示如下的遙控器介面:

  6. 首先點擊 USR LED 這個切換按鈕。應該會看到 LinkIt 7697 板子上面的內建 USR LED 會亮起來。
  7. 然後,接著拖動 Value Slider 這個捲動軸。會看到 Arduino IDE 的 Serial Monitor 會印出捲動軸的目前數值。

這個範例簡單的展示了要怎麼利用 LRemote 與 LinkIt Remote 來建造可以用於 LInkIt 7697 的手機遙控程式。

進一步瞭解範例程式

在上面描述的範例程式中,我們首先建立了一個叫做 LinkIt 7697 的低功耗藍牙裝置,並且添加了數個對應到遙控器介面的 GATT 屬性。LinkIt Remote 手機程式會掃描並且解析這些 GATT 屬性,然後在手機畫面上顯示出相對應的遙控器控制元件。

使用 LRemote library 的第一步就是先設定欲建立的裝置。透過 LRemote 程式庫,可以直接指定開發者要呈現的裝置名稱、遙控器介面是橫向或是直向,以及在遙控器介面上的畫布的網格數目。

  // 設定遙控器的顯示介面
  LRemote.setName("LinkIt 7697");
  LRemote.setOrientation(RC_PORTRAIT);
  LRemote.setGrid(3, 5);

In the example above,

  • 我們把裝置取名為 LinkIt 7697
  • 並且指定了一個直向、等分為 3 x 5 的網格。這個網格並不會實際顯示出來,而是作為後續擺放遙控按鈕元件的參考座標。網格的示意圖如下:

設定好手機的方向以及網格數量之後,我們就可以開始把控制元件擺放到網格上面。比如說,如果我們要添加一個可以用來開關 USR LED 的開關按鈕,我們首先要在全域變數空間當中宣告一個 LRemoteSwitch: 

#include <LRemote.h>
 
LRemoteSwitch switchButton;

and then we configure the text label, size, and position of the switch button:

然後我們接著要設定該按鈕的文字標籤、顏色、大小、以及位置:

void setup() {
  // Add an on/off switch
  switchButton.setText("USR LED");
  switchButton.setPos(0, 1);
  switchButton.setSize(1, 1);
  switchButton.setColor(RC_BLUE);
  LRemote.addControl(switchButton);
}

在上面的範例中,

  • 我們將文字標籤設定為 "USR LED"
  • 我們將按鈕的顏色設定為 RC_BLUE
  • 位置座標設定為 (0, 1),也就是 X = 0、Y = 1,意思是要把這個按鈕擺放到第 1 欄的第 2 列,可以參考下面的圖片來瞭解座標系的編排方式:

  • 設定完成之後,我們要呼叫  LRemote.addControl(switchButton) 來將這個按鈕真正的加到控制器的介面裡面。

    請注意,一定要將按鈕宣告為全域空間變數(global scope) ,並且呼叫 addControl。要不然,按鈕將會無法正確的運作。

當設定好所有的按鈕之後,我們可以呼叫 LRemote.begin() 來啟動我們的裝置,並向周圍發送廣播。

  // Start broadcasting our remote contoller
  // This method implicitly initialized underlying BLE subsystem
  // to create a BLE peripheral, and then
  // start advertisement on it.
  LRemote.begin();

我們可以不斷的用 LRemote.connected() 來檢查是否已經有 LinkIt Remote 程式連接到我們的 LinkIt 7697 裝置:

  if(!LRemote.connected()) {
    Serial.println("waiting for connection");
    delay(1000);
  }

當 LinkIt Remote 連線到此裝置之後,手機程式會查詢有哪些控制元件,並且在手機畫面上面顯示出來:


接著,使用者可以透過點擊手機畫面上面的控制元件,來發送指令到 LinkIt 7697。在 LinkIt 7697 上面,我們需要不斷的在 loop() 函式當中定期呼叫 LRemote.process() ,來檢查並且處理來自手機的指令:

void loop() {

  // Process the incoming BLE write request
  // and translate them to control events
  LRemote.process();
 
  // ...
}

在存取控制元件的數值變化之前,請務必先呼叫 LRemote.process(),如此數值才會被正確的更新。

在手機傳送過來的指令都被處理完成之後, LRemote 會更新每一個控制元件的相關數值,比如說,針對開關按鈕,可以使用下列的 API:

  • LRemoteSwitch::isValueChanged() 可以得知使用者是否有撥動開關按鈕
  • LRemoteSwitch::getValue() 可以取得當前的開關狀態:
    • 0 表示「關」
    • 1 表示「開」

範例程式便是利用這兩個 API 來決定要不要打開或是關閉板子上內建的 USR LED。

  if(switchButton.isValueChanged()){
    digitalWrite(LED_BUILTIN, switchButton.getValue());
  }

針對捲動軸 (LRemoteSlider) ,也可以使用相同的 API,不同之處在於 getValue() 會回傳捲動軸的數字。

其他按鈕 (LRemoteButton and LRemoteCircleButton) 的 API 比較單純:

  • getValue() 回傳 0 表示按鈕沒有被按下
  • getValue() 回傳 1 表示按鈕處於被按下的狀態

另外,也可以使用 LRemoteLabel 來顯示單行文字。不過,因為使用者沒辦法跟標籤進行互動,所以這個類別不會提供 getValue() 這個 API。

開源軟體

LRemote 程式庫以及 LinkIt Remote app 使用了下列的函示庫: