3.15. 直流馬達控制

直流有刷馬達是一個位於磁場中、繞在軸上的線圈。讓電流通過線圈,磁場便會對其施力;這股力轉換為軸上的扭矩。馬達內部的電刷會在軸轉動時切換線圈中的電流方向,使扭矩始終朝同一方向推動軸。在馬達的兩條引線間施加直流電壓,軸就會旋轉;交換極性,它便會反向旋轉。

馬達通常需要數百毫安到數安培的電流,且供應電壓高於相機 3.3 V 的邏輯電軌。一個 GPIO 接腳大約只能供應 25 mA 的電流,且無法反轉極性——它只能在其兩條電軌間驅動。位於相機與馬達之間的驅動級必須承載馬達的電流、引入一條獨立的較高電壓馬達電源,並讓相機能依指令反轉極性。四電晶體的 H 橋(H-bridge) 正是標準解答。

3.15.1. H 橋

H 橋是環繞馬達、排成 H 形的四個開關:

一張 H 橋電路圖。頂端的 Vmotor 透過 開關 S1 向下連到左側的節點 A,並透過 開關 S2 向下連到右側的節點 B。馬達 M 水平地位於 A 與 B 之間。從 A 另有一個 開關 S3 向下接地;從 B 另有一個開關 S4 向下接地。

H 橋:四個開關(S1 -- S4)將馬達 M 連接在 Vmotor 與地之間。

閉合不同的開關配對,可選擇馬達引線兩端所看到的狀態:

  • S1 + S4 閉合,S2 + S3 斷開。 電流從 Vmotor 流經 S1,進入 A,穿過馬達到 B,再經 S4 到地。馬達朝一個方向轉動。

  • S2 + S3 閉合,S1 + S4 斷開。 電流以相反方向流過馬達。馬達朝另一個方向轉動。

  • 四個全部斷開。 馬達兩條引線皆浮接;馬達自由滑行。

  • S3 + S4 閉合(或 S1 + S2 閉合)。 馬達兩條引線都接到同一條電軌;馬達自身的動能驅動出的電流被閉合的配對短路而以熱的形式耗散掉。馬達進行煞車。

禁止的組合是閉合同一列中的兩個開關——S1 + S3S2 + S4——這會形成從 Vmotor 直通到地的短路。這就是 貫穿導通(shoot-through),相機的程式碼絕不能允許它發生。

實務上這四個開關是 MOSFET(在 電壓位準轉換 頁面中介紹過),位於一顆整合式驅動 IC 內。這顆晶片對外提供兩到三個邏輯準位的輸入接腳,在內部對應到那四個開關,並含有防止貫穿導通的互鎖邏輯,因此相機的程式碼無需直接管理它。

3.15.2. PWM 與馬達的電感

設定馬達的 轉速 需要的不只是全開與全關。其訣竅與 以 PWM 調節 LED 亮度 中用於 LED 的方式相同:以高頻率脈衝驅動,並讓負載將結果平均化。對 LED 而言,平均器是人眼;對馬達而言,平均器則是線圈本身。

馬達線圈具有可觀的電感。流過電感的電流無法瞬間改變;它以正比於其兩端電壓的速率變化。以 20 kHz 對橋路進行開關脈衝,會在每個導通階段使線圈電流上升,而在斷開階段電流必須持續流動——線圈會反轉自身兩端的電壓以維持它。

若沒有去處,這股電流會把剛斷開的開關兩端電壓向上拉高,可能損壞電晶體。跨接在每個開關上的 續流二極體(freewheeling diode)——通常就是驅動晶片內 MOSFET 本身的本體二極體——為電流提供所需的路徑。電流流經一個二極體,再繞回經過某個仍閉合的開關,形成一個 續流迴路(freewheel loop),其中電流透過橋路與馬達本身的微小電阻逐漸衰減。該二極體還會把斷開開關兩端的電壓鉗位在迴路返回的那條電軌的一個二極體壓降之內,遠在 MOSFET 的安全工作區之內。

電流在每個 PWM 週期中的 平均值 才是產生扭矩的關鍵,而該平均值與占空比呈線性關係——將占空比加倍大致會使扭矩加倍,在固定負載下也大致使轉速加倍。不同於 LED 調光(人眼的非線性響應需要一條曲線),duty_u16 的線性掃描本身就對應到馬達輸出的線性掃描。

PWM 頻率只需跨過兩道門檻:

  • 在約 20 kHz 以上,載波超出人類可聽頻帶。低於此頻率時,線圈上的磁力會隨每個 PWM 脈衝上下變化,繞組與疊片便會以載波頻率實際振動——馬達實質上變成一個發出 PWM 音調的小喇叭。

  • 遠高於約 50 kHz 時,MOSFET 及其閘極驅動器會因切換損耗而開始損失效率。在每次開關切換的過程中,MOSFET 會短暫地同時承受可觀的電壓與可觀的電流,以熱的形式耗散一小段功率;此外,MOSFET 的閘極電容每個週期都必須充電與放電,這由驅動晶片來負擔。這兩項成本都隨 PWM 頻率上升,因此在高頻率下,切換產生的熱量可能與導通馬達電流產生的熱量不相上下。

對於業餘等級大小的馬達,20 kHz 是合宜的預設值。

3.15.3. 驅動 H 橋

雙輸入的 H 橋驅動晶片大致以如下方式將 IN1IN2 對應到那四個開關:

  • IN1 = 0, IN2 = 0 -- 滑行(四個開關全部斷開)。

  • IN1 = 1, IN2 = 0 -- 朝一個方向驅動。

  • IN1 = 0, IN2 = 1 -- 朝另一個方向驅動。

  • IN1 = 1, IN2 = 1 -- 煞車。

將這兩個輸入作為 PWM 輸出來驅動,可讓相機透過選擇兩個接腳中 哪一個 承載占空比來設定方向,並透過占空比本身的數值來設定轉速:

import time
from machine import PWM, Pin

in1 = PWM(Pin("P7"), freq=20_000, duty_u16=0)
in2 = PWM(Pin("P8"), freq=20_000, duty_u16=0)

def drive_a(speed):       # speed: 0..65535
    in1.duty_u16(speed)
    in2.duty_u16(0)

def drive_b(speed):
    in1.duty_u16(0)
    in2.duty_u16(speed)

def coast():
    in1.duty_u16(0)
    in2.duty_u16(0)

def brake():
    in1.duty_u16(65535)
    in2.duty_u16(65535)

drive_a(32768)    # half speed in direction A
time.sleep(2)
drive_b(16384)    # quarter speed in direction B
time.sleep(2)
coast()

從關到全開再回到關的斜坡可帶來平順的啟動與停止:

for d in range(0, 65535, 256):
    in1.duty_u16(d)
    time.sleep_ms(10)
for d in range(65535, 0, -256):
    in1.duty_u16(d)
    time.sleep_ms(10)

3.15.4. 方向與速度型驅動器

另一類 H 橋晶片提供了更便利的介面:一個數位 方向 輸入(常標記為 DIR 或代表「相位(phase)」的 PH),加上一個 速度 輸入(常為 PWM 或代表「致能(enable)」的 EN)。方向接腳決定橋路驅動的方向;速度接腳上的占空比則設定平均電流。

這比雙 PWM 輸入的方案更易於從軟體驅動。這兩個訊號正好符合問題通常的表述方式——「朝這個方向,以這個速度轉」——因此程式碼可以寫成 set_direction(forward); set_speed(50),而不必在 in1in2 之間分支判斷。只需要一個 PWM 通道,這便釋放出同一計時器上的另一個通道供無關的工作使用。而且方向接腳在多次變更之間可保持不動而無需重新觸發橋路,因此在固定方向下變更速度只需動到一個暫存器。

import time
from machine import PWM, Pin

dir_pin = Pin("P8", Pin.OUT)
speed = PWM(Pin("P7"), freq=20_000, duty_u16=0)

def drive(direction, speed_u16):
    dir_pin.value(direction)         # 0 or 1
    speed.duty_u16(speed_u16)        # 0..65535

drive(0, 32768)     # direction A at half speed
time.sleep(2)
drive(1, 16384)     # direction B at quarter speed
time.sleep(2)
speed.duty_u16(0)   # stop

在這類驅動器上「停止」實際上做什麼——滑行還是煞車——取決於晶片。使用雙輸入驅動器時,由相機的程式碼來選擇(兩個輸入皆為低代表滑行,皆為高代表煞車);使用方向與速度型驅動器時,則由晶片決定,因此在依賴任一行為之前,值得查閱一下資料手冊。