【教學】以ArduinoIDE設計LinkIt 7697藍牙遙控車

之前我們介紹過如何使用LinkIt 7697自己動手做藍牙遙控車(文章連結,請點我),這次我們將更進一步介紹如何使用ArduinoIDE,寫出使用藍牙連線就可以控制車子的Linklt Remote App介面,讓車子前後左右移動並且可以用PWM控制馬達的轉速。

LinkIt Remote 是一個用來產生手機App介面的小程式,是以 BLE 與 LinkIt 7697開發板搭配使用。只要在程式端設定好,就可以在兩者連線之後產生對應的介面。

作者/攝影郭俊廷
時間 2HR
難度

 ★★☆☆☆

材料表

今天我們要來介紹如何使用ArduinoIDE寫出使用Linklt Remote App藍牙連線就可以輕鬆設計各種簡易的控制界面來控制馬達,讓車子前後左右移動並且可以用PWM控制馬達的轉速。

LinkIt Remote 是一個用來產生手機App介面的小程式,是以 BLE 與 LinkIt 7697開發板搭配使用。只要在程式端設定好,就可以在兩者連線之後產生對應的介面。

首先放上Linklt Remote App載點,先把它下載到手機中吧!

 

一、Arduino IDE環境設定

若Arduino IDE沒有新增相關LinkIt 7697的開發版環境設定可以按照以下步驟安裝額外的 board support package 。

 

對 Arduino IDE 來說,LinkIt 7697 屬於第三方開發板,因此需要安裝額外的 board support package 才能在 IDE 中正常使用 LinkIt 7697。設定的步驟如下:

1.開啟 File > Preferences 選單如下圖:

2.將下方的 URL 加進 Additional Boards Manager URLs 的欄位:

http://download.labs.mediatek.com/package_mtk_linkit_7697_index.json

欄位所在處如橘色框標示:

3.點選 OK 完成設定。

4.選擇 Tools > Board > Boards Manager… 以開啟 Board Manager 視窗:

5.開啟後,Board Manager 會根據上述提供的 URL 下載第三方套件資訊。下載完成後,可以在支援列表當中找到 LinkIt 7697 by MediaTek Labs 的欄位。若列表太長不易尋找,也可以在搜尋欄位 (框框處) 輸入 LinkIt 進行過濾:

6.選擇 LinkIt 7697 項目,然後點選 Install 按鈕:

7.此時 IDE 就會開始下載及安裝所需的軟體與工具。 待完成後點選 Close 關閉此視窗。

8.完成安裝程序後,應該就能在 Tools > Board 裡看到 LinkIt 7697 的項目顯示出來。

至此已完成 LinkIt 7697 board support package 的安裝程序。

 

二、車子馬達與馬達驅動板接線

關於馬達跟車子的接線我們使用直流馬達接上馬達驅動板Robot Shield

馬達的腳位跟 Robot Shield的腳位對應表

馬達的腳位Robot Shield的腳位
113
217
310
412

車子實體圖

最近我們升級了我們的LinkIt 7697藍牙遙控車,不僅體積縮小了,Robot Shield一樣可以搭配使用各種感測器歐。有興趣的人歡迎聯絡我們歐~

升級版車子實體圖

 

三、如何使用 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” 的裝置。

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);

在上面的範例程式碼中

我們把裝置取名為 LinkIt 7697

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

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

#include <LRemote.h>
 LRemoteSwitch switchButton;
然後我們接著要設定該按鈕的文字標籤、顏色、大小、以及位置:
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() 來啟動我們的裝置,並向周圍發送廣播。

  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());
  }

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

getValue() 回傳 0 表示按鈕沒有被按下

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

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

 

四、程式設計

接著開始使用ArduinoIDE寫程式,我們程式的需求是要使用Linklt Remote App來藍牙連線控制我們的車子。

程式碼設計我們分成三個部分

  • 第一個部分要先宣告使用的函式庫跟Linklt Remote App要使用到的UI
  • 第二個部分要設定LinkIt Remote藍牙連線的名稱跟各個UI的名稱內容跟大小、位置等等。
  • 第三個部分要設定甚麼UI按下去或是改變它的狀態時會對馬達做出甚麼相對應的動作。

 

首先帶大家認識一下我們使用了哪一些函式與代表的意思

我們宣告了Linklt Remote函式庫、一個文字標籤、五個按鈕分別是前、後、左、右、停止跟一個滑桿。

如果想要了解更多UI的功能可以上聯發科的LinkIt 7697 for Arduino 開發指南 使用 LinkIt Remote網站上查詢

https://docs.labs.mediatek.com/resource/linkit7697-arduino/zh_tw/developer-guide/using-linkit-remote

#include <LRemote.h>  //宣告引用Linklt Remote函式庫LRemote.h
LRemoteLabel label1;    //Linklt Remote App的文字標籤
LRemoteButton F;         //Linklt Remote App的F方形按鈕
LRemoteButton B;         //Linklt Remote App的B方形按鈕
LRemoteButton L;         //Linklt Remote App的L方形按鈕
LRemoteButton R;         //Linklt Remote App的R方形按鈕
LRemoteButton S;         //Linklt Remote App的S方形按鈕
LRemoteSlider slider1;  //Linklt Remote App的滑桿

接著要設定函式的部分要設定App端介面的UI

首先要宣告我們LinkIt Remote App藍牙連線搜尋到的裝置名稱(每台藍牙裝置名稱要不一樣才可以分別連線上不同車子)還有App端介面的UI格式設定,例如UI是直式還是橫式,還有UI的螢幕棋盤格數大小。另外一點要注意的是UI介面的位置設定是從(0, 0)開始設定的。

每個UI的格式要設定UI的位置、UI上顯示的文字、UI的標籤大小、UI的顏色等等。

void setup()
{
  LRemote.setName("RK Car");   //Linklt Remote App的藍牙連線名稱
  LRemote.setOrientation(RC_PORTRAIT);   //Linklt Remote App的UI設定成直式
  LRemote.setGrid(3, 9);   //Linklt Remote App的UI設定螢幕棋盤格數 3行9列
    
    label1.setPos(2, 2);   //label1的標籤位置設定在(2, 2)的位置
    label1.setText("RK Car");   //label1的標籤名稱顯示為RK Car
    label1.setSize(1, 1);   //label1的標籤大小設為1*1
    label1.setColor(RC_GREEN);   //label1的標籤顏色設為綠色
    LRemote.addControl(label1);   //新增一個label1的文字標籤

    //加入按鈕F
    F.setPos(1, 2);   //按鈕F的位置設定在(1, 2)的位置
    F.setText("Foward");   //按鈕F的名稱顯示為Foward
    F.setSize(1, 1);   //按鈕F的大小設為1*1
    F.setColor(RC_ORANGE);   //按鈕F的顏色設為橘色
    LRemote.addControl(F);   //新增一個F的按鈕

    //加入按鈕B
    B.setPos(1, 4);
    B.setText("Back");
    B.setSize(1, 1);
    B.setColor(RC_ORANGE);
    LRemote.addControl(B);

    //加入按鈕L
    L.setPos(0, 3);
    L.setText("Left");
    L.setSize(1, 1);
    L.setColor(RC_ORANGE);
    LRemote.addControl(L);

    //加入按鈕R
    R.setPos(2, 3);
    R.setText("Right");
    R.setSize(1, 1);
    R.setColor(RC_ORANGE);
    LRemote.addControl(R);

    //加入按鈕S
    S.setPos(1, 3);
    S.setText("Stop");
    S.setSize(1, 1);
    S.setColor(RC_ORANGE);
    LRemote.addControl(S);

    //加入滑桿
    slider1.setPos(0, 7);   //slider1的滑桿位置設定在(0, 7)的位置
    slider1.setSize(3, 1);   //slider1的滑桿大小設為3*1
    slider1.setText("速度值");   //slider1的滑桿名稱顯示為速度值
    slider1.setValueRange(0, 255, 0);   //slider1的滑桿範圍為0到255初始值為0
    slider1.setColor(RC_ORANGE);   //slider1的滑桿顏色設為橘色
    LRemote.addControl(slider1);   //新增一個slider1的滑桿
 
  //開始廣播您的遙控器、設定腳位輸入輸出模式
  LRemote.begin();   //開始廣播您的遙控器
  pinMode(10, OUTPUT);   //設定PIN10為輸出
  pinMode(12, OUTPUT);   //設定PIN12為輸出
  pinMode(13, OUTPUT);   //設定PIN13為輸出
  pinMode(17, OUTPUT);   //設定PIN17為輸出
}

最後是無限迴圈的部分我們要設定當Linklt Remote開始處理手機程式指令時需要做的動作,需要做的動作這邊我們設計成當按下前後左右的按鈕時會偵測滑桿數值有無改變如果有改變就送出PWM訊號到對應的馬達腳位做對應的動作。

void loop()
{
LRemote.process();    //開始處理手機程式指令
//如果F按鈕按下去則車子依照滑桿的速度前進
  if (F.getValue() == 1) {    //如果F按鈕得到的值為1做以下動作
    if (slider1.isValueChanged()) {    //如果滑桿數值改變做以下動作
      analogWrite(10, 0);    //PIN10腳位寫入PWM訊號0
      analogWrite(12, slider1.getValue());    //PIN12腳位寫入PWM訊號滑桿的數值
      analogWrite(13, 0);    //PIN13腳位寫入PWM訊號0
      analogWrite(17, slider1.getValue());    //PIN17腳位寫入PWM訊號滑桿的數值

    }

  }
//如果B按鈕按下去則車子依照滑桿的速度後退
 if (B.getValue() == 1) {
    if (slider1.isValueChanged()) {
      analogWrite(10, slider1.getValue());
      analogWrite(12, 0);
      analogWrite(13, slider1.getValue());
      analogWrite(17, 0);

    }

  }
//如果L按鈕按下去則車子依照滑桿的速度左轉
 if (L.getValue() == 1) {
    if (slider1.isValueChanged()) {
      analogWrite(10, 0);
      analogWrite(12, slider1.getValue());
      analogWrite(13, slider1.getValue());
      analogWrite(17, 0);

    }

  }
//如果R按鈕按下去則車子依照滑桿的速度右轉
  if (R.getValue() == 1) {
    if (slider1.isValueChanged()) {
      analogWrite(10, slider1.getValue());
      analogWrite(12, 0);
      analogWrite(13, 0);
      analogWrite(17, slider1.getValue());

    }

  }
//如果S按鈕按下去則車子停止
  if (S.getValue() == 1) {    //如果S按鈕得到的值為1做以下動作
    analogWrite(10, 0);    //PIN10腳位寫入PWM訊號0
    analogWrite(12, 0);    //PIN12腳位寫入PWM訊號0
    analogWrite(13, 0);    //PIN13腳位寫入PWM訊號0
    analogWrite(17, 0);    //PIN17腳位寫入PWM訊號0

  }

}

燒入的時候記得開發版要改成7697

 

五、LinkIt 7697藍牙遙控車操作介紹

燒入完成之後就是開啟Linklt Remote APP藍牙連線,選擇剛剛命名的藍牙名稱,連線之後就會開啟我們的UI介面。

程式寫好產生出來的UI介面如下圖,可以看到有前後左右和停止的按鈕,下面還有可以拖曳馬達速度值的滑桿。

只要按下前後左右並改變速度值的滑桿就可以讓車子進行對應速度的移動,按下停止就可以讓車子停止。

以上我們程式設計部份的講解在這告一段落,大家可以依照自己的喜好設計相對應的UI來設計我們 LinkIt 7697藍牙遙控車控制App介面。

影片操作說明(請觀看基礎篇0:00~1:23的部分):

 

完整的程式碼如下如有需要請至雲端硬碟下載

7697Linklt_RemoteAPP.zip

 

部分引用自MEDIATEK labs:

  • Resources LinkIt 7697 for Arduino 環境設定 設定 Arduino IDE
  • Resources LinkIt 7697 for Arduino 開發指南 使用 LinkIt Remote

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *