A DC motor speed can be controlled using PWM(Pulse Width Modulation) and to control its direction of roatation, clockwise and anti-clockwise direction, an H bridge is required. The H-bridge can be made using BJT(Bipolar Junction Transistor) or FET(Field Effect Transistor) transistors or a dedicated H-bridge Integrated Circuits(IC) such as L298N or L293D can be used. Here an example of using H-bridge made up of BJT transistor for direction control of DC motor is presented. The H-bridge is made up of 2N2222 general purpose transistor. Other similar transistor like 2N3904 and BC547 can be used.
The following shows animation of how the BJT based H-bridge works. The H-bridge and hence DC motor is controlled using ATmega16 microcontroller.
In the animation diagram above, when the switch on PD2 is pressed the direction of the rotation of the motor changes. The animation also shows the current flowing through the H-bridge and the motor. To construct the H-bridge four transistors 2N2222 are required. Each acts as a microcontroller switch. Each of the transistor is connected to the PA0, PA1, PA2 and PA3. The direction of rotation is controlled by turning on or off the switches. For clockwise rotation, the transistor Q1 and Q4 are turned on so that the current from the +12V power sources flows from the transistor Q1 into the DC motor and then through the transistor Q4 to the ground. In this case the transistor Q2 and Q3 are turned off. In similar manner, for anti-clockwise rotation, the transistor Q2 and Q3 are turned on while the transistors Q1 and Q4 are turned off. Here we have directly connected the transistors to the microcontroller pins. For protection it is better to use optocouplers, diode and capacitors. For this see the post DC motor control with ATmega32 Optocoupler and Darlington Pair.The following is the program code for the ATmega16 microcontroller.
#ifndef F_CPU
#define F_CPU 4000000UL
#endif
#include <avr/io.h>
#include <util/delay.h>
#define SW (PIND & (1<<PD2))
int main(){
DDRA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3));
DDRD &= ~(1<<PD2);
PORTD |= (1<<PD2);
while (1){
if(SW){
PORTA |= ((1<<PA0) | (1<<PA3));
PORTA &= ~((1<<PA1) | (1<<PA2));
}
else{
PORTA |= ((1<<PA1) | (1<<PA2));
PORTA &= ~((1<<PA0) | (1<<PA3));
}
}
return 0;
}
Video demonstration:
See other following tutorials on DC motors:
- Controlling Motor Speed with PWM
- DC motor Speed control with Potentiometer and PWM using Arduino