跳轉到

第 5 章:馬達混控與 PWM 輸出

本章學習目標

  • 理解「一個 roll/pitch/yaw 修正量」怎麼變成「四顆馬達各轉多少」
  • 看懂 X 型四軸的混控(mixing)加減法(含帶你算一次
  • 知道 PWM 怎麼把數字變成馬達轉速,以及為什麼油門要留「餘量」

5.1 問題:三個修正量,四顆馬達

第 4 章內環算出三個數字:pidRateX.out(roll 修正)、pidRateY.out(pitch 修正)、pidRateZ.out(yaw 修正)。 但飛機有四顆馬達。要怎麼把「我想向右滾一點、同時稍微前傾、再轉個頭」這三件事, 同時翻譯成四顆馬達各自的轉速?這就是混控

🎚️ 生活化比喻:調音檯 想像四顆馬達是四個音量推桿。roll、pitch、yaw、油門是四個「旋鈕」。 混控就是「轉一個旋鈕,會同時推/拉某幾個推桿」的那張對應表。


5.2 X 型四軸的混控邏輯

這台是 X 型四軸:四顆馬達在四個角,對角線的兩顆同方向旋轉。要做出動作,靠的是讓某幾顆加速、某幾顆減速

  • 想滾轉(roll) → 一側兩顆加速、另一側兩顆減速 → 機身往減速側傾。
  • 想俯仰(pitch) → 前面兩顆與後面兩顆做差速 → 機頭抬或低。
  • 想偏航(yaw) → 利用螺旋槳的反扭矩:讓同方向旋轉的一對對角加速、另一對減速,反扭矩失衡 → 機身原地轉頭。

對著程式看(HAL/control.cMotorControl()):

HAL/control.c(已將 GBK 註解翻成正體中文)
MOTOR1 = MOTOR2 = MOTOR3 = MOTOR4 = LIMIT(thr_temp, 0, 700);  // 先給四顆「基礎油門」

MOTOR1 += + pidRateX.out - pidRateY.out + pidRateZ.out;       // 再疊加姿態修正
MOTOR2 += + pidRateX.out + pidRateY.out - pidRateZ.out;
MOTOR3 += - pidRateX.out + pidRateY.out + pidRateZ.out;
MOTOR4 += - pidRateX.out - pidRateY.out - pidRateZ.out;

看那一行行的正負號就是整張混控表:

roll(X) pitch(Y) yaw(Z)
MOTOR1 + +
MOTOR2 + +
MOTOR3 + +
MOTOR4

roll 那一欄:M1、M2 是 +,M3、M4 是 → 滾轉時這兩組做反向差速。 yaw 那一欄:M1、M3(+)對 M2、M4()→ 正是兩條對角線,靠反扭矩轉頭。 (哪顆馬達在哪個實體角落、轉向如何,要對照 4.四轴飞机资料 的電路圖與飛行說明書。)


5.3 帶你算一次:純滾轉

假設此刻基礎油門 thr = 400,內環要求向右滾 pidRateX.out = 100,pitch/yaw 都是 0:

馬達 計算 結果
MOTOR1 400 + 100 − 0 + 0 500
MOTOR2 400 + 100 + 0 − 0 500
MOTOR3 400 − 100 + 0 + 0 300
MOTOR4 400 − 100 − 0 − 0 300

M1、M2 加速到 500、M3、M4 降到 300——一側升、一側降,機身就往低的一側滾轉。 注意:四顆的平均仍是 400,所以總升力不變、高度不受影響,只是「歪」了。這就是混控的巧妙之處: 姿態與油門互不干擾


5.4 從數字到轉速:PWM

MOTOR1~4 算好後,最後寫進 PWM 暫存器(FLY_TYPE == 2):

HAL/control.c
PWM0 = LIMIT(MOTOR1, 0, 1000);   // PWM0 = TIM2->CCR1
PWM1 = LIMIT(MOTOR2, 0, 1000);   // PWM1 = TIM2->CCR2
PWM2 = LIMIT(MOTOR3, 0, 1000);   // PWM2 = TIM3->CCR1
PWM3 = LIMIT(MOTOR4, 0, 1000);   // PWM3 = TIM3->CCR2
  • 這台是有刷馬達:PWM 以 18kHz 開關 MOSFET,0~1000 就是導通比例(占空比)—— 500 代表「半開」,馬達拿到約一半的平均電壓 → 約半速。數字越大轉越快。
  • LIMIT(…,0,1000) 把值夾在合法範圍:負數歸 0(馬達不能反轉)、超過 1000 也封頂。
  • FLY_TYPE >= 3(無刷電調)則是 1000 + LIMIT(...),因為電調吃的是 1~2ms 脈寬,零油門對應 1000。

為什麼基礎油門只給到 700,不是 1000?

看 5.2 第一行 LIMIT(thr_temp, 0, 700):故意留 300 的餘量給姿態修正。 如果油門直接開到 1000,四顆馬達全滿,那「想加速的那顆」已經沒空間再加了—— 姿態就修不動、飛機會失控。留餘量=永遠保留修正能力。


5.5 動手驗證(先拆槳!)

這章的驗證一定要拆槳

你會讓馬達真的轉動。務必先把四個螺旋槳拆掉,把飛控拿在手上測。

  • 解鎖、給一點油門,用 ANO 上位機看四個馬達輸出值,應該都差不多(平衡)。
  • 手動把飛控往右傾,看是不是某一側兩顆數值上升、另一側下降(對應 5.3)。
  • 手動轉頭(yaw),看是不是某一條對角線兩顆上升、另一條下降。
  • 油門推到很大時再傾斜,觀察數值有沒有被 1000 封頂——體會 5.4 的「餘量」問題。

5.6 思考題

  • 用 5.3 的方法,算「同時 roll=+100、pitch=+50、yaw=0」時四顆馬達各是多少。
  • 為什麼混控加減後「四顆平均不變」對「定高」很重要?(提示:總升力)
  • 如果某顆馬達接反了(該加速卻減速),飛機解鎖會發生什麼事?你會怎麼用 5.5 的方法在拆槳狀態下提早發現?

5.7 本章對應的原始碼

檔案 看什麼
HAL/control.c MotorControl():基礎油門 + 混控 + PWM 輸出
CONFIG/TIM.c TIM2_PWM_Config() / TIM3_PWM_Config():PWM 頻率與通道
USER/ALL_DEFINE.h PWM0~3 對應哪個 TIM 通道、FLY_TYPE 腳位

下一章:到目前為止都是飛機「自己穩住自己」。但你的指令怎麼進來? 下一章看遙控接收與飛行模式切換