第1部分:用小型Arduino相容設備(M5Stack)享受電子製作的樂趣
第2部分:透過M5Stack使用馬達驅動器
大家好,我是吉田!
本系列連載將為您介紹使用小型Arduino相容設備M5Stack製作遙控車的過程。這次我們將在M5Stack上添加各種感測器,以便實現自動控制。M5Stack有很多引腳,因此僅需插入接近感測器或距離感測器即可輕鬆增加相應的功能。
搭載了ESP32、顯示器、感測器等的Arduino相容設備
透過發射紅外光並測量其反射光來測量光強和接近程度。
發射超聲波並透過其反彈聲波來測量距離的模組。
使用“I2C”通信方式與Grove引腳連接即可使用的馬達驅動器
我希望遙控車在行駛時,在即將撞到障礙物或即將從桌子上掉下來的情況下,能夠自動避讓並避免掉落。
首先,我們使用接近感測器來判斷是否即將掉落。接近感測器我們用
ROHM感測器評估套件
中的照度、接近一體型感測器模組(RPR-0521RS)。
該感測器透過發射紅外LED光並檢測其反射光來測量物體等的接近程度。另外,還可以透過亮度感測器來同時測量亮度。
要使用該感測器,需要進入下面的ROHM感測器頁面並下載Arduino用的庫。
https://www.rohm.com.tw/sensor-shield-support/ps-als-sensor
在ROHM官網上下載zip檔後,透過其功能表安裝Arduino IDE庫。
接下來,我們把M5Stack和感測器連接起來。M5Stack上下有8個引腳,左右有15個引腳,背面寫有引腳排列編號。Arduino的GPIO(輸入輸出引腳)與數位標注的引腳編號相對應。
照度、接近一體型感測器使用“I2C”通訊方式。我們用M5Stack下方引腳中的SDA=G21和SCL=G22進行I2C通信。請按照下表連接感測器和M5Stack。
感測器側引腳 (右起) |
M5Stack側 (下方) |
VDO | 3.3V (橙) |
GND | GND (藍) |
SDA | GPIO21 (黃) |
SCL | GPIO22 (綠) |
INT | NA |
感測器和M5Stack連接好之後,從Arduino IDE的草圖範例中選擇前面安裝的範例PRP-0521RS。
添加到範例中之後還需要在M5Stack的顯示器中顯示等,所以要將其另存為“M5Stack_PRP-0521RS.ino”。在這裡添加如下程式(第1、11〜14、20、29〜30、36、39行)。
[M5Stack_PRP-0521RS.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 |
#include <M5Stack.h> #include <Wire.h> #include <RPR-0521RS.h> RPR0521RS rpr0521rs; void setup() { byte rc; Serial.begin(115200); while (!Serial); Wire.begin(21,22); M5.begin(); M5.Lcd.setTextSize(2); M5.Lcd.setRotation(3); rc = rpr0521rs.init(); } void loop() { Wire.begin(21,22); byte rc; unsigned short ps_val; float als_val; byte near_far; rc = rpr0521rs.get_psalsval(&ps_val, &als_val); if (rc == 0) { Serial.print(F("RPR-0521RS (Proximity) = ")); M5.Lcd.setCursor(10, 20); M5.Lcd.printf("RPR-0521RS: "); 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.printf("M5 Near!"); } else { Serial.println(F(" Far")); M5.Lcd.printf("M5 Far !"); } } delay(500); } |
透過M5Stack使用該程式時,需要更改一項。打開文件“PRP-0521RS.cpp”並刪除“#include”部分中的“avr/”(通常安裝的庫位於Arduino > Libraries > RPR-0521RS中)。進行該操作後,M5Stack就可以正常讀取pgmspace.h了。
[PRP-0521RS.cpp的位置,更改前。刪除紅框部分的“avr/”。 ]
完成該更改後,運行“M5Stack_PRP-0521RS.ino”。將會開始自動測量,當您將手指靠近設備時,螢幕上會出現如圖所示的“Near!”消息。
接下來,我們在M5Stack上安裝距離感測器,以便能夠檢測出並避讓障礙物。我們使用這種名為“HC-SR04”的
超聲波距離感測器。這是一種能夠發射超聲波並透過其反彈聲波來測量距離的模組。
按照下表和照片所示連接該超聲波感測器。
感測器側引腳 (左起) |
M5Stack側 (左側側面) |
VCC | 5V (紅) |
Trig | GPIO2 (橙) |
Echo | GPIO5 (黃) |
GND | GND (黑) |
驅動這個距離感測器的程式“M5Stack_Dist.ino”如下。由於G2與輸出TRIG連接,G5與輸入ECHO連接,因此程式中分別指定了GPIO編號。
[M5Stack_Dist.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 |
#include <M5Stack.h> #define TRIG 2 #define ECHO 5 int times; int distance; void setup() { Serial.begin(115200); while (!Serial); pinMode(TRIG, OUTPUT); pinMode(ECHO, INPUT); M5.begin(); M5.Lcd.setTextSize(2); M5.Lcd.setRotation(3); } void loop() { // 發射超聲波 digitalWrite(TRIG, HIGH); delayMicroseconds(10); digitalWrite(TRIG, LOW); // 接收超聲波 times = pulseIn(ECHO, HIGH); distance = (int)(times * 0.017); // 在監視器、顯示器上顯示 Serial.println(distance); M5.Lcd.setCursor(0, 0); M5.Lcd.print(distance); delay(500); } |
運行該程式,當將手指靠近距離感測器時,就會測量出距離。該距離資料表示串口監視器和M5Stack螢幕與手等障礙物之間的距離。
最後,要能夠根據感測器的測量結果進行控制,以避讓障礙物並避免從桌子上掉落下來。首先,我們需要將馬達驅動器、車輪等連同傳感器重新連接起來。將馬達驅動器連接在Grove引腳上,將距離感測器設定在容易捕捉前方情況的位置,將接近感測器設定在下方。
還要創建一個使感測器和馬達聯動的程式。在程式中,當距離感測器測到距離小於5cm時,即判斷為“附近有障礙物”。另外,當接近感測器測量到與地板之間的接近程度變為“Far”時,即判斷為“即將從桌子邊緣掉落”。此時,馬達將會反轉,以避免掉落(避讓障礙物)。否則將繼續前進。
範例程式“M5Stack_Near_Dist_Motor.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 |
#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 void setup() { Serial.begin(115200); while (!Serial); byte rc; rc = rpr0521rs.init(); pinMode(TRIG, OUTPUT); pinMode(ECHO, INPUT); Motor.begin(I2C_ADDRESS); Wire.begin(21,22); M5.begin(); M5.Lcd.setTextSize(4); M5.Lcd.setCursor(10,0); M5.lcd.print("M5 Near Dist Motor"); } void loop() { Wire.begin(21,22); byte rc; unsigned short ps_val; float als_val; byte near_far; M5.lcd.clear(); M5.Lcd.setCursor(10,0); M5.lcd.print("M5 Near Dist Motor"); 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); M5.Lcd.setCursor(10,150); // 當距離小於6時,如果接近程度繼續變大,將使馬達反轉 if ( ((distance > 0) and (distance < 6)) or (near_far != RPR0521RS_NEAR_VAL) ) { Motor.speed(MOTOR1, 100); Motor.speed(MOTOR2, -100); delay(800); Motor.speed(MOTOR1, 100); Motor.speed(MOTOR2, 100); M5.lcd.print("Danger!"); delay(800); } else { // 如果沒有障礙物就繼續前進 Motor.speed(MOTOR1, -100); Motor.speed(MOTOR2, 100); M5.lcd.print("Forward!"); } delay(300); } |
程式準備好後,將其導入M5Stack。當您接通電源後,車輪將開始轉動並向前行駛。請您確認一下,在遙控車遇到障礙物或要從桌子上掉落下來時,馬達能否反轉。
行駛中的視頻如下
在這個連載系列中,將為您介紹使用M5Stack進行遙控並實現自動駕駛小車的製作過程。在第三部分中,我們使用距離感測器來確認了前方物體,並使用接近感測器來確認了接近情況。
我們還讓這兩種感測器和馬達的旋轉聯動實現了自動駕駛。怎麼樣,效果還不錯吧?由於還需要微調與障礙物之間的距離設定、反轉時間等參數,因此您需要一邊試用一邊調整數值。
M5Stack仍然有可以使用的引腳,因此您還可以嘗試添加其他感測器來實現相應的功能,這可能會更有趣。比如,可以讓它在自由行駛的同時測量室內溫度和空氣清潔度。
在下一部分中,我們將介紹透過智慧手機等從外部來控制遙控車的方法,敬請期待!
本系列連載一覽
第1部分:用小型Arduino相容設備(M5Stack)享受電子製作的樂趣
第2部分:透過M5Stack使用馬達驅動器
第3部分:透過M5Stack使用感測器實現自動駕駛和自動避讓功能(本章)