直流馬達(DC Motor)是一種將電能轉換為機械能的裝置。其基本原理基於「勞侖茲力」:當載有電流的導體(線圈)放置在磁場中時,會受到一個力的作用,從而產生轉矩,驅動馬達轉動。馬達內部的電刷和換向器結構確保線圈在不同旋轉角度下能持續朝同一方向轉動。
要控制直流馬達的轉速,最常見的方法是使用脈衝寬度調變(Pulse-Width Modulation, PWM)。
- 原理:PWM 技術不是改變電壓大小,而是快速地開關電源,並調整「開啟」時間佔總週期的比例(稱為工作週期 Duty Cycle)。
- 效果:
- 高工作週期(如90%):馬達獲得的平均功率較高,轉速較快。
- 低工作週期(如20%):馬達獲得的平均功率較低,轉速較慢。
- Arduino 實作:Arduino 的 analogWrite(pin, value) 函式就是用來產生PWM訊號的。value 的範圍是 0(0% 工作週期,停止)到 255(100% 工作週期,全速)。
理論上的方向控制:
要改變馬達的旋轉方向,最直觀的方法就是將供應給馬達的電源正負極交換。如果你將一個直流馬達接到電池上,然後將電線反接,你會發現馬達立刻反向旋轉。
實務上的挑戰:
這個「手動換線」的方法在自走車、機器手臂等需要動態改變方向的專案中是完全不可行的。我們不可能在程式跑到一半時,親手去拔插電線。我們需要的是一種能讓 Arduino 用程式邏輯訊號來控制電流方向的方法。
解決方案:馬達驅動器 (Motor Driver)
這就是為什麼馬達驅動器是不可或缺的。它一次解決了控制直流馬達的兩大核心問題:
功率放大 (Power Amplification):
Arduino 的 I/O 接腳輸出電流非常小(約 20-40mA),遠不足以驅動馬達(通常需要數百mA甚至數A)。馬達驅動器從外部電源獲取足夠的電力,並根據 Arduino 的訊號來驅動馬達,就像一個由程式控制的「大功率水龍頭」。直接將馬達接到 Arduino 會燒毀開發板!
方向控制 (Direction Control):
馬達驅動器內部整合了稱為 H-Bridge (H橋) 的精密電路。這個電路就像一個由程式控制的「雙向道閘門」,可以根據 Arduino 送來的 HIGH 或 LOW 訊號,來決定電流要「從左到右」還是「從右到左」流過馬達,從而實現程式化的正反轉控制。
總結來說,馬達驅動器扮演著「翻譯官」兼「大力士」的角色:它將 Arduino 微弱的「指令」(邏輯訊號)轉譯成強大的「動作」(大電流輸出),並能依指令決定動作的方向。
| 特性 | 一般直流馬達 (無齒輪箱) | TT馬達 (帶減速齒輪箱) |
|---|---|---|
| 轉速 | 非常高 | 較低 |
| 扭力 | 非常低 | 較高 |
| 應用場景 | 風扇、飛輪、需要高速旋轉的場合 | 輪型機器人、履帶車、需要力量的場合 |
| 控制 | 轉速不易在低速時穩定控制 | 轉速相對穩定,適合入門自走車 |
| 選擇建議 | 如果你需要高速旋轉,例如做一個小風扇。 | 如果你需要驅動輪子或任何需要力量的結構,請選擇TT馬達。 |
H-Bridge (H橋) 是所有直流馬達驅動器的核心電路。它的名字來自其電路結構形狀像一個大寫的 "H"。
H橋由四個電子開關(Q1, Q2, Q3, Q4)組成。在現代驅動器中,這些開關通常是電晶體(Transistors),由 Arduino 發出的邏輯訊號控制其開關狀態。馬達(M)被放置在H的中央橫槓上。
1. 正轉 (Forward)
- 狀態:開關 Q1 和 Q4 閉合,Q2 和 Q3 斷開。
- 電流路徑:電流從 Power+ -> Q1 -> 馬達 (左至右) -> Q4 -> Ground-。
- 結果:馬達向一個方向旋轉。
2. 反轉 (Reverse)
- 狀態:開關 Q2 和 Q3 閉合,Q1 和 Q4 斷開。
- 電流路徑:電流從 Power+ -> Q2 -> 馬達 (右至左) -> Q3 -> Ground-。
- 結果:馬達向相反方向旋轉。
3. 自由滑行 (Coast / Freewheeling)
- 狀態:所有開關 Q1, Q2, Q3, Q4 全部斷開。
- 電流路徑:沒有電流路徑。馬達與電路完全斷開。
- 結果:馬達會因自身的慣性繼續旋轉,直到摩擦力使其自然停止。這就像空檔滑行。
4. 電磁煞車 (Dynamic Brake)
- 狀態:上方開關 Q1, Q2 斷開,下方開關 Q3, Q4 閉合。
- 電流路徑:馬達的兩個接腳被 Q3 和 Q4 短路在一起。
- 結果:
- 由於慣性,仍在旋轉的馬達會像一個小型發電機一樣產生感應電動勢。
- 這個電壓在短路的迴路中產生電流。
- 根據勞侖茲力,這個電流會產生一個與旋轉方向相反的扭力,從而迅速地讓馬達停下來。這提供了比自由滑行更快的煞車效果。
絕對不能讓同一側的開關(例如 Q1 和 Q3,或 Q2 和 Q4)同時閉合。這會造成從 Power+ 直接通過兩個開關流向 Ground- 的短路,產生巨大電流,瞬間燒毀馬達驅動器。專業的馬達驅動晶片(如L298N)內部都設計有「死區時間」或保護邏輯,以防止這種情況發生。
除了 L298N,市面上還有許多不同的馬達驅動器,各有優劣:
- L298N:經典、便宜、耐用,但效率較低、體積大、會發熱。適合初學者。
- TB6612FNG:比 L298N 更現代、效率更高、體積小。是目前許多專案的首選。
- DRV8833:與 TB6612FNG 類似,體積小、效率高,常用於小型機器人。
- 馬達擴充板 (Motor Shield):直接插在 Arduino 上的擴充板,通常整合了 TB6612FNG 或類似晶片,接線非常方便,但價格較高。
這張圖展示了如何連接 Arduino UNO、L298N、兩個TT馬達以及一個外部電池盒,構成一個典型的雙輪驅動車基礎。
假設 IN1, IN2 控制左輪,IN3, IN4 控制右輪。轉速由 ENA, ENB 的PWM值決定。
| 動作 | IN1 | IN2 | IN3 | IN4 | 說明 |
|---|---|---|---|---|---|
| 前進 | HIGH |
LOW |
HIGH |
LOW |
兩個馬達都向前轉 |
| 後退 | LOW |
HIGH |
LOW |
HIGH |
兩個馬達都向後轉 |
| 左轉 | LOW |
HIGH |
HIGH |
LOW |
左輪後退,右輪前進 (原地旋轉) |
| 右轉 | HIGH |
LOW |
LOW |
HIGH |
左輪前進,右輪後退 (原地旋轉) |
| 停止 | LOW |
LOW |
LOW |
LOW |
兩個馬達停止 (自由滑行) |
註:左轉和右轉也可以透過單邊輪子轉動、另一邊停止的方式實現,會是畫弧線轉彎而非原地旋轉。
這個範例程式會讓自走車重複執行「前進2秒 -> 停止1秒 -> 右轉0.5秒 -> 停止1秒」的動作。
// ===== Pin Definitions =====
// Motor A (Left)
const int enA = 9; // 左輪轉速控制 (PWM)
const int in1 = 8; // 左輪方向控制
const int in2 = 7; // 左輪方向控制
// Motor B (Right)
const int enB = 6; // 右輪轉速控制 (PWM)
const int in3 = 5; // 右輪方向控制
const int in4 = 4; // 右輪方向控制
// ===== Speed Setting =====
int motorSpeed = 200; // 設定馬達轉速 (0-255)
// ===== Setup Function =====
void setup() {
// 將所有控制腳位設定為輸出模式
pinMode(enA, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
// 程式開始時,先讓馬達停止
stopMotors();
}
// ===== Main Loop =====
void loop() {
// 1. 前進 2 秒
moveForward(motorSpeed);
delay(2000);
// 2. 停止 1 秒
stopMotors();
delay(1000);
// 3. 右轉 0.5 秒
turnRight(motorSpeed);
delay(500);
// 4. 停止 1 秒
stopMotors();
delay(1000);
}
// ===== Custom Functions =====
// 前進
void moveForward(int speed) {
// 左輪前進
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, speed);
// 右輪前進
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
analogWrite(enB, speed);
}
// 後退
void moveBackward(int speed) {
// 左輪後退
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
analogWrite(enA, speed);
// 右輪後退
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
analogWrite(enB, speed);
}
// 原地右轉
void turnRight(int speed) {
// 左輪前進
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, speed);
// 右輪後退
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
analogWrite(enB, speed);
}
// 原地左轉
void turnLeft(int speed) {
// 左輪後退
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
analogWrite(enA, speed);
// 右輪前進
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
analogWrite(enB, speed);
}
// 停止
void stopMotors() {
// 左輪停止
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
analogWrite(enA, 0);
// 右輪停止
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
analogWrite(enB, 0);
}
const int)定義所有接腳,方便未來修改與閱讀。setup():pinMode() 將所有控制腳位設為 OUTPUT。stopMotors(),確保裝置啟動時不會暴衝。loop():moveForward)和 delay() 來實現一個簡單的自動控制流程。loop() 中的邏輯更清晰,並且可以重複使用這些動作。digitalWrite() 設定方向,並用 analogWrite() 設定速度。stopMotors() 函式將所有方向設為 LOW,並將PWM速度設為 0,徹底停止馬達。問題:馬達完全沒反應
VCC 是否接到外部電源?外部電源是否有電?GND 是否同時連接到外部電源負極和 Arduino 的 GND?這是最常見的錯誤。ENA 和 ENB 跳線帽是否插著?如果拔掉了,需要手動將 ENA 和 ENB 接到 HIGH 或 PWM 腳位。5V EN 跳線帽是否插著?如果拔掉了,需要手動為 5V 腳位提供邏輯電源。問題:馬達轉向或轉速不如預期
IN1/IN2 和 IN3/IN4 的接線是否與程式碼中的定義一致?HIGH/LOW 的組合是否正確?ENA 和 ENB 是否接到 Arduino 的 PWM 腳位(有 ~ 符號的)?如果接到普通數位腳位,將無法調速。OUT1/OUT2 或 OUT3/OUT4 的接線,看看轉向是否反了。如果反了,可以交換接線或修改程式碼邏輯。問題:Arduino 板上的燈變暗或重啟