###### tags: `選修` # 小阿丟車 ## 一、軟體安裝 1. ### [Ardunio IDE](https://www.arduino.cc/en/Main/Software) 2. ### 主控制器(Nano) 驅動程式 - 安裝 [CH341SER\SETUP.EXE](http://cs.cysh.cy.edu.tw/computer_club/arducar/CH341SER.7z) 3. ### sonar library 補充 - 將 [HCSR04Ultrasonic](http://cs.cysh.cy.edu.tw/computer_club/arducar/HCSR04Ultrasonic.7z) 資料夾,複製貼在 C:\Program Files(x86)\Arduino\libraries\ 之下 <br /> ## 二、部位說明及控制IC接腳對照表 1. ### 部位說明 ![](https://i.imgur.com/5nU9ZFb.png) 2. ### 控制IC接腳對照表 |腳位|名稱 | 功能 | |:-:|--------|------------| |2|TX|HC-06藍芽TX |3|Buzzer|蜂鳴器 |4|RX|HC-06藍芽RX |<font color=red>5</font>|<font color=red>MR2</font>|<font color=red>右馬達後腳2</font> |<font color=red>6</font>|<font color=red>MR1</font>|<font color=red>右馬達前腳1</font> |7|Trig|SR-04超音波Trig |7|B2|LED2 |8|B1|LED1 |9|servo|伺服機訊號腳 |<font color=red>10</font>|<font color=red>ML1</font>|<font color=red>左馬達前腳1</font> |<font color=red>11</font>|<font color=red>ML2</font>|<font color=red>左馬達後腳2</font> |12|RGB|RGB LED |13|B3|LED3 |13|Echo|SR-04超音波Echo |A0|VR|可變電阻 |A1|CDS_R|光敏電阻(右) |A2|IR_RR|紅外線循跡(最右) |A3|IR_R|紅外線循跡(右) |A4|IR_L|紅外線循跡(左) |A5|IR_LL|紅外線循跡(最左) |A6|CDS_L|光敏電阻(左) |A7|VinDet|電池電壓偵測 | <br /> ## 三、LED 1. ### LED 電路示意圖 ![](https://i.imgur.com/TRVpt5g.png =400x) 2. ### 按鍵控制 - 當B1按鍵被按住,D8導通,LED1亮 - 當B1按鍵被放開,D8斷路,LED1滅 3. ### 實作步驟 - 開啟 Arduino IDE 或 \*.ino - 選擇開發板: Arduino Nano - 選擇處理器:ATmega328P(Old Bootloader) - 選擇連接序列埠: COM? (至裝置管理員/連接埠(COM和LPT)查詢) - 驗證 / 編譯(Ctrl+R) - 上傳(Ctrl+U) :::info EX3_1:使LED2快速閃爍10次 ::: ``` javascript= void setup() { // 執行一次的程式碼 pinMode(7,OUTPUT); for(int i=0;i<10;i++) { digitalWrite(7,0); delay(1000); digitalWrite(7,1); delay(1000); } } void loop() { // 不斷循環執行的程式碼 } ``` :::info EX3_2:使LED2持續不停快速閃爍 ::: <br /> ## 四、Buzzer 1. ### tone(腳位,音頻,時間) :::info EX4_1:隨意發出一些聲音 ::: ``` javascript= /* Do(523Hz) Re(587Hz) Mi(659Hz) Fa(698Hz) So(784Hz) La(880Hz) Si(988Hz) 高音 Do (1047Hz) */ const byte Buzzer = 3; // 蜂鳴器的接腳 D3 void setup() { pinMode(Buzzer,OUTPUT); } void loop() { tone(Buzzer, 523, 100); delay(500); } ``` :::info EX4_2:小蜜蜂編曲 :mega: 先下載 [DoReMi.h](http://cs.cysh.cy.edu.tw/computer_club/arducar/DoReMi.h) 置於相同資料夾 ::: ``` javascript= #include "DoReMi.h" //==== 接腳定義 ==== #define TX 2 //HC-06藍芽TX #define Buzzer 3 //蜂鳴器 #define RX 4 //HC-06藍芽RX #define MR2 5 //右馬達輸入2 #define MR1 6 //右馬達輸入1 #define Trig 7 //SR-04超音波Trig #define B2 7 //按鈕2 #define B1 8 //按鈕1 #define servo 9 //伺服機訊號腳 #define ML1 10 //左馬達輸入1 #define ML2 11 //左馬達輸入2 #define RGB 12 //RGB LED #define B3 13 //按鈕3 #define Echo 13 //SR-04超音波Echo #define VR A0 //可變電阻 #define CDS_R A1 //光敏電阻(右) #define IR_RR A2 //TCRT5000紅外線尋跡(最右) #define IR_R A3 //TCRT5000紅外線尋跡(右) #define IR_L A4 //TCRT5000紅外線尋跡(左) #define IR_LL A5 //TCRT5000紅外線尋跡(最左) #define CDS_L A6 //光敏電阻(左) #define VinDet A7 //電池電壓偵測 //================== int melody[] = {0,Do,Re,Mi,Fa,So,La,Si,HDo}; void setup() { pinMode(Buzzer,OUTPUT); } void loop() { tone(Buzzer,melody[5],300); delay(300); tone(Buzzer,melody[3],300); delay(300); tone(Buzzer,melody[3],600); delay(600); tone(Buzzer,melody[4],300); delay(300); tone(Buzzer,melody[2],300); delay(300); tone(Buzzer,melody[2],600); delay(600); tone(Buzzer,melody[1],300); delay(300); tone(Buzzer,melody[2],300); delay(300); tone(Buzzer,melody[3],300); delay(300); tone(Buzzer,melody[4],300); delay(300); tone(Buzzer,melody[5],300); delay(300); tone(Buzzer,melody[5],300); delay(300); tone(Buzzer,melody[5],600); delay(600); } ``` :::info EX4_3:來回轉動可變電組,發出傳腦魔音 :mega: 利用可變電阻升降電壓,控制器轉換成相對的頻率。 ::: ``` javascript= #include "DoReMi.h" //==== 接腳定義 ==== #define TX 2 //HC-06藍芽TX #define Buzzer 3 //蜂鳴器 #define RX 4 //HC-06藍芽RX #define MR2 5 //右馬達輸入2 #define MR1 6 //右馬達輸入1 #define Trig 7 //SR-04超音波Trig #define B2 7 //按鈕2 #define B1 8 //按鈕1 #define servo 9 //伺服機訊號腳 #define ML1 10 //左馬達輸入1 #define ML2 11 //左馬達輸入2 #define RGB 12 //RGB LED #define B3 13 //按鈕3 #define Echo 13 //SR-04超音波Echo #define VR A0 //可變電阻 #define CDS_R A1 //光敏電阻(右) #define IR_RR A2 //TCRT5000紅外線尋跡(最右) #define IR_R A3 //TCRT5000紅外線尋跡(右) #define IR_L A4 //TCRT5000紅外線尋跡(左) #define IR_LL A5 //TCRT5000紅外線尋跡(最左) #define CDS_L A6 //光敏電阻(左) #define VinDet A7 //電池電壓偵測 //================== void setup() { pinMode(Buzzer,OUTPUT); pinMode(VR,INPUT); } void loop() { int val = analogRead(VR); // 讀取可變電阻(數值介於 0 到 1023) val = map(val, 0, 1023, 262, 1976); // 把 0 - 1023 的數值按比例縮放為 262 - 1976 的數值 tone(Buzzer,val); delay(20); } ``` <br /> ## 五、直流馬達 1. ### 馬達驅動IC:H橋IC_TA7291SG ![](https://i.imgur.com/HCNk453.png) 2. ### 轉彎控制 - 大半徑右轉:右輪不動,左輪往前 - 小半徑右轉:右輪往後,左輪往前 ![](https://i.imgur.com/t5ZFOGP.png) :::info EX5_1:調整左右馬達速度,讓車子可直線前進。 #define SpeedR 200 #define SpeedL 165 EX5_2:試試右輪往後和右輪停止的右轉有何不同? void Right(){ digitalWrite(MR1,LOW); analogWrite(MR2,SpeedR); // 右輪往後 // digitalWrite(MR2,LOW); // 右輪不動 analogWrite(ML1,SpeedL); // 左輪往前 digitalWrite(ML2,LOW); } EX5_3:讓車子走正方形1圈。 ::: ``` javascript= //==== 接腳定義 ==== #define TX 2 //HC-06藍芽TX #define Buzzer 3 //蜂鳴器 #define RX 4 //HC-06藍芽RX #define MR2 5 //右馬達輸入2 #define MR1 6 //右馬達輸入1 #define Trig 7 //SR-04超音波Trig #define B2 7 //按鈕2 #define B1 8 //按鈕1 #define servo 9 //伺服機訊號腳 #define ML1 10 //左馬達輸入1 #define ML2 11 //左馬達輸入2 #define RGB 12 //RGB LED #define B3 13 //按鈕3 #define Echo 13 //SR-04超音波Echo #define VR A0 //可變電阻 #define CDS_R A1 //光敏電阻(右) #define IR_RR A2 //TCRT5000紅外線尋跡(最右) #define IR_R A3 //TCRT5000紅外線尋跡(右) #define IR_L A4 //TCRT5000紅外線尋跡(左) #define IR_LL A5 //TCRT5000紅外線尋跡(最左) #define CDS_L A6 //光敏電阻(左) #define VinDet A7 //電池電壓偵測 //================== #define SpeedR 200 //馬達速度(0-255) #define SpeedL 165 //馬達速度(0-255) void setup() { pinMode(MR1,OUTPUT); pinMode(MR2,OUTPUT); pinMode(ML1,OUTPUT); pinMode(ML2,OUTPUT); } void loop() { Forward(); delay(3000); // 前進3秒 Stop(); elay(3000); } void Forward(){ analogWrite(MR1,SpeedR); //右輪往前 digitalWrite(MR2,LOW); analogWrite(ML1,SpeedL); //左輪往前 digitalWrite(ML2,LOW); } void Backward(){ digitalWrite(MR1,LOW); analogWrite(MR2,SpeedR); //右輪往後 digitalWrite(ML1,LOW); analogWrite(ML2,SpeedL); //左輪往後 } void Right(){ digitalWrite(MR1,LOW); analogWrite(MR2,SpeedR); //右輪往後 // digitalWrite(MR2,LOW); // 右輪不動 analogWrite(ML1,SpeedL); //左輪往前 digitalWrite(ML2,LOW); } void Left(){ analogWrite(MR1,SpeedR); //右輪往前 digitalWrite(MR2,LOW); digitalWrite(ML1,LOW); analogWrite(ML2,SpeedL); //左輪往後 } void Stop(){ digitalWrite(MR1,LOW); digitalWrite(MR2,LOW); digitalWrite(ML1,LOW); digitalWrite(ML2,LOW); } ``` <br /> ## 六、紅外線 1. ### 紅外線 IR 數值及偵測距離 - 數值大表示高反射(白) - 數值小表示高反射(黑) - 偵測距離 ![](https://i.imgur.com/hw6eIZz.png) :::info EX6_1:紅外線測試 :mega:打開序列埠監控視窗 ::: ``` javascript= //==== 接腳定義 ==== #define IR_RR A2 //TCRT5000紅外線尋跡(最右) #define IR_R A3 //TCRT5000紅外線尋跡(右) #define IR_L A4 //TCRT5000紅外線尋跡(左) #define IR_LL A5 //TCRT5000紅外線尋跡(最左) //================== int S1,S2,S3,S4; void setup() { Serial.begin(9600); // 啟用串列埠 pinMode(A2,INPUT); pinMode(A3,INPUT); pinMode(A4,INPUT); pinMode(A5,INPUT); } void loop() { S1=analogRead(IR_LL); S2=analogRead(IR_L); S3=analogRead(IR_R); S4=analogRead(IR_RR); Serial.print("IR_LL:"); Serial.println(S1); Serial.print("IR_L:"); Serial.println(S2); Serial.print("IR_R:"); Serial.println(S3); Serial.print("IR_RR:"); Serial.println(S4); delay(1000); } ``` 2. ### 循跡原理 - IR 在黑線二側 -> 直線前進 ![](https://i.imgur.com/T1GgpaV.png =300x) - 左側 IR 壓線 -> 左轉 ![](https://i.imgur.com/PsfAO24.png =200x) - 右側 IR 壓線 -> 右轉 ![](https://i.imgur.com/1cDcQ56.png =200x) :::info EX6_2:紅外線循跡自走車。調整馬達速度與IR臨界值,找到不會衝出軌道的最高車速。 ::: ``` javascript= //==== 接腳定義 ==== #define MR2 5 //右馬達輸入2 #define MR1 6 //右馬達輸入1 #define ML1 10 //左馬達輸入1 #define ML2 11 //左馬達輸入2 #define IR_RR A2 //TCRT5000紅外線尋跡(最右) #define IR_R A3 //TCRT5000紅外線尋跡(右) #define IR_L A4 //TCRT5000紅外線尋跡(左) #define IR_LL A5 //TCRT5000紅外線尋跡(最左) ////========調整參數========== #define Speed 160 //馬達速度(0-255) int IR=500; //紅外線臨界值 int S1,S2,S3,S4; void setup() { Serial.begin(9600); //啟用串列埠 pinMode(IR_RR,INPUT); pinMode(IR_R,INPUT); pinMode(IR_L,INPUT); pinMode(IR_LL,INPUT); } void loop() { S1=analogRead(IR_LL); S2=analogRead(IR_L); S3=analogRead(IR_R); S4=analogRead(IR_RR); analogWrite(MR1,Speed); // 前進 digitalWrite(MR2,LOW); analogWrite(ML1,Speed); digitalWrite(ML2,LOW); if(S2<IR) //左側IR壓線->左轉 { analogWrite(MR1,Speed); digitalWrite(MR2,LOW); analogWrite(ML1,LOW); digitalWrite(ML2,LOW); } if(S3<IR) //右側IR壓線->右轉 { analogWrite(MR1,LOW); digitalWrite(MR2,LOW); analogWrite(ML1,Speed); digitalWrite(ML2,LOW); } } ``` :::info :tada: 紅外線循跡自走車競賽。俢改EX6_2程式碼,使完成賽道時間最短。 :mega: 可能賽道:直角轉彎、V型彎、泥淖、髮夾彎… ![](https://i.imgur.com/woxAQsT.jpg) 提示: 1.參考 EX5,將前進、轉彎寫成函式,會較方便。 2.利用IR_RR和IR_LL,讓車子衝出軌道後還可修正回來。 3.參考語法 (1) 邏輯:&&(and)、||(or) (2) if else (3) if elseif elseif … else (4) do{ }while(); 4.[Arduino 語法參考網站](https://sites.google.com/site/csjhmaker/arduino-ji-chu/arduino-yu-fa-can-kao) ::: <br /> ## 七、超音波 1. ### 超音波測距 - 人耳可聽到的聲音頻率由16Hz 到 20KHz,超音波頻率>20KHz。 - 音速在空氣中約為343公尺/秒。 - 利用音速與反射時間可以換算障礙物的距離。 - 超音波感測器(HC-SR04)可探測距離為 2cm-400cm,精度為 0.3 cm,感應角度為 15 度。 ![](https://i.imgur.com/yeNCpXw.jpg =200x) ![](https://i.imgur.com/Zk9SeA4.png =330x) :::info EX7_1:超音波測量花板有多高。 :mega: 打開序列埠監控視窗 EX7_2:解開註解,模擬倒車雷達。 ::: ``` javascript= #include <Ultrasonic.h> #define Trig 7 //SR-04超音波Trig #define Echo 13 //SR-04超音波Echo #define Buzzer 3 //蜂鳴器 Ultrasonic ultrasonic(Trig,Echo); void setup(){ Serial.begin(9600); //啟用串列埠 pinMode(Trig,OUTPUT); //超音波的Trig,作用為發出聲波。同時也是按鈕2,使用按鈕2時要註解這行。 pinMode(Echo,INPUT); //超音波的Echo,取得回音的時間。同時也是按鈕3,使用按鈕3時要註解這行。 pinMode(Buzzer, OUTPUT); } void loop(){ float cmMsec; long microsec = ultrasonic.timing(); cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM); Serial.print(microsec); Serial.print(" MS, "); Serial.print(cmMsec); Serial.println(" CM"); delay(500); /* if (cmMsec <= 10) // 低於10公分,蜂鳴器持續發出警告聲 { tone(Buzzer, 400); } else if (cmMsec <= 50) { // 10~50公分時,蜂鳴器會間隔0.1秒發出一短聲警示 tone(Buzzer, 400, 100); // 發出100ms的聲音 delay(100); // 延遲0.1秒 } else { // 超過100公分時,蜂鳴器每秒發出一0.3秒的長聲警示 tone(Buzzer, 400, 300); // 發出300ms的聲音 delay(1200); // 延遲1.2秒 } */ } ``` :::info EX7_3:超音波避障。車子遇到障礙物會自動轉彎避開。 ::: ``` javascript= #include <Ultrasonic.h> //==== 接腳定義 ==== #define MR2 5 //右馬達輸入2 #define MR1 6 //右馬達輸入1 #define Trig 7 //SR-04超音波Trig #define ML1 10 //左馬達輸入1 #define ML2 11 //左馬達輸入2 #define RGB 12 #define Echo 13 //SR-04超音波Echo //================== #define SpeedR 200 //馬達速度(0-255) #define SpeedL 165 //馬達速度(0-255) Ultrasonic ultrasonic(Trig,Echo); void setup() { Serial.begin(9600); pinMode(Trig,OUTPUT); pinMode(Echo,INPUT); pinMode(MR1,OUTPUT); pinMode(MR2,OUTPUT); pinMode(ML1,OUTPUT); pinMode(ML2,OUTPUT); } void loop() { float cmMsec; delay(500); long microsec = ultrasonic.timing(); cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM); Serial.print(cmMsec); Serial.println(" CM"); // delay(100); if (cmMsec < 15) { Stopcar(); Left(); delay(500); Stopcar(); delay(500); } else { Forward(); } } void Forward(){ analogWrite(MR1,SpeedR); digitalWrite(MR2,LOW); analogWrite(ML1,SpeedL); digitalWrite(ML2,LOW); } void Right(){ digitalWrite(MR1,LOW); analogWrite(MR2,SpeedR); analogWrite(ML1,SpeedL); digitalWrite(ML2,LOW); } void Left(){ analogWrite(MR1,SpeedR); digitalWrite(MR2,LOW); digitalWrite(ML1,LOW); analogWrite(ML2,SpeedL); } void Backward(){ digitalWrite(MR1,LOW); analogWrite(MR2,SpeedR); digitalWrite(ML1,LOW); analogWrite(ML2,SpeedL); } void Stopcar(){ digitalWrite(MR1,LOW); digitalWrite(MR2,LOW); digitalWrite(ML1,LOW); digitalWrite(ML2,LOW); } ``` :::info :tada: 紅外線循跡自走車+超音波避障。 :mega: 賽道上有障礙物,結合六、七程式碼,使完成賽道時間最短。 ![](https://i.imgur.com/k9n4JQF.jpg =500x) [競賽實例1](https://www.youtube.com/watch?v=ODnV2ndIY0k)、[競賽實例2](https://www.youtube.com/watch?v=FAUJtchuhpQ&feature=youtu.be)、[競賽實例3](https://www.youtube.com/watch?v=vjmcWIxILPI&feature=youtu.be) [Arduino 語法參考網站](https://sites.google.com/site/csjhmaker/arduino-ji-chu/arduino-yu-fa-can-kao) :::