第9章 Arduino Analog Input 與 ADC 原理:analogRead、0~1023 與可變電阻實作
本章完整介紹 Arduino Analog Input(類比輸入)與 ADC(類比數位轉換器)的基本原理,說明 Digital 與 Analog 訊號的差異、Arduino Uno 為什麼會回傳 0~1023,以及如何使用 analogRead() 讀取類比訊號。文章並透過 10K 可變電阻實作,示範 A0 接線、ADC 數值讀取、電壓換算、取樣平均與常見故障排除,適合 Arduino 初學者建立類比感測器應用基礎。
本章將帶你認識 Analog Input(類比輸入)與 ADC(Analog to Digital Converter,類比數位轉換器)的基本原理,並實際使用 Arduino Uno 的 analogRead() 讀取可變電阻輸出的電壓變化。
你將了解數位訊號與類比訊號的差異、Arduino Uno 為什麼回傳 0~1023、如何把 ADC 數值換算成電壓,以及類比輸入腳位的安全限制。
本章以 Arduino Uno 與 10K 可變電阻為主要實作環境。Arduino Uno 的類比輸入腳位不可直接量測超過允許範圍的電壓,量測較高電壓時必須先使用適當的分壓與保護電路。
本章學習目標
- 了解 Analog(類比訊號)的基本概念。
- 理解 ADC 將電壓轉換成數位數值的工作原理。
- 學會使用 analogRead() 讀取 Arduino Uno 的類比輸入。
- 了解 Arduino Uno 的 10-bit ADC 為什麼回傳 0~1023。
- 使用 10K 可變電阻完成第一個 Analog Input 實驗。
- 學會將 ADC 數值換算成近似電壓。
Digital 與 Analog 有什麼不同?
Digital(數位)訊號只有有限的離散狀態。以 Arduino Uno 的一般數位輸入輸出為例,最常見的是 HIGH 與 LOW,也就是邏輯高電位與邏輯低電位。
按鍵是否按下、LED 是否點亮,通常可以用兩種狀態表示,因此適合使用 Digital Input 或 Digital Output。
現實世界中的光線、溫度、濕度、聲音與旋鈕位置,通常不是只有開或關,而是會在一定範圍內連續變化。這類訊號稱為 Analog(類比)訊號。
類比訊號的讀值範例
旋轉可變電阻時,輸出電壓會逐漸改變。Arduino 經過 ADC 轉換後,可能依序讀到 0、100、350、620、850、1023 等不同數值。
這些數值本身仍是離散的數位資料,但因為 ADC 將連續電壓切分成許多細小區間,所以可以用來近似表示類比訊號的變化。
Arduino Uno 的 Analog Input 腳位
Arduino Uno 提供 A0、A1、A2、A3、A4、A5,共 6 個主要類比輸入腳位,可搭配 analogRead() 讀取外部電壓。
A4 與 A5 同時也是 I²C 通訊腳位,其中 A4 對應 SDA,A5 對應 SCL。使用時應確認程式是否同時需要 I²C 與類比輸入功能,避免腳位用途互相衝突。
ADC 是什麼?
ADC 是 Analog to Digital Converter 的縮寫,中文常稱為類比數位轉換器。
微控制器無法直接以程式處理連續電壓,因此 ADC 會先把輸入電壓轉換成一個數位數值。例如輸入電壓為 2.37V 時,Arduino Uno 可能將它轉換成約 485 的 ADC 數值。
程式透過 analogRead() 取得的是 ADC 轉換後的整數,而不是直接取得以伏特為單位的電壓。
ADC 的基本工作流程
- 外部元件輸出一個位於允許範圍內的電壓。
- Arduino Uno 的 ADC 取樣該電壓。
- ADC 依參考電壓與解析度,將輸入電壓量化成整數。
- analogRead() 將轉換結果回傳給程式。
- 程式可顯示、比較、換算或進一步控制其他元件。
Arduino Uno 為什麼回傳 0~1023?
Arduino Uno 的 ATmega328P 內建 10-bit ADC。10-bit 可以表示 2 的 10 次方,也就是 1024 個不同的量化階級。
因為數值從 0 開始計算,所以 analogRead() 的有效回傳範圍是 0~1023,而不是 0~1024,也不是 0~1000。
在預設參考電壓約為 5V 的情況下,數值 0 代表接近 0V,數值 1023 代表接近參考電壓。
解析度代表什麼?
解析度表示 ADC 可以把輸入範圍切分成多少個階級。Arduino Uno 的 10-bit ADC 有 1024 個階級,因此每一個階級約對應參考電壓的 1/1024。
若參考電壓以 5V 估算,每一個 ADC 階級約為 4.88mV。實際結果仍會受到供電電壓、參考電壓、雜訊與元件誤差影響。
電壓與 ADC 數值的關係
Arduino Uno 預設通常以板子的供電電壓作為 ADC 參考電壓。教學中常以 5V 作為近似值,因此可用 0~1023 表示約 0~5V 的輸入範圍。
下表為理想條件下的近似對照。實際量測值可能因 USB 供電、穩壓器、參考電壓與元件公差而略有不同。
使用 analogRead() 讀取類比輸入
analogRead() 用來讀取指定類比輸入腳位的 ADC 數值。以下程式每 500 毫秒讀取一次 A0,並將結果輸出到 Serial Monitor。
上傳程式後,開啟 Serial Monitor 並將鮑率設為 9600。若 A0 接收到變化中的電壓,畫面會顯示不同的整數。
int sensorValue;
void setup()
{
Serial.begin(9600);
}
void loop()
{
sensorValue = analogRead(A0);
Serial.println(sensorValue);
delay(500);
}
預期觀察結果
Serial Monitor 可能顯示 325、326、327、450、650、780 等數值。當輸入電壓改變時,讀值也會跟著改變。
即使輸入看似固定,ADC 數值仍可能在相鄰數值間小幅波動,這通常是電源、接線、環境雜訊與 ADC 本身量化造成的正常現象。
實作:使用可變電阻讀取 Analog Input
準備材料
- Arduino Uno 開發板。
- Breadboard(麵包板)。
- 10K Potentiometer(10K 可變電阻)。
- 杜邦線。
- USB 傳輸線。
可變電阻接線方式
- 將可變電阻其中一側的外腳接到 Arduino Uno 的 5V。
- 將另一側的外腳接到 Arduino Uno 的 GND。
- 將可變電阻中間腳接到 Arduino Uno 的 A0。
- 確認 5V 與 GND 沒有短路後,再連接 USB 電源。
可變電阻的兩側外腳形成固定電阻路徑,中間腳是滑動端,也是本實驗的 Signal 輸出。旋轉旋鈕時,中間腳輸出的電壓會在接近 0V 與接近 5V 之間變化。
不同型號可變電阻的實體腳位排列可能不同,接線前應依元件標示或使用萬用電表確認,不要只依外觀猜測。
讀取可變電阻程式
const int POT_PIN = A0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
int value = analogRead(POT_PIN);
Serial.println(value);
delay(100);
}
上傳程式並開啟 Serial Monitor 後,緩慢旋轉可變電阻。預期可以看到讀值在接近 0~1023 的範圍內變化。
若旋轉方向與數值增加方向相反,可交換可變電阻兩側外腳的 5V 與 GND 接線;中間腳仍需接到 A0。
如何把 ADC 數值換算成電壓?
當參考電壓以 5V 估算時,可將 analogRead() 的結果乘以 5.0,再除以 1023.0,得到近似電壓。
例如 ADC 數值為 512,換算結果約為 2.50V。使用浮點數 5.0 與 1023.0 可以避免整數除法造成小數部分被捨去。
const int POT_PIN = A0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
int adcValue = analogRead(POT_PIN);
float voltage = adcValue * 5.0 / 1023.0;
Serial.print("ADC: ");
Serial.print(adcValue);
Serial.print(" Voltage: ");
Serial.print(voltage, 2);
Serial.println("V");
delay(200);
}
參考電壓不是固定 5.00V
公式中的 5.0 是教學用近似值。實際 USB 供電或板上 5V 可能不是精確的 5.00V,因此換算結果不等同於精密電表量測值。
需要較準確結果時,可以先以萬用電表量測實際參考電壓,再把程式中的 5.0 改成量測值,並考慮電阻誤差、訊號雜訊與 ADC 校正。
Arduino Uno 能直接量測超過 5V 嗎?
不能直接量測。Arduino Uno 的類比輸入電壓不得高於其允許範圍,也不得低於 GND。將 12V 等較高電壓直接接到 A0,可能損壞 ATmega328P 或整塊開發板。
量測高於參考電壓的訊號時,必須先使用適當的分壓電路,必要時再加入限流、箝位、保險絲、隔離或其他保護措施。
設計分壓時除了計算比例,也要考慮輸入可能出現的最高電壓、電阻功率、公差與突波。接線前應先以萬用電表確認分壓輸出不會超過 Arduino 的允許範圍。
為什麼有些開發板會回傳 0~4095?
不同微控制器的 ADC 解析度不一定相同。12-bit ADC 有 2 的 12 次方,也就是 4096 個階級,因此常見回傳範圍為 0~4095。
部分 ESP32 開發環境常以 12-bit 讀值表示類比輸入,但實際有效精度、線性度、衰減設定與允許輸入範圍會受到晶片型號及設定影響,不能只依 0~4095 判斷量測品質。
比較不同開發板時,除了 bit 數,也要確認參考電壓、輸入範圍、取樣速度、線性度與雜訊表現。
Analog Input 的常見用途
- 讀取可變電阻與旋鈕位置。
- 讀取光敏電阻(LDR)分壓後的光線變化。
- 讀取 LM35、TMP36 等類比溫度感測器。
- 讀取土壤濕度感測器的類比輸出。
- 讀取 Joystick(搖桿)的 X 軸與 Y 軸位置。
- 讀取經適當偏壓與調理後的麥克風訊號。
- 透過分壓與保護電路量測電池電壓。
常見錯誤與故障排除
analogRead() 一直讀到 0
先確認程式讀取的腳位與實際接線相同,例如程式使用 A0,訊號線也必須接到 A0。
確認可變電阻中間腳是否接到 A0、兩側外腳是否分別接到 5V 與 GND。若訊號端被直接接到 GND,讀值通常會接近 0。
ADC 數值一直停在 1023
A0 可能直接接到 5V、可變電阻接線錯誤,或輸入電壓已接近或超過參考電壓。
應立即確認輸入電壓是否在安全範圍內。若來源可能高於 Arduino 允許值,先斷電並檢查分壓與保護電路。
讀值大幅亂跳
常見原因包括 GND 未共地、訊號腳懸空、麵包板接觸不良、導線過長、電源雜訊或感測器輸出阻抗過高。
先檢查共地與接線,再縮短訊號線。必要時可加入適當的電容濾波、改善電源品質,或使用多次取樣平均降低波動。
讀值只有小幅變化
輸入電壓可能只在很小範圍內變動,或感測器輸出沒有涵蓋完整參考電壓範圍。
可先使用萬用電表量測輸入端的實際電壓,再確認感測器規格、分壓比例與程式所使用的參考電壓是否一致。
為什麼數值無法完全穩定?
ADC 量測出現少量波動通常是正常現象。電源雜訊、接線、周圍電磁干擾、參考電壓變動與 ADC 量化都可能影響讀值。
若應用需要穩定結果,可以使用多次取樣平均、中位數濾波、低通濾波、適當去耦電容與較穩定的參考電壓。
多次取樣平均範例
以下範例連續讀取 A0 十次,再計算平均值。這種方法可以降低部分隨機波動,但也會增加讀取時間,並不代表可以消除所有誤差。
const int SENSOR_PIN = A0;
const int SAMPLE_COUNT = 10;
void setup()
{
Serial.begin(9600);
}
void loop()
{
long total = 0;
for (int i = 0; i < SAMPLE_COUNT; i++)
{
total += analogRead(SENSOR_PIN);
delay(2);
}
float averageValue = total / (float)SAMPLE_COUNT;
float voltage = averageValue * 5.0 / 1023.0;
Serial.print("Average ADC: ");
Serial.print(averageValue, 1);
Serial.print(" Voltage: ");
Serial.print(voltage, 2);
Serial.println("V");
delay(200);
}
Q&A
A0 可以當成數位腳位使用嗎?
在 Arduino Uno 上,A0~A5 通常也可以作為數位輸入輸出腳位使用,但使用方式與腳位編號應依 Arduino 核心定義與程式需求確認。本章重點仍是使用 analogRead() 進行類比輸入。
analogRead() 讀到的是電壓嗎?
不是。analogRead() 回傳的是 ADC 整數值。需要以參考電壓與 ADC 最大值進行換算,才能得到近似電壓。
為什麼換算後的電壓和萬用電表不同?
常見原因是程式假設參考電壓為 5.00V,但實際供電不是精確的 5.00V。另外,ADC、元件與萬用電表本身也都有誤差。
可先量測實際參考電壓,再修正換算常數;需要更高準確度時,還要進行校正並改善電源與訊號品質。
可以直接把感測器的 Analog Output 接到 A0 嗎?
只有在確認感測器輸出電壓範圍、GND 參考與 Arduino Uno 相容時才可以直接連接。若輸出可能超過允許範圍、含負電壓或雜訊突波,必須先加入適當的訊號調理與保護電路。
本章實作練習
- 使用可變電阻接到 A0,觀察旋轉時 ADC 數值的變化。
- 修改程式,同時顯示 ADC 數值與換算後的電壓。
- 記錄可變電阻轉到最小、中間與最大位置時的讀值。
- 比較單次讀取與十次取樣平均的穩定程度。
- 嘗試設定門檻值,例如 ADC 大於 700 時點亮 LED,低於 650 時熄滅 LED。
Challenge:製作簡易電壓顯示器
- 使用可變電阻作為輸入。
- 在 Serial Monitor 同時顯示 ADC 數值與換算後的電壓。
- 輸出格式可設計為 ADC: 512 Voltage: 2.50V。
- 觀察旋轉旋鈕時,ADC 數值與電壓如何同步變化。
- 記錄實際 5V 電源電壓,並比較修正前後的換算結果。
本章重點整理
- Digital 訊號以離散狀態表示,Analog 訊號會在一定範圍內連續變化。
- ADC 負責將輸入電壓轉換成微控制器可以處理的數位數值。
- Arduino Uno 使用 10-bit ADC,因此 analogRead() 常回傳 0~1023。
- A0~A5 是 Arduino Uno 的主要類比輸入腳位,其中 A4 與 A5 也用於 I²C。
- ADC 數值可依參考電壓換算成近似電壓,但實際精度受多種因素影響。
- Arduino Uno 不可直接量測超過允許範圍的電壓,量測高電壓必須先分壓並加入保護。
- 可變電阻是學習 Analog Input、ADC 與電壓換算最適合的入門元件之一。
下一章預告
下一章將介紹 PWM(Pulse Width Modulation)與 analogWrite(),說明 Arduino Uno 為什麼沒有一般用途的真正類比電壓輸出,以及如何利用 Duty Cycle(占空比)控制 LED 亮度與直流馬達速度。
完成 Analog Input 與 ADC 的學習後,你可以在下一章把可變電阻讀值映射成 PWM 輸出,製作旋鈕控制 LED 亮度的完整實驗。