# 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;
}
}
}
```