Learning Objectives
- 說明伺服馬達用脈波寬度決定角度,並用 Servo 與 AngularServo 控制
- 依伺服的規格校正脈波寬度,讓角度對得上
- 說明直流馬達為什麼不能直接接 GPIO,要經過驅動板,並用 Motor 控制方向與速度
- 替馬達規劃獨立電源與共地
讓作品動起來
LED、蜂鳴器、顯示器都只需要一點點電流,GPIO 直接就推得動。可是要讓作品動起來,例如自動餵食器的閘門、 會轉頭的攝影機、小車的輪子,就要用馬達,而馬達是另一個等級的負載。
這一課介紹兩種最常用的馬達,並回答:
- 伺服馬達怎麼知道要轉到 30° 還是 120°?
- 直流馬達為什麼不能直接接在 GPIO 上?
- 馬達的電從哪裡來?為什麼一定要「共地」?
「自造者入門」軌第 09 課會比較直流、伺服與步進馬達的原理;這一課專注在樹莓派上怎麼接、怎麼寫。
伺服馬達:脈波寬度就是角度
伺服馬達裡面有馬達、齒輪、位置感測與控制電路,只要告訴它「轉到幾度」,它會自己轉過去並維持在那裡。它有三條線:
| 線(常見顏色) | 接到 |
|---|---|
| 電源(紅) | 5V 電源(建議用獨立電源,下面說明) |
| 地(棕或黑) | GND,和樹莓派共地 |
| 訊號(橘或黃) | GPIO,例如 GPIO18 |
訊號是第 07 課的 PWM:每 20 ms 送一個脈波(50 Hz),脈波的寬度決定角度。以常見的小型伺服 SG90 為例, 規格書寫的脈波寬度大約是 0.5 ms~2.4 ms,對應 0°~180°;不同廠牌、甚至同一型號的不同批次都略有差異。
gpiozero 有兩個類別:
from gpiozero import Servo, AngularServo
s = Servo(18) # value 從 -1 到 1;預設脈波 1 ms~2 ms
s.min(); s.mid(); s.max() # 等於 value = -1、0、1
a = AngularServo(18, min_angle=0, max_angle=180,
min_pulse_width=0.5/1000, max_pulse_width=2.5/1000)
a.angle = 90 # 直接用角度
Servo 預設的 1 ms~2 ms 比很多伺服實際能接受的範圍窄,所以 min() 到 max() 可能轉不到 180°。
要轉滿,就用 min_pulse_width、max_pulse_width 依你的伺服校正:從小範圍開始慢慢放寬,聽到伺服頂住的聲音就退回來,
免得齒輪一直出力。
模擬器畫的伺服以 0.5 ms=0°、2.5 ms=180° 換算角度(示意),所以預設的
Servo只會在 45°~135° 之間轉。
逐步看:Servo 的 min、mid、max
看電路上伺服顯示的角度與脈波寬度。注意建立 Servo 的那一步:預設的 initial_value 是 0,伺服一通電就先轉到中間。
逐步看:校正過的 AngularServo
把脈波寬度設成 0.5 ms~2.5 ms、角度設成 0~180,程式就能直接寫角度。對照每一步印出的脈波寬度。
直流馬達:一定要經過驅動板
小型直流馬達接上電就轉,電壓反過來就反轉,電壓越高轉越快。但它絕對不能直接接在 GPIO 上:
- 樹莓派官方文件寫明,每支 GPIO 最多只能提供 16 mA,全部 GPIO 加起來也只有約 50 mA;一顆小馬達啟動時的電流就遠超過這個數字。
- 馬達是線圈,停止或換方向時會產生反向的電壓突波,可能傷害樹莓派。
所以中間要放一塊馬達驅動板,核心是 H 橋電路:GPIO 只送出很小的控制訊號,驅動板用自己的電源去推馬達。 常見的驅動晶片有 DRV8833、TB6612FNG 等,接受 3.3V 的控制訊號;較舊的 L298N 模組壓降比較大,使用前確認它認得 3.3V 的訊號。
驅動板的兩個輸入腳(常標成 IN1、IN2)決定馬達怎麼轉:
| IN1 | IN2 | 馬達 |
|---|---|---|
| 高 | 低 | 正轉 |
| 低 | 高 | 反轉 |
| 低 | 低 | 停止(自由滑行) |
速度用 PWM 控制:IN1 送工作週期 40% 的 PWM,馬達就以大約四成的力氣轉。gpiozero 的 Motor 把這些都包好了:
from gpiozero import Motor
m = Motor(forward=23, backward=24) # 接驅動板的 IN1、IN2
m.forward(0.4) # 0~1 是速度
m.backward()
m.stop()
逐步看:正轉、減速、停止、反轉
電路上的馬達顯示正轉或反轉,以及目前的速度。程式只控制兩支 GPIO,真正推動馬達的是驅動板。
獨立電源與共地
馬達與伺服的電流大、而且忽大忽小。如果從樹莓派的 5V 腳位取電,負載一重,樹莓派的電壓可能跟著往下掉, 輕則 USB 裝置斷線、重則整台重新開機。所以:
- 馬達用獨立的電源:電池盒或另一個電源供應器,接到驅動板的馬達電源輸入(常標成 VM 或 VMOT)與伺服的電源線。 電壓依馬達與驅動板的規格選擇,不要超過。
- 一定要共地:把馬達電源的 GND、驅動板的 GND、樹莓派的 GND 接在一起。電壓永遠是「兩點之間」的差, 樹莓派說的 3.3V 是相對於它自己的 GND;兩邊的地沒接在一起,驅動板看不懂樹莓派送來的訊號。
- 不要把馬達電源接到樹莓派的 GPIO 或 3.3V,接線前再檢查一次正負極。
伺服馬達在作業系統很忙時可能會微微抖動:gpiozero 常用軟體產生 PWM,脈波寬度偶爾不準(第 07 課)。 需要穩定的角度時,可以改用支援硬體 PWM 的腳位工廠,或是專門的伺服驅動板(例如 PCA9685 這類 I2C 的 PWM 晶片)。
小測驗:伺服
伺服馬達的訊號是每 20 ms 一個脈波,這個 PWM 的頻率是多少?
下面的程式會印出什麼?(0.5 ms 對應 0°、2.5 ms 對應 180°)
angle = 135
pulse = 0.5 + angle / 180 * 2.0
print(pulse)
用預設的 Servo(18),min() 到 max() 只轉了大約 90°,最合理的做法是?
小測驗:直流馬達與電源
驅動板的 IN1 是低電位、IN2 送工作週期 70% 的 PWM,馬達會怎樣?
馬達用電池盒供電,驅動板的控制腳接樹莓派。哪一種接法是對的?
重點整理
- 伺服:每 20 ms(50 Hz)一個脈波,脈波寬度決定角度;
Servo用 -1~1,AngularServo直接用角度,記得依規格校正脈波寬度。 - 直流馬達不能直接接 GPIO(每支腳約 16 mA 上限,還有反向電壓突波),要經過 H 橋驅動板。
- 驅動板的 IN1/IN2 決定方向,PWM 的工作週期決定速度;gpiozero 的
Motor用forward(速度)、backward(速度)、stop()。 - 馬達與伺服用獨立電源,並把所有 GND 接在一起(共地);不要讓馬達電源碰到 GPIO。
- 伺服抖動常見的原因是軟體 PWM 時間不準或電源不足,可以考慮硬體 PWM 或專用的伺服驅動板。
下一課加上「眼睛」:用超音波量距離、用人體感測器知道有人經過。