第1部分:用小型Arduino相容設備(M5Stack)享受電子製作的樂趣
第2部分:透過M5Stack使用馬達驅動器
第3部分:透過M5Stack使用感測器實現自動駕駛和自動避讓功能
大家好,我是吉田!
本系列連載將為您介紹使用小型Arduino相容設備M5Stack製作遙控車的過程。在前面的部分中,我們已經用馬達驅動器讓遙控車能夠前後左右移動,並透過感測器實現了自動駕駛。在本文中,也就是本系列的最後一部分中,我們將實現從外部遙控這輛遙控車。這次,我們將會導入一種能夠透過智慧手機操作5Stack的名為“Blynk”的機制。
搭載了ESP32的Arduino相容設備
與Grove引腳連接即可使用的馬達驅動器
透過發射紅外光來測量光強和接近程度。
透過發射超聲波來測量距離的模組
我們需要導入名為“Blynk”的應用程式,以便透過智慧手機操作用M5Stack製作而成的遙控車。
在iOS或Android系統中搜索並安裝Blynk應用程式。
下載後,打開應用程式,會被要求建立一個帳戶,請用您的郵箱等註冊並登錄。在第一個畫面中,會出現“New Project”,需要給它命名並建立新專案。
在詳細設定中,Device請選擇“ESP32 Dev Board”,Connection請選擇“WiFi”。然後,將會出現一個空白的專案畫面,這就表示智慧手機的準備工作完成了。
接下來,在要程式設計的Arduino IDE中,獲取Arduino用的Blynk程式庫。從下面的連結下載程式庫並透過圖中功能表添加zip檔。
Blynk的Github頁面
現在,已經做好在手機和Arduino IDE上使用Blynk的準備了。
我們已經將M5Stack與智慧手機聯結起來了,下面需要在畫面上添加一個操作功能。
當點擊Blynk應用程式的畫面時,會出現可以從右側添加的Widget(功能),我們先添加“Button”。
在這裡,我希望在按下該按鈕時能夠從M5Stack的揚聲器發出嘟嘟聲。在按鈕的詳細設定畫面上,OUTPUT選擇“Virtual”並指定V1。稍後將在M5Stack上指定V1,所以請記住這裡的設定。您還可以選擇僅在按下時發送信號的“PUSH”,並設定標籤名稱(Beep)等。
最後,要獲取一個與M5Stack連接的權杖。權杖可以在專案創建時透過e-mail發送,也可透過打開“Project Settings”複製下方的“AUTH TOKEN”。稍後將透過Arduino IDE指定。
現在,需要使用Arduino IDE進行程式設計了。首先,拷貝一個名為“Speaker”的草圖範例作為M5Stack的範例。
在該範例中添加以下第3〜9、13〜22、28〜29、36行的內容。在草圖的xxxx部分添加前面複製的AUTH TOKEN。yyyy和zzzz是您Wifi環境的用戶名和密碼。此外,當按下V1按鈕時,要能聽到嘟嘟聲。
[M5Stack_Speaker_Blynk.ino]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
#include <M5Stack.h> #include <WiFi.h> #include <WiFiClient.h> #include <BlynkSimpleEsp32.h> char auth[] = "xxxx”; //輸入Blynk應用程式的YourAuthToken char ssid[] = "yyyy"; //輸入Wifi的ID和密碼 char pass[] = "zzzz"; #define NOTE_DH2 661 int BEEP_Flag = 0; BLYNK_WRITE(V1) { BEEP_Flag = param.asInt(); if(BEEP_Flag == 1){ M5.Lcd.printf("Blynk wasPressed \r\n"); M5.Speaker.beep(); //beep } M5.update(); } void setup() { // Initialize the M5Stack object M5.begin(); M5.Lcd.setTextSize(3); Blynk.begin(auth, ssid, pass); M5.Power.begin(); M5.Lcd.printf("M5Stack Speaker:\r\n"); } void loop() { Blynk.run(); if(M5.BtnA.wasPressed()) { M5.Lcd.printf("A wasPressed \r\n"); M5.Speaker.beep(); //beep } if(M5.BtnB.wasPressed()) { M5.Lcd.printf("B wasPressed \r\n"); M5.Speaker.tone(NOTE_DH2, 200); //frequency 3000, with a duration of 200ms } M5.update(); } |
運行此程式後,當Wi-Fi連接完成時,在串口監視器上會顯示下列畫面。在與智慧手機相同的Wifi環境下,將會從Blynk連接M5Stack。當按下螢幕上的按鈕時,應該會發出嘟嘟聲。
現在,我們需要添加一個透過智慧手機驅動M5Stack的馬達的功能。有現成的“Joystick”(操縱杆)可以用來控制行進方向和旋轉速度,我們可以在手機畫面上對其進行設定。Joystick的輸出為V0,將其輸出範圍設定為-50到50。
最後,需要編寫透過Blynk控制M5Stack的程式。將Blynk的描述添加到在上一部分中創建的感測器與馬達聯動的程式“M5Stack_Near_Dist_Motor.ino”中。
下面的第15〜31、96、116行是前面的揚聲器所用的部分。
在第33〜93、111〜112、123〜126、162〜163行添加了根據Joystick控制馬達的描述。
[M5Stack_Near_Dist_Motor_Blynk.ino]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
#include <M5Stack.h> #include <Wire.h> #include <RPR-0521RS.h> RPR0521RS rpr0521rs; #define TRIG 2 #define ECHO 5 int times; int distance; #include "Grove_I2C_Motor_Driver.h" #define I2C_ADDRESS 0x0f #include <WiFi.h> #include <WiFiClient.h> #include <BlynkSimpleEsp32.h> char auth[] = "xxxx”; //輸入Blynk應用程式的YourAuthToken char ssid[] = "yyyy"; //輸入Wifi的ID和密碼 char pass[] = "zzzz"; int BEEP_Flag = 0; BLYNK_WRITE(V1) { BEEP_Flag = param.asInt(); if(BEEP_Flag == 1){ M5.Lcd.printf("Blynk wasPressed \r\n"); M5.Speaker.beep(); //beep } M5.update(); } long Speed; long Speed1, Speed2; long SpeedL, SpeedR; //接收操縱杆的資料 BLYNK_WRITE(V0) { M5.Lcd.setCursor(10,180); long x = param[0].asInt(); long y = param[1].asInt(); Speed = sqrt(x*x+y*y); if(Speed > 50){ Speed = 50; } SpeedR = Speed - Speed1; SpeedL = Speed - Speed2; if(y >= 0){ if(x >= 0){ Speed1 = abs(x); Speed2 = 0; }else{ Speed1 = 0; Speed2 = abs(x); } Serial.print(" R:"); Serial.print(SpeedR); Serial.print(" L:"); Serial.println(SpeedL); Motor.speed(MOTOR1, -SpeedR); Motor.speed(MOTOR2, SpeedL); M5.Lcd.print("Fwd!"); delay(500); Motor.speed(MOTOR1, 0); Motor.speed(MOTOR2, 0); }else{ if(x >= 0){ Speed1 = abs(x); Speed2 = 0; }else{ Speed1 = 0; Speed2 = abs(x); } Serial.print(" -R:"); Serial.print(SpeedR); Serial.print(" -L:"); Serial.println(SpeedL); Motor.speed(MOTOR1, SpeedR); Motor.speed(MOTOR2, -SpeedL); M5.Lcd.print("Back!"); delay(500); Motor.speed(MOTOR1, 0); Motor.speed(MOTOR2, 0); } } void setup() { Blynk.begin(auth, ssid, pass); Serial.begin(115200); while (!Serial); byte rc; rc = rpr0521rs.init(); pinMode(TRIG, OUTPUT); pinMode(ECHO, INPUT); Motor.begin(I2C_ADDRESS); M5.begin(); M5.Lcd.setTextSize(4); Wire.begin(21,22); M5.Lcd.setCursor(10,0); M5.Lcd.println(ssid); } void loop() { Blynk.run(); byte rc; unsigned short ps_val; float als_val; byte near_far; M5.lcd.clear(); M5.Lcd.setCursor(10,0); M5.lcd.print("M5 Blynk"); M5.Lcd.setCursor(10,50); rc = rpr0521rs.get_psalsval(&ps_val, &als_val); if (rc == 0) { Serial.print(F("RPR-0521RS (Proximity) = ")); Serial.print(ps_val); Serial.print(F(" [count]")); near_far = rpr0521rs.check_near_far(ps_val); if (near_far == RPR0521RS_NEAR_VAL) { Serial.println(F(" Near")); M5.lcd.print("Near!"); } else { Serial.println(F(" Far")); M5.lcd.print("Far!"); } } digitalWrite(TRIG, HIGH); // 發射超聲波 delayMicroseconds(10); digitalWrite(TRIG, LOW); times = pulseIn(ECHO, HIGH); // 接收超聲波 distance = (int)(times * 0.017); Serial.println(distance); // 在顯示器上顯示 M5.Lcd.setCursor(10, 100); M5.Lcd.print(distance); if ( ((distance > 0) and (distance < 6)) or (near_far != RPR0521RS_NEAR_VAL) ) { Motor.speed(MOTOR1, 50); Motor.speed(MOTOR2, -50); delay(800); Motor.speed(MOTOR1, 50); Motor.speed(MOTOR2, 50); M5.Lcd.setCursor(10,150); M5.lcd.print("Danger!"); delay(800); } else { Motor.speed(MOTOR1, 0); Motor.speed(MOTOR2, 0); } delay(300); } |
下面我們來嘗試操縱遙控車。和前面一樣,進入相同的Wi-Fi環境,連接M5Stack。當您前後左右移動操縱杆時,M5Stack是否跟著做出了相應的移動?當遙控車接近牆壁或者要從桌子上掉落下來時,和上次一樣,它會避開。
實際行駛的視頻如下。
您可以根據馬達的連接方法來調整旋轉方向、轉數、轉速等。
在本系列連載中,為您介紹了使用M5Stack自動駕駛遙控車的製作過程。
使用可以從智慧手機連接M5Stack的應用程式Blynk,還能輕鬆添加透過智慧手機操縱遙控車的功能。我們成功地使按鈕與M5Stack揚聲器聯動起來,並實現了透過操縱杆的控制而前後左右移動。
Blynk有各種各樣的Widget,還可以根據M5Stack的感測器等來添加更多不同的功能,這樣會更有趣。比如,您還可以考慮怎樣將物體的接近程度以及溫濕度感測器測量到的值等在顯示器上顯示出來。
盼望您大膽嘗試,讓您的創意變成現實!感謝您閱讀本系列文章!
本系列連載一覽
第1部分:用小型Arduino相容設備(M5Stack)享受電子製作的樂趣
第2部分:透過M5Stack使用馬達驅動器
第3部分:透過M5Stack使用感測器實現自動駕駛和自動避讓功能
劇終篇:實現M5Stack與智慧手機聯動控制(本章)