NOTES | 技術筆記

樹莓派用 Python 控制步進馬達:接線、程式與常見問題

從選驅動板、接線到 Python 程式,說明樹莓派怎麼讓步進馬達正轉、反轉、轉指定角度。涵蓋 ULN2003+28BYJ-48 與 A4988/TMC2209 兩種接法,以及抖動、失步、發燙的原因。

這篇是樹莓派步進馬達控制的實作筆記。完整程式碼在 GitHub。

驗證狀態:程式以模擬測試驗證;接線表依驅動板與樹莓派腳位規格整理,尚未實機測試。實機測過後會更新這篇。

先選驅動方式

樹莓派的 GPIO 電流很小,不能直接接馬達,中間一定要有驅動板。常見兩種:

ULN2003 + 28BYJ-48 A4988/TMC2209 + NEMA17
價格 很便宜,常整組賣 較高
扭力 小,有減速齒輪 大
轉速 慢,約 10~15 rpm 以內 快
控制線 4 條(IN1~IN4) 2~3 條(STEP、DIR、EN)
適合 展示、輕負載、學習 滑軌、治具、需要力量的機構

接線

ULN2003 + 28BYJ-48

ULN2003 板 樹莓派
IN1~IN4 GPIO17、18、27、22(實體 pin 11、12、13、15)
+ 外接 5V
− 外接電源負極,並接樹莓派 GND

A4988/TMC2209 + 步進馬達

驅動器 樹莓派
STEP GPIO20(pin 38)
DIR GPIO21(pin 40)
EN GPIO16(pin 36),低電位啟用
VDD/GND(邏輯) 3.3V(pin 1)/GND
VMOT(馬達電源) 外接,依馬達與驅動器規格

兩種接法都要共地:馬達電源的負極要和樹莓派 GND 接在一起,否則訊號沒有共同的參考電位,馬達會亂抖或不動。

程式的核心

ULN2003:照序列輪流通電

28BYJ-48 有四組線圈,依順序通電就會轉。半步序列共 8 個狀態,往前走就是正轉,往回走就是反轉:

HALF_STEP_SEQUENCE = (
    (1, 0, 0, 0), (1, 1, 0, 0), (0, 1, 0, 0), (0, 1, 1, 0),
    (0, 0, 1, 0), (0, 0, 1, 1), (0, 0, 0, 1), (1, 0, 0, 1),
)

def step(self, direction):
    self.index = (self.index + direction) % 8
    for out, value in zip(self.outputs, HALF_STEP_SEQUENCE[self.index]):
        out.value = value

STEP/DIR:方向一條線,脈衝一條線

驅動器把線圈時序都處理掉了,程式只要設定方向,再送一個脈衝就走一步:

def step(self, direction):
    self.dir_out.value = 1 if direction == CW else 0
    self.step_out.value = 1
    time.sleep(5e-6)
    self.step_out.value = 0

轉速怎麼換算

每一步之間要等多久,由轉速和「一圈幾步」決定:

每步間隔(秒) = 60 ÷ (rpm × 一圈步數)

例如 1.8° 馬達一圈 200 步,60 rpm 就是每步 5 毫秒。

一圈到底幾步

  • 28BYJ-48 半步:約 4096 步。不同批次的減速比略有差異,要精準定位請自己轉十圈量一下。
  • 1.8° 步進馬達:整步 200 步;驅動器設成 16 微步就是 3200 步。程式裡的 --steps-per-rev 要跟驅動器設定一致,不然角度會不準。

常見問題

馬達只抖不轉 多半是線序錯,或轉速太快。28BYJ-48 先把轉速降到 5 rpm 試;STEP/DIR 驅動器檢查馬達兩組線圈有沒有接對(同一組線圈的兩條線,量起來電阻很小)。

轉一轉會失步、位置跑掉 負載太重或轉速太快。先降速;要快又要穩,就需要加減速曲線,或換扭力更大的馬達。

馬達很燙 停著的時候線圈還一直通電。程式預設結束會放開線圈(release());如果你需要停著也保持出力,再加 --hold。A4988、TMC2209 這類驅動器也要先把電流限制調到馬達的額定值。

換了樹莓派 5 就不能用 Pi 5 的 GPIO 架構改了,舊的 RPi.GPIO 套件不支援。這份程式用的是 gpiozero,Raspberry Pi OS 內建,Pi 5 也能用。

不接硬體先測

程式裡有 Mock 模式和 11 個自動測試,可以先在電腦上確認邏輯:

python3 cli.py --driver mock --turns 1
python3 -m unittest -v

這種程式的極限

Python 在 Linux 上用 time.sleep 控制節奏,一般的正反轉、定位都夠用;但作業系統排程會造成微小的時間抖動,需要高轉速、非常平順的運動,或多軸精準同步,就該改用硬體 PWM、pigpio,或交給專用的運動控制板。

← 回到技術筆記

你的情況也類似?

加 LINE 最快。說說你現在怎麼做、想變成什麼樣子,
我回你可行的做法和需要釐清的問題。

加 LINE 聊一聊 →

或寫信:ted@tedshen.link