# Arduino #### [軟體下載Arduino IDE](https://www.arduino.cc/en/software) #### [線上模擬](https://wokwi.com/) #### [程式指令參考](https://www.arduino.cc/reference/en/?_gl=1*qe343k*_ga*MzQ4NDI4MDkyLjE2NjM1Njk2Njk.*_ga_NEXN8H46L5*MTY3ODA3MDI0MS4xOC4xLjE2NzgwNzAzMzkuMC4wLjA.) #### [內建library](https://www.arduino.cc/reference/en/libraries/?_gl=1*1fh72ca*_ga*MzQ4NDI4MDkyLjE2NjM1Njk2Njk.*_ga_NEXN8H46L5*MTY3ODA3MDI0MS4xOC4xLjE2NzgwNzA0MDkuMC4wLjA.) ### [Mega 2560規格](https://store-usa.arduino.cc/products/arduino-mega-2560-rev3?selectedStore=us) ### [完整規格資料](https://docs.arduino.cc/hardware/mega-2560?_gl=1*1r3x6qd*_ga*MzQ4NDI4MDkyLjE2NjM1Njk2Njk.*_ga_NEXN8H46L5*MTY3ODA3MDI0MS4xOC4xLjE2NzgwNzEzNDQuMC4wLjA.) ### [mega2560詳細接腳資料](https://content.arduino.cc/assets/Pinout-Mega2560rev3_latest.pdf?_gl=1*1fumfc9*_ga*MzQ4NDI4MDkyLjE2NjM1Njk2Njk.*_ga_NEXN8H46L5*MTY3ODA3MDI0MS4xOC4xLjE2NzgwNzEzNDQuMC4wLjA.) ![](https://i.imgur.com/Uyvb9hV.png) ![](https://i.imgur.com/tQFHDHg.png) ![](https://i.imgur.com/PMTYTSw.png) ![](https://i.imgur.com/MlAook8.png) # 範例 ### Blink 電路與程式 ![](https://i.imgur.com/sIoC6GS.png) ``` int led=23; void setup() { pinMode(led, OUTPUT); digitalWrite(led, LOW); } void loop() { digitalWrite(led, HIGH); delay(500); digitalWrite(led, LOW); delay(500); } ``` ### 變數宣告(其它用途) 全域變數可用於整個程式之中,除了中斷副程式外。若要讓全域變數也同時適用於中斷副程式之中,則在宣告該全域變數之前面,必須加一個volatile 關鍵字 例如: volatile int a=0; //宣告整數變數a,初始值=0 在函數裡所宣告的變數,只能用於該函數裡,而且每次呼叫該函數,該變數就被重新宣告一次,結束該函數時,該函數將消失,而釋放所佔用的記憶體。 若要為函數設置專用變數,不隨函數而消失,則可在宣告該區域變數之前面,加一個static關鍵字, 例如: static int b=0; ### 中斷 ![](https://i.imgur.com/RlKPqeY.png) mega256 ![](https://i.imgur.com/SxNqhdB.png) INT.0 最高優先等級,INT.1 優先等級次之,而INT.5優先等級最低。 當較高優先等級的中斷時,低優先等級的中斷將無作用。當較低優先等級的中斷時,若發生較高優先等級的中斷,則會先執行較高優先等級的中斷,待較高優先等級的中斷執行完畢後,才會接續執行原本較低優先等級的中斷。 ### 中斷觸發 Arduino Mega 2560 開發板裡提供四種觸發方式(LOW、CHANGE、RISING、FALLING) ![](https://i.imgur.com/cR9F9Kr.png) 當出現中斷觸發後,即跳入中斷服務程式(interrupt service routine, ISR) [中斷指令語法說明](https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/) Example Code ``` const byte ledPin = 22; // 接D22 const byte interruptPin = 2; //接int0(D2) volatile byte state = LOW; void setup() { pinMode(ledPin, OUTPUT); pinMode(interruptPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE); //設定中斷,並使用change觸發模式 } void loop() { digitalWrite(ledPin, state); } void blink() { state = !state; } ``` ### 8顆LED左右來回 ``` int led[8]={22,23,24,25,26,27,28,29}; void setup() { for (int i=0 ; i<=7 ;i++) { pinMode(led[i], OUTPUT); digitalWrite(led[i], LOW); } } void loop() { for (int i=0 ; i<=7 ; i++) { digitalWrite(led[i], HIGH); delay(500); digitalWrite(led[i], LOW); } for (int j=7 ; j>=0 ; j--) { digitalWrite(led[j], HIGH); delay(500); digitalWrite(led[j], LOW); } } ``` ### SHT10實驗 #### [SHT1X Library下載](https://github.com/practicalarduino/SHT1x) ``` #include <SHT1x.h> #define dataPin 20 //SDA #define clockPin 21 //SCL SHT1x sht1x(dataPin, clockPin); void setup() { Serial.begin(115200); // Open serial connection to report values to host Serial.println("Starting up"); } void loop() { float temp_c; float humidity; // Read values from the sensor temp_c = sht1x.readTemperatureC(); humidity = sht1x.readHumidity(); // Print the values to the serial port Serial.print("Temperature: "); Serial.print(temp_c); Serial.println("C"); Serial.print("Humidity: "); Serial.print(humidity); Serial.println("%"); delay(3000); } ``` ### DHT11實驗 ![](https://i.imgur.com/QX5ioKm.png) ``` #include <DHT.h> #define DHTPin 23 #define DHTTYPE DHT22 //DHT11、DHT21、DHT22 DHT dht(DHTPin,DHTTYPE); void setup() { Serial.begin(9600); dht.begin(); } void loop() { delay(2000); // wait a 2 second for mesurements float humi=dht.readHumidity(); float temp=dht.readTemperature(); // it's Celsius temp.; if parameter is true,that's Fahrenheit temp. if (isnan(humi)||isnan(temp)) // 如果讀取失敗,則輸出下列字串 { Serial.println("Failed to read from DHT sensor"); return; } Serial.print("Humidity="); Serial.println(humi); Serial.print("Temperature="); Serial.println(temp); delay(1000); } ``` ### HC-SR04實驗 ![](https://i.imgur.com/a3Sw2F6.png) ``` #include <NewPing.h> #define TRIGGER_PIN 24 #define ECHO_PIN 25 #define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm. NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance. void setup() { Serial.begin(9600); // Open serial monitor at 9600 baud to see ping results. } void loop() { delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings. Serial.print("Ping: "); Serial.print(sonar.ping_cm()); // Send ping, get distance in cm and print result (0 = outside set distance range) Serial.println("cm"); delay(1000); } ``` ### SG90伺服馬達實驗 ``` #include <Servo.h> Servo serv; int angle; //宣告一全域變數 angle void setup() { serv.attach(22); // 伺服馬達訊號腳接到D22 } void loop() { for(angle=0; angle<=180; angle++) //從0度轉到180度 { serv.write(angle); //設定伺服馬達轉動角度 delay(10); } for(angle=180; angle>=0; angle--) //從180度轉到0度 { serv.write(angle); delay(10); } } ``` ### 類比輸入實驗 利用實驗板上的可變電阻,讀取輸入值。(S-600-plus實驗板讀出介於0~789) ![](https://hackmd.io/_uploads/HJESy_xrn.png) ``` // 量測實驗器上VR從A0讀進來的值 int vr_pin=A0; int value=0; void setup() { Serial.begin(9600); } void loop() { value=analogRead(vr_pin); Serial.println(value); delay(1000); } ``` ### 使用map函數 ``` // 量測實驗器上VR從A0讀進來的值 //利用map指令,將讀值對應至所需範圍 int vr_pin=A0; int svalue; int mvalue; void setup() { Serial.begin(9600); } void loop() { svalue=analogRead(vr_pin); mvalue=map(svalue,0,789,0,180); //對應0~180 Serial.print("svalue="); Serial.println(svalue); Serial.print("Mapping Value="); Serial.println(mvalue); delay(1500); } ``` ### 串列埠通訊 串列埠通訊參數預設值如下 ![](https://hackmd.io/_uploads/HJmFDHJr3.png) #### 從電腦端串列埠查看arduino送出之資料 ``` // 觀察從arduino串列埠送出的資料與對應的ASCII code void setup() { Serial.begin(9600); } void loop() { Serial.println('A'); Serial.print("ASCII ="); Serial.println('A',DEC); Serial.println('B'); Serial.print("ASCII ="); Serial.println('B',DEC); Serial.println('a'); Serial.print("ASCII ="); Serial.println('a',DEC); delay(3000); } ``` #### 使用Labview設計簡易顯示儀表板 ##### Block Diagram ![](https://hackmd.io/_uploads/SJ0mKMnLh.png) ##### FrontPanel ![](https://hackmd.io/_uploads/rJgwKG2Lh.png) #### 將溫溼度分開顯示 ![](https://hackmd.io/_uploads/SJInbXhLh.png) ![](https://hackmd.io/_uploads/ryU0bXhIh.png) #### 電腦端自本身串列埠傳送資料到arduino串列埠 arduino內部具有Buffer(緩衝區),用來暫存序列埠所接收到的資料 查看該buffer,即可得知是否收到對方所傳遞的訊息 Serial.available() 用來檢查是否有資料的函式, 若無資料,則回傳 0 若有資料,則回傳緩衝區內資料的位元組數 Serial.read() 用來讀取緩衝區內資料(字元) Serial.readString() 用來讀取緩衝區內資料(字串) **1.arduino讀取電腦端傳送的字元** ``` char a; void setup() { Serial.begin(9600); } void loop() { if(Serial.available()==0) { Serial.println("無接收到任何資料"); } else { a=Serial.read(); Serial.print("讀取值="); Serial.println(a); } delay(3000); //每隔3秒接收一次 } ``` **2.arduino讀取電腦端傳送的字串** ``` String a; void setup() { Serial.begin(9600); } void loop() { if(Serial.available()==0) { Serial.println("無接收到任何資料"); } else { a=Serial.readString(); //讀取字串 Serial.print("讀取值="); Serial.println(a); } delay(3000); //每隔3秒接收一次 } ``` **3.透過指令控制LED亮/滅** ``` //arduino讀取電腦端傳送的字,控制LED ON / OFF int LED=13; char a; void setup() { Serial.begin(9600); pinMode(LED,OUTPUT); } void loop() { if(Serial.available()) { a=Serial.read(); switch (a) { case '0': digitalWrite(LED,LOW); break; case '1': digitalWrite(LED,HIGH); break; default: Serial.println("請輸入正確指令"); break; } } } ```