Learning Objectives
- 說明為什麼 GPIO 不能直接驅動馬達、繼電器線圈這類需要大電流的零件
- 用 NPN 電晶體或 MOSFET 做低側開關,估算基極電阻
- 說明續流二極體保護了什麼,以及它要怎麼接
- 用繼電器模組控制另一個電路,並用遲滯避免來回切換
腳位的力氣有限
GPIO 腳位能輸出的電壓是 3.3V(ESP32、Pico)或 5V(多數 Arduino),能提供的電流也很有限: 一支腳位大約只能安全提供十幾到幾十毫安(mA),確切的上限要看晶片的規格書,而且整顆晶片所有腳位加起來還有總量限制。
點亮一顆 LED(約 10 mA)沒問題,但是:
| 零件 | 常見的需求 |
|---|---|
| 小型直流馬達、風扇 | 5V 以上,一百到數百 mA,啟動瞬間更多 |
| 繼電器的線圈 | 5V 或 12V,數十 mA |
| 一整條 LED 燈條 | 5V 或 12V,可能好幾安培(A) |
這些都超過腳位能負擔的範圍。直接接上去,輕則推不動,重則讓開發板當機或燒壞腳位。
解決的方法是加一個開關:讓腳位只負責「按開關」,真正的大電流從另一個電源,經過開關流到零件。 這一課的兩種開關:
- 電晶體(transistor):沒有機械零件、切換很快(可以配合 PWM 調速),適合直流的馬達、燈條。
- 繼電器(relay):用電磁鐵吸動一片金屬接點,控制端與負載端完全分開,可以切換另一個電源的電路。
電晶體當開關
NPN 雙極性電晶體(BJT)
NPN 電晶體有三支腳:基極(B)、集極(C)、射極(E)。 從基極流進一點點電流,就允許集極到射極流過大很多的電流,倍數叫電流增益(hFE),小訊號電晶體常見幾十到幾百倍。
最常見的接法是低側開關:負載接在正電源與集極之間,射極接地,GPIO 經過一顆基極電阻接到基極。
+5V ──┬──────────┐
│ │
[負載] 續流二極體(陰極朝 +5V)
│ │
├──────────┘
C
GPIO ─[1kΩ]─ B NPN
E
│
GND ──┴── 開發板的 GND(共地)
基極電阻怎麼估?假設負載要 100 mA、電晶體的 hFE 最小是 100:
至少需要的基極電流 = 100 mA ÷ 100 = 1 mA
用 1kΩ:基極電流 =(3.3V − 0.7V)÷ 1000Ω = 2.6 mA
2.6 mA 是需要量的 2.6 倍,足夠讓電晶體完全導通(稱為飽和),這時它像一個閉合的開關,自己不太發熱。 0.7V 是基極到射極的電壓降,實際數值以規格書為準。
MOSFET
MOSFET 用電壓控制:閘極(G)幾乎不需要持續的電流,導通時的電阻很小,適合幾安培的負載。 要注意選擇邏輯準位(logic-level)MOSFET:規格書上要寫明閘極只加 3.3V(或更低)時就能完全導通。 常見的做法是在 GPIO 與閘極之間串一顆小電阻,再用一顆約 10kΩ 的電阻把閘極拉到 GND,開機時腳位還沒設定,MOSFET 也會保持關閉。
兩個一定要記得的事
- 共地:馬達的 5V 電源與開發板必須接同一個 GND,基極(閘極)的電壓才有共同的參考點。
- 續流二極體:馬達、繼電器線圈都是線圈(電感)。電流突然被切斷時,線圈會產生很高的反向電壓, 可能擊穿電晶體。在線圈兩端反向並聯一顆二極體(陰極接正電源那一端),讓電流在線圈與二極體之間繞圈慢慢消失。 常見選用 1N4007 這類整流二極體。
逐步看:用 MOSFET 和 PWM 調整風扇轉速
GPIO25 接到 MOSFET 的閘極,MOSFET 開關一顆 5V 風扇。腳位輸出 PWM:工作週期越高,MOSFET 導通的時間越長,風扇轉得越快。 電路畫面上的「直流馬達」卡片代表風扇,數字是轉速的比例。
繼電器
繼電器裡面有一個線圈和一組會被吸動的接點:
| 接腳 | 意思 |
|---|---|
| COM | 共用端 |
| NO(Normally Open,常開) | 線圈沒通電時和 COM 分開,通電時接通 |
| NC(Normally Closed,常閉) | 線圈沒通電時和 COM 接通,通電時分開 |
線圈這一側是控制電路,接點那一側是負載電路,兩邊沒有電的連接,所以可以用 3.3V 的開發板控制另一個電源的電路。 繼電器的線圈要數十 mA,一樣不能直接接在 GPIO 上,所以市售的繼電器模組通常已經做好電晶體、續流二極體與指示燈, 有些還加了光耦合器;你只要接 VCC、GND 與一支訊號腳。有的模組是低電位觸發(訊號腳寫 0 才吸合),使用前看清楚模組的說明。
繼電器的缺點:切換慢(數毫秒)、會發出聲響、接點有使用次數的壽命,不適合 PWM 這種快速開關。
市電安全:繼電器的接點規格常寫著 250V AC,但 110V/220V 市電可能造成觸電與火災。 控制家電要由合格的電機人員處理,或直接使用合格的智慧插座;本課程不提供任何市電的接線方式,練習時只控制低電壓直流的負載。
逐步看:按一下切換繼電器
繼電器模組的訊號腳接 GPIO26(這個模組是高電位觸發),按鈕接 GPIO4。 程式每 0.1 秒讀一次按鈕,只在「剛按下」的那一刻切換繼電器。每 0.1 秒讀一次也剛好避開了按鈕的彈跳(第 07 課)。
溫控風扇與遲滯
用繼電器做溫控風扇,最直覺的寫法是「超過 28°C 就開,否則關」。 但溫度在 28°C 附近上下跳動時,繼電器會一下吸合、一下釋放,不只吵,接點也會很快磨損。
改成兩個門檻:超過 28°C 才開,降到 26°C 以下才關,中間的 2°C 維持原狀。這叫遲滯(hysteresis), 冷氣、電熱水瓶的溫控都是這樣做的。
if temp > 28:
relay.value(1) # 太熱:開風扇
elif temp < 26:
relay.value(0) # 夠涼:關風扇
# 26~28°C 之間:維持原本的狀態
下面的模擬裡,溫度感測模組輸出 0~3.3V,對應 0~50°C(示意)。溫度會在 28°C 附近上下跳動幾次,再升高、最後降下來。
小測驗:電晶體
為什麼不建議把小型直流馬達直接接在 GPIO 腳位上?
下面的程式估算基極電流,以及 hFE=100 時最多能讓多少集極電流流過,會印出什麼?
v_gpio = 3.3
v_be = 0.7
r_b = 1000
i_b = (v_gpio - v_be) / r_b
print(round(i_b * 1000, 1), "mA", round(i_b * 100 * 1000), "mA")
繼電器線圈兩端並聯的續流二極體,主要保護什麼?
小測驗:繼電器與遲滯
希望開發板沒有通電(或程式當掉、腳位輸出 0)時,負載一定是關閉的,負載應該接在繼電器的哪兩個接點?
下面的程式模擬遲滯控制,會印出什麼?
temps = [27.5, 28.3, 27.9, 28.4, 26.5, 25.8]
on = 0
changes = 0
for t in temps:
new = on
if t > 28:
new = 1
elif t < 26:
new = 0
if new != on:
changes += 1
on = new
print(on, changes)
專題想用繼電器控制 110V 的檯燈,下列哪一個做法正確?
重點整理
- GPIO 的電流與電壓有限,馬達、繼電器線圈、燈條要經過開關元件驅動。
- NPN 電晶體做低側開關:負載接在電源與集極之間,GPIO 經過基極電阻控制;基極電流要給足,讓電晶體飽和。
- MOSFET 用電壓控制,選邏輯準位的型號,閘極加下拉電阻;兩者都要和負載電源共地。
- 線圈類負載(馬達、繼電器)要並聯續流二極體,陰極接正電源端。
- 繼電器隔離控制端與負載端,常開(NO)接點在斷電時是斷開的;溫控這類應用用遲滯避免來回切換。
- 市電只由合格人員處理,練習時只控制低電壓直流負載。
下一課介紹三種馬達:直流馬達要用 H 橋才能反轉,伺服馬達看脈波寬度,步進馬達照順序讓線圈通電。