【雙A計劃】Part4:App Inventor 藍牙遙控 Arduino 雙輪機器人

雙A計畫來到第五篇了,您都 follow 了嗎?在手機上製作多個按鈕,分別發送不同的字元來控制 Arduino 機器人。

雙A計畫文章總覽:

中文系列文章

English version

 

作者/攝影   曾吉弘
難度

★★★☆☆

材料表
  • Android系統智慧型手機
  • Arduino相容開發板(機器人王國購物連結,請點我)本文使用 Arduino MEGA2560
  • 藍牙收發接收器,本系列使用JY-MCU04 或 JY-MCU05
  • 麵包板
  • 具備2個連續型伺服馬達的車身,右側馬達的訊號線接在 D12 腳位,左側則是13。並分別接電與接地。
  • 9V電池,為機器人供電。如果用 USB 的話,馬達可能轉得非常慢或根本不會轉。

【推薦套件】自學者的天堂|Arduino 入門到雲端基本套件包

下載 範例程式請點我下載(App Inventor中文學習網檔案庫)  App Inventor 2檔名:BTRobot.aia

範例影片如下:

 

先根據下圖,將藍牙與兩個 servo motor 接上Arduino。

*請注意如果您要用直流馬達的話,就要使用 TA7279p 或 L293D  等馬達驅動電路。或是國產的 motoduino 控制板(已整合 L293D 晶片)

App Inventor 編寫藍牙訊息接收程式

畫面元件很簡單,點選 BT List 之後,會顯示藍牙配對裝置清單,點選您已經配對好的藍牙裝置之後,就會顯示一個包含有五個按鈕的操作介面。

a001

以下是安裝到實體手機上的截圖

 

 

程式說明:

本段程式重點在於按下不同的按鈕就會藉由 BluetoothClient元件發送不同的字元。例如 f 是前進,s 是停止等等。到了Arduino 端的程式就是藉由 switch 架構去判斷所收到字元的 ASCII碼,並執行對應的動作。所以機器人的接收端程式不太需要修改。

其他程式例如點選 ListPicker 去連接藍牙裝置或是斷線等,與先前的範例完全相同。在此就不再介紹囉。

BT_U:送出 ‘ f ‘ 讓機器人前進

BT_S:送出 ‘ s ‘ 讓機器人停止

BT_R:送出 ‘ r ‘ 讓機器人右轉

BT_L:送出 ‘ l ‘ 讓機器人左轉

BT_Dwn:送出 ‘ d ‘ 讓機器人後退

a002

Arduino 端程式

請注意Arduino 端程式會因為您使用連續型伺服馬達或是透過直流馬達控制晶片而有所不同,但基本上的架構都是一樣的。手機端程式則完全不變,都是滿足某個條件(例如按按鈕)發送字元。

連續型伺服馬達的機器人如下圖 (請忽略學生手上拿的 Wii 手把)

 

請先看伺服馬達的版本

Arduino 藍牙遙控機器人 - 伺服馬達版
#include <SoftwareSerial.h>
#include <Servo.h>

Servo servoRight;
Servo servoLeft;

SoftwareSerial BTSerial(10, 11); // RX, TX

byte dis[6]; //distance package
int t,i,pp; //temp value


void setup(){
Serial.begin(9600);
BTSerial.begin(57600); //BTSerial 9600,19200,38400,57600
servoRight.attach(12);
servoLeft.attach(13);
dis[0] = 65; //check value
}

void loop(){
if (BTSerial.available()>0){
pp=BTSerial.read();
Serial.println(pp);
switch(pp){
case 'f': //Forward
Up();
break;
case 'x': //Back
Down();
break;
case 'a': //Turn Left
Left();
break;
case 'd': //Turn Right
Right();
break;
case 's': //Stop
stop();
break;
case 65: //Return distance value
for(i=5;i>0;i--){
dis[i] = t%10;
t/=10;
}
//Pack value
for(i=0;i<=5;i++)
BTSerial.write(dis[i]);
//Return value
break;
default:
break;
}
}
}
int Up(){
servoRight.writeMicroseconds(1300);
servoLeft.writeMicroseconds(1700);
//delay(1000);
}
int Down(){
servoRight.writeMicroseconds(1700);
servoLeft.writeMicroseconds(1300);
//delay(1000); //視情況調整
}
int Right(){
servoRight.writeMicroseconds(1700);
servoLeft.writeMicroseconds(1700);
}
int Left(){
servoRight.writeMicroseconds(1300);
servoLeft.writeMicroseconds(1300);
}
int stop(){
servoRight.writeMicroseconds(1500);
servoLeft.writeMicroseconds(1500);
}

 

為了回饋各位朋友,也一併附上 motoduino 的版本。

Arduino 藍牙遙控機器人 - 直流馬達版(Motoduino)
const int Motor_E2 = 5; // digital pin 5 of Arduino (PWM)    
const int Motor_E1 = 6; // digital pin 6 of Arduino (PWM)
const int Motor_M1 = 7; // digital pin 7 of Arduino
const int Motor_M2 = 8; // digital pin 8 of Arduino
char val; // variable to receive data from the serial port(bluetooth)

void setup()
{
// Start serial communication at 9600
Serial.begin(9600);
pinMode(Motor_M1, OUTPUT);
pinMode(Motor_M2, OUTPUT);
}

void loop()
{
if(Serial.available()>0)
{
val = Serial.read();
switch(val)
{
case 'f': // car forward
forward(0, 255);
break;
case 'd': // car backward
backward(0, 255);
break;
case 'l': // car turn left
left(0, 255);
break;
case 'r': // car turn right
right(0, 255);
break;
case 's': // car stop
motorstop(0, 0);
break;
}
}
}

void motorstop(byte flag, byte motorspeed)
{
Serial.println("Stop!");
digitalWrite( Motor_E1, motorspeed);
digitalWrite( Motor_E2, motorspeed);
}

void forward(byte flag, byte motorspeed)
{
Serial.println("Forward!");

digitalWrite( Motor_M1, HIGH);
digitalWrite( Motor_M2, HIGH);

analogWrite( Motor_E1, motorspeed);
analogWrite( Motor_E2, motorspeed);
}

void backward(byte flag, byte motorspeed)
{
Serial.println("Backward!");

digitalWrite( Motor_M1, LOW);
digitalWrite( Motor_M2, LOW);

analogWrite( Motor_E1, motorspeed);
analogWrite( Motor_E2, motorspeed);
}

void right(byte flag, byte motorspeed)
{
Serial.println("Turn Right! ");

digitalWrite( Motor_M1, HIGH);
digitalWrite( Motor_M2, HIGH);

analogWrite( Motor_E1, motorspeed);
analogWrite( Motor_E2, 0);
}

void left(byte flag, byte motorspeed)
{
Serial.println("Turn Left!");

digitalWrite( Motor_M1, HIGH);
digitalWrite( Motor_M2, HIGH);

analogWrite( Motor_E1, 0);
analogWrite( Motor_E2, motorspeed);
}

80 thoughts on “【雙A計劃】Part4:App Inventor 藍牙遙控 Arduino 雙輪機器人

  1. Money says:

    在使用Motoduino的情況下 如果要加入改變馬達轉速的程式 在App Inventor及Motoduino的程式需要加入哪些?
    我的想法是在App Inventor中加入Slide來改變數值 然後將數值經由藍芽傳送到Motoduino
    Motoduino的motorspeed再經由接收到數值來改變馬達速度
    但因為剛接觸 不太知道這方面的程式該怎麼去寫 不知道能否得到提點

    • CAVEDU 阿吉 says:

      您好, 您的思路是正確的. 首先您必須要把 slider的 thumbposition 透過 bluetoothclient 元件發送出去. 但這時您的藍牙會有兩筆資料: 1. 控制字元 2. 馬達轉速. 我建議可以組合成同一筆資料之之後到 Arduino 端再拆開. 例如送出 “f180” 就是以 180 的速度(最大255) 來前進.

  2. 葉宗葆 says:

    不好意思 我跟朋友全部弄好之後
    藍牙配對成功 Arduino版的程式碼也沒有錯誤
    可是開啟app要操控車子的時候
    輪胎沒有反應 然後手機app出現 unable to write broken pipe

  3. wayne lin says:

    抱歉 我是初學者 請問 如上例的伺服馬達程式 如果我自己組的是一般的直流馬達 我需要在哪裡做修改呢??謝謝

  4. 初學者 says:

    你好 我參考了這幾篇文章 自己做了一個直流馬達的藍芽遙控車
    可是卻不能動 可以幫我看看程式嗎 不知道是哪裡有錯

  5. Alvin says:

    我已經成功將藍牙控制LED on/off 軟體程式在Arduino UNO板上執行,同時也另外由Arduino UNO驅動2相4線的步進馬達. 可是在合併兩個程式後,執行compiling 時,會發生未定義的問題,請問您是否有用藍牙控制2相4線步進馬達的Arduino程式碼可提供參考,謝謝!

  6. 黃國舜 says:

    老師你好
    我想用語音辨識控制藍芽開關並且可以循環使用但我怎麼試還是卡住.可以指點我一下嗎??

  7. 趴擦 says:

    不好意思我是超級新手 請問為什麼我在arduino程式碼那邊複製你上面伺服馬達的程式碼,他卻一直告訴我#include <Servo.h> 有錯誤

  8. 謝雲樹 says:

    老師你好 我是超級新手 請問一下 我是使用arduino uno r3+l298n +DC馬達 事要使用哪一種的程式碼呢? 還有l298n的接法該如何呢 他除了接在PWM角上還有除了IN1 2 3 4 還有ENA換EMB 查了一下那是帶動第一跟第二個馬達的 這樣使用有需要修改程式碼嗎?

  9. 謝雲樹 says:

    不好意思想自在請問一下 我看了一下 藍牙收發接收器(本系列使用JY-MCU04 或 JY-MCU05) 那使用http://goods.ruten.com.tw/item/show?21312195985411這種的藍芽能嗎?

  10. 安安 says:

    你好請問使用arduino uno可以嗎 都接好後 程式碼弄好 範例程式App Inventor 2 打開BTRobot.aia使用模擬器就可以了嗎 ?

    • CAVEDU 阿吉 - 雜工 says:

      首先,請告訴我您選用哪一種直流馬達控制板或是您的電路怎麼接。從手機傳訊號給Arduino都是一樣的,差別只在於Arduino接到訊號之後要幹嘛,這個幹嘛就會根據您實體的線路而定

  11. 嚴晨霖 says:

    你好~
    你們的文章寫得好詳細,很棒!
    但我有一點問題想請問一下
    我使用 Arduino uno版 + HC06 + SG90 servo
    但在我連上後,讓馬達轉動幾下
    卻突然沒有反應了
    這個問題會是什麼呢?
    非常的困擾QQ
    另外請問一下如果接5個馬達
    在電源上有什麼建議嗎?

    • CAVEDU 阿吉 - 雜工 says:

      突然沒反應… 我覺得是電力不足的可能性很高。單顆sg90的耗電量不高,所以用 USB 供電還過得去。如果您要一次用到五顆的話,就要用電池盒獨立對馬達供電啦

      這類型的電池盒在光華商場很好買:http://www.educlub.com.tw/itemphoto/MV-PT-BH341_1.gif 把紅黑線拉到麵包板上的 V / GND軌,再讓馬達的電拉到同一軌上就好

  12. 賴一 says:

    你好,我參考這幾篇文章,在app寫好arduino自走車的開跟關,我已經用swtich判斷使車子自走,請問要如何使用藍芽來啟動自走車跟停止。我有使用過while來寫,是可以用app來使車子啟動,不過我無法使他跳出迴圈,不知道哪裡出問題,請問能幫我看看程式嗎?

  13. LinYuWei says:

    想問Arduino 藍牙遙控機器人 – 直流馬達版那個程式碼是已經有加藍芽驅動了嗎?
    我是用HC-05的藍芽接收器和Arduino Mega2560+L289N馬達模組

  14. barley says:

    我看您的影片,似乎是同時按下同時發送字元給arduino,所以我想請問您,如果要同時按app的按鈕,程式改如何撰寫?arduino的部分也該如何改良。

  15. jeff85898 says:

    請問你們這篇文章中,Arduino 藍牙遙控機器人 – 直流馬達版的程式碼是已經有加藍芽驅動了嗎?
    我是用HC-06藍芽接收器和Arduino UNO R3+L293D馬達模組,程式碼需要如何做修改呢,方便的話,麻煩提供修改的建議,謝謝

  16. MAX says:

    剛剛那個問題解決了.. 想問一點題外話
    我目前uno有接溫濕度感測器,appinventor已經可以接收溫度溼度這種數字的字元。
    請問appinventor的藍芽有辦法接收影像嗎?如果uno有接攝影鏡頭的話
    想完成類似探勘車那樣子

  17. MAX says:

    請問這段的意思是?
    case 65: //Return distance value
    for(i=5;i>0;i–){
    dis[i] = t%10;
    t/=10;
    }
    //Pack value
    for(i=0;i<=5;i++)
    BTSerial.write(dis[i]);
    //Return value
    break;
    default:
    break;

    • 鈺莨 says:

      你好,圓仔:
      要判斷switch有無觸發的簡易方法,就是在判別式中加上Serial.println(),然後以序列埠監控視窗來看狀態,
      例如:
      switch(pp){
      case ‘f’: //Forward
      Up();
      Serial.println(f);
      break;
      表示如果arduino 接收到’f’字元,序列埠監控視窗就會顯示f;如果沒有,就代表沒有跑進判別式裡。

    • 鈺莨 says:

      你好,yun:
      文章使用的是Parallax 連續旋轉伺服機,配合BB CAR使用,是需要通電時以一字起子微調可變電阻校正的(校正至馬達停止轉動為止),如果你使用的馬達跟文章中馬達使用的是一致的話,有可能你沒有先校正馬達

  18. jackaXX says:

    你好,感謝你們的技術分享!!
    我想請問一下我連接藍芽也正常,車子也有正常行走,但我輸入一個值傳送到arduino後,車子有讀取到也正常行走,但HC-06藍芽就會斷開,要在重新接上藍芽才可輸入第二個動作,有時也會斷斷續續的,請問這有可能是什麼問題?
    我用的是HC-06藍芽接收器、板子是Arduino mega2560、L298P馬達模組 謝謝

  19. min says:

    您好,我程式和手機app都是用一樣的,馬達也校正到不會一直自動旋轉後,手機怎麼按按鈕都無法讓馬達有反應,藍芽也可以確實連接手機,電池是用五個3號電池,怕是不是供電不夠

發佈留言

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