光感應
讀一個「有很多種可能」的值。 · ⏱ 約 30 分鐘
你會學到三件事
analogRead 讀到的不是兩種值,是 0 到 1023
map 把一個範圍換算成另一個範圍
- 感測器讀到的數字沒有單位,單位是你給的
開始之前
上一課的按鈕只有兩種答案,而光線是連續的:它可以是任何亮度。
接線:光敏電阻一腳接 A0、一腳接 5V,A0 再用一顆 10kΩ 電阻接 GND。
這叫分壓電路,它把「電阻變化」變成「電壓變化」,因為板子只讀得懂電壓。
🟢 先把編輯器打開,跟著下面一起做:跟著做
一、0 到 1023
類比腳讀進來的是一個 0 到 1023 的數字:
1int raw = analogRead(A0);
|
範圍 |
digitalRead |
兩種:HIGH / LOW |
analogRead |
1024 種:0 到 1023 |
為什麼是 1023?和上一課同一個理由:10 個位元,2¹⁰ = 1024 種值。
⚠️ 只有 A0 到 A5 這幾支腳可以。 一般數位腳沒有這個能力。
📋 而 A0 到 A5 各是幾號、你這塊板子有沒有 A6/A7
——板子規格 查得到。⚠️ 不同板子不一樣。
積木盤上它寫著「讀取類比腳位 …」——與上一課那顆「讀取腳位」是一對。
⚠️ analogRead 的腳不用 pinMode。
二、那個數字是什麼意思?
它什麼意思都沒有。
analogRead 回報的是「這支腳上的電壓,佔滿格的幾分之幾」。
它不是「幾勒克斯」、不是「幾度」,它只是一個比例。
感測器給你的是原始讀數,意義是你賦予的。
要變成「亮度」或「溫度」,你得自己換算——而換算要靠實測。
所以第一步永遠是:印出來看看。
先把它印出來,遮住感應器再看一次:
🔎 這一段是試一下——打了看結果就好,不要留在程式裡。
用手遮住感測器、拿燈照它,看那個數字怎麼變。先觀察,再寫邏輯。
三、map:把範圍換掉
讀到的是 0~1023,而 analogWrite 要的是 0~255。差 4 倍。
map 把一個範圍換成另一個範圍:
1int level = map(raw, 0, 1023, 0, 255);
讀法:「把 raw 從 0~1023 這個範圍,換算到 0~255」。
raw 0 ────────────────── 1023
level 0 ────────────────── 255
⚠️ map 用的是整數除法(C++ 入門第 5 課那件事),所以會有一點誤差。
map(500, 0, 1023, 0, 255) 得到 124 而不是 124.6。
⚠️ 而 map 不會幫你把值夾在範圍內。輸入超出去的話輸出也會超出去,
要夾住得用 constrain。
四、接起來
照著打上這一段,光越暗,燈越亮:
1int raw = analogRead(A0);2int level = map(raw, 0, 1023, 0, 255);3Serial.println(level);4analogWrite(9, level);
越暗,燈越亮,一個會自己調整的夜燈。
⚠️ 而方向對不對取決於你怎麼接線。反了的話,把 map 的後兩個數字對調:
map(raw, 0, 1023, 255, 0)。
完成的樣子
這一課的參考做法——程式碼每一行的號碼,就印在對應的那塊積木上。
1void setup() {2 Serial.begin(9600);3 pinMode(9, OUTPUT);4}5 6void loop() {7 int raw = analogRead(A0);8 int level = map(raw, 0, 1023, 0, 255);9 Serial.println(level);10 analogWrite(9, level);11 delay(200);12}
換你了
先只印 raw,用手遮住感測器,記下最暗和最亮的實際數字
(多半不是 0 和 1023,可能是 200 和 800)。
然後把 map 的前兩個數字換成你量到的,畫面會靈敏很多。
這就是「校正」。規格書寫的範圍,和你桌上這一顆的範圍,不一樣。
到編輯器做這一題:練習:量出你這一顆的實際範圍,拿去校正 map
做一個
暗了就開燈、亮了就關燈。
🔴 先做最直覺的版本(一個門檻值),然後把手慢慢移過感測器。
燈會在臨界點瘋狂閃爍,那不是壞掉,是門檻只有一個的必然結果。
⚠️ 修法是兩個門檻:暗到 300 才開,亮到 500 才關。那個中間地帶叫遲滯。
到編輯器做這一題:做一個:不會抖的自動夜燈
這一課你做了什麼
- 你用
analogRead 讀到了 0~1023 的連續值
- 你用
map 把它換算到另一個範圍
- 你知道感測器的讀數沒有單位,而校正要靠實測
如果卡住了
| 你看到 |
多半是因為 |
| 一直是 0 或一直是 1023 |
接線問題——分壓電阻沒接,或接到 5V/GND 短路了 |
| 數字跳來跳去 |
正常。類比讀數本來就會抖,可以多讀幾次取平均 |
analogRead(9) 得到 0 |
9 號腳不是類比輸入。要用 A0~A5 |
| 越亮燈越亮(想要相反) |
把 map 的後兩個數字對調 |
在編輯器打開這一課 →