H橋馬達控制器(H-Bridge Motor Controlle)非常簡單,用起來也非常有趣,像小時候玩風車一樣。但是,馬達是工業應用的基礎,用起來并不簡單。
本項目電路中的 NPN 晶體管可為馬達提供更大電流,這樣我們就可以使用較小電壓來切換馬達,使用較大電壓驅動馬達,讓馬達獲得更高轉速和更大力矩。但是,一定要確保馬達工作于安全功率和要求電壓范圍內。
?
?
該電路中的開關可由微型控制器取代,可通過PWM技術控制馬達的轉速。當然,也可以控制馬達讓其在一個方向旋轉。
也可以再增加一個晶體管,這次我們使用 P-N-P 型,并通過一個二極管來保護這兩個晶體管,免受來自馬達的感性負載影響。
?
為電路正確工作,需下拉引腳2為 LOW,并為引腳3加上一個PWM信號。電路中,兩個晶體管通過推、拉電流,為馬達提供更大的力矩,實現更高的效率。
這下,我們開始提到的問題出現了,那就是如何讓讓馬達轉向。這也不難,把電路復制一下,再增加幾個元件就解決了。不過,電路看起來有些復雜。
?
?
這個電路中,Q1、Q2為P-N-P晶體管,Q3、Q4為N-P-N晶體管,P-N-P晶體管導通時基極的R1 or R2必須下拉為 LOW,N-P-N晶體管工作時基極的R3 or R4必須上拉為 HIGH。
這里,PNP和NPN晶體管必須為匹配良好的對管,電流和電壓大小要根據馬達尺寸來選擇,這取決于馬達是用于小玩具或者個人愛好,而2N2222A NPN晶體管、2N2907A PNP晶體管可提供中等性能。也可以使用NPN型2N3904晶體管和PNP型2N3906晶體管, 但是性能表現不佳,而ZTX1049A NPN型晶體管和ZTX968 PNP型晶體管的表現最佳。
對于像RC類的較大型DC馬達,NPN型的TIP120、TIP121和TIP122,PNP型的TIP125、TIP126、TIP127能夠承受5A工作電流,以及高達8A的峰值電流。但是一定要使用散熱片,這些晶體管的外形也非常大,封裝形式TO-220。
通過下拉為LOW(接地),D2、D4可打開或關斷一個指定的 PNP 晶體管(Q1 or Q2 )。
D3、D5為PWM或常態數字輸出,將其上拉為HIGH(接VCC)可打開晶體管(Q3 or Q4 )。
如果想讓馬達轉向,這也簡單。上拉D4為HIGH,下拉D5為LOW,D2也為LOW,為D3施加一個PWM信號,或者將其上拉為HIGH,看看發生了什么?
上拉D2為LOW開關Q1,上拉D5為High,或為其加上一個PWM信號,打開Q4、Q2、Q3并保持關閉。
現在,電路就開始向Q1推、拉電流,經過馬達,再經過Q4流向地,使馬達按照一定方向轉圈,我們稱之為正向。
相反,如果D2 HIGH,D4 LOW, D5 LOW,D3 HIGH或者添加一個PWM信號,使電流從Q2流出,再通過馬達的流向Q3,這就有效的改變了馬達的方向。
不過,有些情況會導致電池短路,例如:
D2 LOW,D5 High 或PWM狀態
D4 LOW,D3 High 或PWM狀態
這兩種狀態會導致電池電壓直接與“地”短路,因此千萬別使用這兩個組合。
下面是Arduino開發板代碼:
/*
* Example code to use with DIY H-Bridge ( One Motor )
* Another second motor will need another H-Bridge, and control pins
*
* Maker and IOT Ideas 2020 (MakerIOT2020)
*/
/* Define control pins */
const int fwd_enable=2;
const int fwd_pwm=3;
const int rev_enable=4;
const int rev_pwm=5;
void setup()
{
? ? ?// Set pin Modes, while preventing accidental short of supply
? ? ?digitalWrite(fwd_enable,HIGH);
? ? ?digitalWrite(rev_enable,HIGH);
? ? ?// force PNP transistors to stay off;
? ? ?digitalWrite(fwd_pwm,LOW);
? ? ?digitalWrite(rev_pwm,LOW);
? ? ?// force NPN transistors to stay off;
? ? ?// now set the pin mode.
? ? ?pinMode(fwd_enable,OUTPUT);
? ? ?pinMode(rev_enable,OUTPUT);
? ? ?pinMode(fwd_pwm,OUTPUT);
? ? ?pinMode(rev_pwm,OUTPUT);
}
void stop_all()
{
? ? ?/* This will stop everything,
? ? ?* ?allowing the motor to run free or coast)
? ? ?* ?
? ? ?*/
? ? ?digitalWrite(fwd_pwm,LOW);
? ? ?digitalWrite(rev_pwm,LOW);
? ? ?digitalWrite(fwd_enable,HIGH);
? ? ?digitalWrite(rev_enable,HIGH);
}
void motor_fwd()
{
? ? ?/* ?
? ? ? * ? Makes the motor run “forward”
? ? ? * ? If you find that it actually reverses your motor,
? ? ? * ? please swap the physical wiring at the motor once.
? ? ? * ? It should now work correctly forever …
? ? ? */
? ? ?digitalWrite(rev_enable,HIGH);
? ? ?digitalWrite(rev_pwm,LOW);
? ? ?// Make sure about the states of the other side of the
? ? ?// H-Bridge, to prevent shorts
? ? ?digitalWrite(fwd_enable,LOW);
? ? ?digitalWrite(fwd_pwm,HIGH);
? ? ?// Motor will now be on and running, at a fixed speed
}
void motor_fwd_pwm(int motor_speed)
{
? ? ?digitalWrite(rev_enable,HIGH);
? ? ?digitalWrite(rev_pwm,LOW);
? ? ?// Make sure about the states of the other side of the
? ? ?// H-Bridge, to prevent shorts
? ? ?digitalWrite(fwd_enable,LOW);
? ? ?analogWrite(fwd_pwm,motor_speed);
}
void motor_rev()
{
? ? ?digitalWrite(fwd_enable,HIGH);
? ? ?digitalWrite(fwd_pwm,LOW);
? ? ?// Make sure about the states of the other side of the
? ? ?// H-Bridge, to prevent shorts
? ? ?digitalWrite(rev_enable,LOW);
? ? ?digitalWrite(rev_pwm,HIGH);
? ? ?// Motor will now be on and running, at a fixed speed
}
void motor_rev_pwm(int motor_speed)
{
? ? ?digitalWrite(fwd_enable,HIGH);
? ? ?digitalWrite(fwd_pwm,LOW);
? ? ?// Make sure about the states of the other side of the
? ? ?// H-Bridge, to prevent shorts
? ? ?digitalWrite(rev_enable,LOW);
? ? ?analogWrite(rev_pwm,motor_speed);
}
void motor_brake()
{
? ? ?/*
? ? ? * This will brake the motor, or make it slow down
? ? ? */
? ? ? digitalWrite(fwd_enable,HIGH);
? ? ? digitalWrite(rev_enable,HIGH);
? ? ? digitalWrite(fwd_pwm,HIGH);
? ? ? digitalWrite(rev_pwm,HIGH);
}
void motor_brake_intervals(int brakes = 2)
{
? ? ?// this will brake the motor x times, default of 2
? ? ?// delay used here for ease of explanation, feel free to change
? ? ?// this to millis
? ? ?for (int i = 0; i < brakes; i++)
? ? ? ? ?{
? ? ? ? ? ? ?motor_brake;
? ? ? ? ? ? ?delayMicroseconds(10);
? ? ? ? ? ? ?stop_all();
? ? ? ? ? ? ?delayMicroseconds(10);
? ? ? ? ?}
? ? ?// and allow motor to run free
? ? ?stop_all();
}
void loop() {
?// Sample use
?// Start with a stopped motor
?stop_all();
?// go forwards
?motor_fwd();
?delay(2000);
?// brake and stop
?motor_brake_intervals(5);
?// reverse direction
?motor_rev();
?delay(2000);
?// brake and stop
?motor_brake_intervals(5);
?// PWM slow to fast
?for (int i = 155; i < 255; i+=10)
?{
? ? ?motor_fwd_pwm(i);
? ? ?delay(100);
?}
?// brake and stop
?motor_brake_intervals(5);
?delay(500);
?// Reverse fast to slow
?for (int i = 255; i > 155 ; i-=10)
?{
? ? ?motor_rev_pwm(i);
?}
?// brake and stop
?motor_brake_intervals(5);
?delay(500);
?stop_all;
}
評論
查看更多