How can we help you today?
【致動】直流電機PWM正反轉基礎
簡介
我們無法使用微處理器、單晶片(MCU)等可程式微控器單元,直接控制致動器(電機、電磁閥…)或是較大功率元件,原因在於MCU的GPIO控制腳位是一種通用型的輸出輸入訊號處理設計思維,GPIO腳位對外的電流輸出能力(fan out)都相當微小,不足以驅動致動器等需要較大功率的元件。如下圖。解決的方法就是透過專化的處理電路,對應被控制元件(如直流電機、BLDC…)的特性進行功率放大、訊號回授、電路保護…等處裡。
設計考量上,由於DUAL22開發板經常使用在競賽環境,除了需要提供足夠的電機接口之外,也要避免外接線路的複雜性,因為競賽的環境考驗著【衝撞、運動重心、擴充性、電源充沛與保護】等問題。是以,如圖,DUAL22開發板提供4路獨立電機控制,大幅降地傳統外接線路複雜性與不穩定性;電源端使用電力強勁的鋰電池直接供電,當然我們在電路保護上也下了不少功夫。
函數庫
#include “DUAL22.h”
DUAL22函數庫參照手冊(PDF),下載。
DEMO
韌體範例說明
我們提供兩個範例,兩個程式相同的控制動作。說明如下:
我們使用DUAL22的函數庫,如上DUAL22.h,以大幅降競賽程式的複雜程度。如本單元範例(一) – 快速應用版。DUAL22函數匯入方式,請參考單元:程式環境設定。當然,若想要認識更多與細部的控制方式,你也可以直接針對GPIO進行控制,如範例(二) – 詳細設定版。
當你要編寫如範例(二)的程式時,你需要認識DUAL22腳位控制規劃,如下圖:
範例(一)、DC電機增減速循環 – 快速應用版
#include "DUAL22.h"
void setup() {
// put your setup code here, to run once:
DUAL22Inital(); //DUAL22初始化
}
void loop() {
// 電機增速循環:變數i,小於100前,每次增量1。
for(int i=0; i<100; i++)
{
mPWM(M4, mCCW, i*10); //控制M4接口電機,逆時針,PWM增速每次(i*10)
delay(100); //每次間隔100ms
}
//控制M4接口電機,逆時針,PWM數值1000。(1024max)
mPWM(M4, mCCW, 1000);
delay(1000);
// 電機減速循環:變數i,大於0之前,每次減量1。
for(int i=100; i>0; i--)
{
mPWM(M4, mCCW, i*10);
delay(100);
}
mPWM(M4, mSTOP, 0);
delay(2000);
}
範例(二)、DC電機增減速循環 – ESP32設定版
const int M4A = 23; // 馬達4 A PIN
const int M4B = 22; // 馬達4 B PIN
const int M4A_CH = 0; //PWM 設定, 馬達4 A PIN PWM 通道
const int M4B_CH = 1; //PWM 設定, 馬達4 B PIN PWM 通道
const int MFreq = 5000; // for PWM 設定
const int MRes = 10; // for PWM 設定
const int mCW = 11;
const int mCCW = 22;
const int mSTOP = 33;
void setup() {
// put your setup code here, to run once:
ledcSetup(M4A_CH, MFreq, MRes);
ledcSetup(M4B_CH, MFreq, MRes);
ledcAttachPin(M4A, M4A_CH);
ledcAttachPin(M4B, M4B_CH);
}
void loop() {
// 電機增速循環:變數i,小於100前,每次增量1。
for(int i=0; i<100; i++)
{
M4_mPWM(mCCW, i*10); //控制M4接口電機,逆時針,PWM增速每次(i*10)
delay(100); //每次間隔100ms
}
M4_mPWM(mCCW, 1000);//控制M4接口電機,逆時針,PWM數值1000。(1024max)
delay(1000);
// 電機減速循環:變數i,大於0之前,每次減量1。
for(int i=100; i>0; i--)
{
M4_mPWM(mCCW, i*10);
delay(100);
}
M4_mPWM(mSTOP, 0);
delay(2000);
}
//M4馬達正反轉PWM控制
void M4_mPWM(int Dir, int PWMSpeed)
{
if(Dir == mCW) {ledcWrite(M4A_CH, PWMSpeed); ledcWrite(M4B_CH, 0);}
else if(Dir == mCCW) {ledcWrite(M4A_CH, 0); ledcWrite(M4B_CH, PWMSpeed);}
else if(Dir == mSTOP) {ledcWrite(M4A_CH, 0); ledcWrite(M4B_CH, 0);}
}