---
# System prepended metadata

title: Arduino

---

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






