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;
}
luckyzy2000 2022-6-17 10:58