本章學習重點
GPIO 是 Arduino 與外部電子元件溝通的核心介面。本章將從 Digital Input、Digital Output 與 INPUT_PULLUP 三種模式開始,說明 pinMode()、digitalWrite()、digitalRead() 的用途。
你也會完成 LED 常亮、LED 閃爍與按鍵控制 LED 等基礎實驗,並理解浮動輸入、反向邏輯與 GPIO 電流限制。
- 了解 GPIO 的真正意義。
- 分辨 Digital Input 與 Digital Output。
- 熟悉 pinMode()、digitalWrite()、digitalRead() 的使用方式。
- 理解 INPUT_PULLUP 的工作原理。
- 完成 LED 與按鍵控制實驗。
什麼是 GPIO?
GPIO 是 General Purpose Input/Output 的縮寫,中文通常稱為通用輸入/輸出腳位。它的主要特色是同一個腳位可以依程式需求設定成輸入或輸出。
例如 D8 今天可以設定為 OUTPUT 來控制 LED,之後也可以改成 INPUT 或 INPUT_PULLUP 來讀取按鍵。GPIO 的角色由程式決定,因此具有高度彈性。
| 項目 | 說明 |
|---|---|
| 全名 | General Purpose Input/Output |
| 中文 | 通用輸入/輸出 |
| 可設定 | INPUT、OUTPUT、INPUT_PULLUP |
| Arduino Uno | D0~D13(部分 Analog 腳也可作為數位腳使用) |
| 常見用途 | LED、按鍵、Relay、蜂鳴器、感測器 |
Arduino Uno 有多少 GPIO?
Arduino Uno R3 提供 D0~D13,共 14 個數位 GPIO。A0~A5 除了可讀取類比訊號,也可以作為數位 GPIO 使用。
因此在不考慮其他功能占用的情況下,Arduino Uno R3 最多可使用 20 個 GPIO。實際專案仍應留意 D0、D1 與序列通訊共用,以及其他腳位可能具有 PWM、I2C 或 SPI 等複用功能。
INPUT、OUTPUT 與 INPUT_PULLUP
GPIO 常用模式包括 INPUT、OUTPUT 與 INPUT_PULLUP。設定模式時使用 pinMode(),並在 setup() 中完成初始化。
OUTPUT:由 Arduino 控制外部元件
OUTPUT 代表 Arduino 主動輸出電位,常用於控制 LED、蜂鳴器、Relay 驅動電路、MOSFET 或電晶體。
pinMode(13, OUTPUT);
設定為 OUTPUT 後,可使用 digitalWrite() 輸出 HIGH 或 LOW。
INPUT:由 Arduino 讀取外部狀態
INPUT 代表 Arduino 讀取外部電位,常見輸入來源包括按鍵、開關、光耦與數位感測器。
pinMode(2, INPUT);
int state = digitalRead(2);
INPUT_PULLUP:啟用內建上拉電阻
INPUT_PULLUP 會啟用 Arduino 內部約 20 kΩ~50 kΩ 的上拉電阻,讓輸入腳位在按鍵未按下時維持穩定 HIGH,通常不需要再外接 10 kΩ 上拉電阻。
pinMode(2, INPUT_PULLUP);
使用 INPUT_PULLUP 時,按鍵應接在輸入腳位與 GND 之間。未按下時讀到 HIGH,按下時讀到 LOW,因此判斷邏輯與直覺相反。
HIGH 與 LOW 代表什麼?
HIGH 與 LOW 不只是數字 1 與 0,也代表腳位的電壓狀態。以 Arduino Uno 的 5V 邏輯為例,HIGH 約為 5V,LOW 約為 0V。
digitalWrite(13, HIGH);
digitalWrite(13, LOW);
第一行會讓 D13 輸出高電位,第二行會讓 D13 輸出低電位。實際電壓與可承受電流仍受硬體規格與負載影響。
實驗一:LED 常亮
材料清單
- Arduino Uno R3 一片
- LED 一顆
- 220Ω 限流電阻一個
- Breadboard 一片
- 杜邦線若干
接線方式
- Arduino D13 連接 220Ω 電阻。
- 電阻另一端連接 LED 長腳(正極)。
- LED 短腳(負極)連接 GND。
完整程式
const int LED_PIN = 13;
void setup()
{
pinMode(LED_PIN, OUTPUT);
}
void loop()
{
digitalWrite(LED_PIN, HIGH);
}
上傳程式後,預期 LED 會持續亮起。若沒有亮,先檢查 LED 極性、限流電阻與 GND 接線。
digitalWrite() 的使用方式
digitalWrite() 用於控制 Digital Output,語法如下:
digitalWrite(pin, value);
pin 是要控制的腳位,value 只能是 HIGH 或 LOW。使用前應先用 pinMode() 將該腳位設定為 OUTPUT。
實驗二:LED 閃爍
const int LED_PIN = 13;
void setup()
{
pinMode(LED_PIN, OUTPUT);
}
void loop()
{
digitalWrite(LED_PIN, HIGH);
delay(500);
digitalWrite(LED_PIN, LOW);
delay(500);
}
這段程式會讓 LED 亮 500 毫秒、滅 500 毫秒,持續循環。完整的一亮一滅週期約為 1 秒。
digitalRead() 的使用方式
digitalRead() 用於讀取 Digital Input,回傳值為 HIGH 或 LOW。
int state;
state = digitalRead(2);
當輸入腳位為高電位時,state 為 HIGH;當輸入腳位為低電位時,state 為 LOW。輸入腳位若沒有明確上拉或下拉,讀值可能因雜訊而不穩定。
使用 INPUT_PULLUP 連接按鍵
接線原則
- D2 連接按鍵其中一端。
- 按鍵另一端連接 GND。
- 不需要將按鍵接到 5V。
- 程式使用 pinMode(2, INPUT_PULLUP)。
按鍵邏輯
未按下按鍵時,內建上拉電阻會讓 D2 維持 HIGH。按下按鍵後,D2 直接連到 GND,因此讀到 LOW。
實驗三:按鍵控制 LED
const int LED_PIN = 13;
const int BUTTON_PIN = 2;
void setup()
{
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop()
{
if (digitalRead(BUTTON_PIN) == LOW)
{
digitalWrite(LED_PIN, HIGH);
}
else
{
digitalWrite(LED_PIN, LOW);
}
}
按住按鍵時,D2 讀到 LOW,LED 亮起;放開按鍵時,D2 回到 HIGH,LED 熄滅。這就是 INPUT_PULLUP 的反向邏輯。
Floating 是什麼?
當輸入腳位設定為 INPUT,卻沒有外接上拉或下拉電阻時,腳位可能處於 Floating,也就是沒有固定電位。此時 digitalRead() 可能在 HIGH 與 LOW 之間不規則變動。
Floating 容易受到環境雜訊、人體接近或導線感應影響。使用 INPUT_PULLUP,或外接適當的上拉/下拉電阻,可以讓輸入狀態穩定。
Arduino Uno GPIO 的電流限制
Arduino Uno 的 GPIO 應以控制訊號為主,不應視為一般電源輸出端。設計時建議將單一 GPIO 的工作電流控制在 20mA 以下。
馬達、繼電器線圈、大功率 LED 或其他高耗電負載,不可直接由 GPIO 驅動,應搭配電晶體、MOSFET、二極體或專用驅動模組,並使用合適的外部電源。
初學者常見錯誤與排除方式
忘記設定 pinMode()
若直接使用 digitalWrite() 或 digitalRead(),卻沒有先設定腳位模式,結果可能不如預期。建議在 setup() 中集中完成所有 pinMode() 設定。
INPUT_PULLUP 按鍵接到 5V
使用 INPUT_PULLUP 時,按鍵應接到 GND,而不是 5V。按下後讀值為 LOW。
LED 極性接反
LED 長腳通常是正極,短腳通常是負極。若 LED 不亮,可先反向檢查接法,但不要省略限流電阻。
LED 沒有限流電阻
LED 應串接適當限流電阻,本章使用 220Ω。直接將 LED 接到 GPIO 可能讓電流過大,損壞 LED 或 Arduino 腳位。
按鍵讀值不穩定
若按鍵讀值自行跳動,通常是 Floating、接線鬆脫或共地不完整。可先改用 INPUT_PULLUP,並確認按鍵確實接在輸入腳位與 GND 之間。
本章實作練習
練習一:LED 常亮
讓 D13 的 LED 持續亮起,並嘗試將 LED_PIN 改成其他可用的數位腳位。
練習二:改變閃爍速度
分別將 delay() 改為 1000、500 與 200 毫秒,比較 LED 閃爍速度。
練習三:按鍵控制 LED
完成按住按鍵時 LED 亮、放開時 LED 滅的功能,並使用 Serial Monitor 顯示讀到的 HIGH 或 LOW。
Challenge:每按一次切換 LED 狀態
進一步嘗試讓 LED 不需要一直按住按鍵,而是每按一次就切換亮/滅狀態。這個功能需要記錄前一次狀態,並處理按鍵彈跳(Button Bounce)與狀態切換(Toggle)。
這些概念會延伸到後續的按鍵去彈跳、狀態機與非阻塞式程式設計。
本章重點整理
- GPIO 可依程式需求切換為輸入或輸出。
- OUTPUT 搭配 digitalWrite() 控制 HIGH 與 LOW。
- INPUT 或 INPUT_PULLUP 搭配 digitalRead() 讀取外部狀態。
- INPUT_PULLUP 讓未按下為 HIGH、按下為 LOW。
- 沒有上拉或下拉的輸入腳位可能產生 Floating。
- GPIO 不適合直接驅動高耗電負載。
- LED 必須注意極性並串接限流電阻。