In this Arduino Electronics tutorial, DC motor speed and direction control using Fast PWM method is illustrated. To control the DC motor the L298N motor driver is used. Fast PWM signal is generated on pin 6(OC0A) and pin 5(OC0B) on Arduino using Timer 0 which is fed into the L298N motor driver. The output from the L298N is used to drive a simple DC motor. Example arduino code for Fast PWM DC motor control is provided.
Arduino has six PWM pins out of which 6 and 5 are used by Timer 0. We can generate broadly two types of PWM signal with Arduino one of which is Fast PWM and the other is Phase Correct PWM. Within Fast PWM we can generate inverted and non-inverted Fast PWM signal. Although it is adviced to use Phase Correct PWM mode for motor control application, here for sake of illustration we will use Fast PWM mode. The analogWrite() function used with Arduino uses Phase Correct PWM mode which was illustrated in previous tutorials How to use L298N motor driver with Arduino and Arduino L298N DC Motor Speed control with PWM.
The following picture L298N connected to Arduino PWM pins 5 and 6, the DC motor, the diode protection on a breadboard.
The circuit schematic of the interfacing of L298D with Arduino, DC motor and diodes is shown below.
In the above circuit schematic diagram, the Arduino pins 6(OCA0) and 5(OCB0) are connected to IN1 and IN2 of the L298N motor driver respectively. The OCA0 and OCB0 are used by Timer 0 to output Fast PWM. The digital pin 7 of Arduino is connected to the ENA pin of L298N motor driver. The DC motor is connected to OUT1 and OUT2 of the L298N. The protection diode for back e.m.f from motor wires due to sudden cutoff of current are connected to the DC motor as shown.
DC motor speed control Arduino code
Below is arduino code for DC motor speed and direction control using L298D motor driver.
//Program for DC motor speed control using Fast PWM with L298N & Arduino
//Source: https://www.ee-diary.com
void forward(int D){
pinMode(6,OUTPUT);
pinMode(5,OUTPUT);
digitalWrite(5,LOW);
digitalWrite(7,HIGH);
OCR0A = (unsigned char)((256*D)/100)-1;
TCCR0A = (1 << COM0A1) | (1<<WGM01) | (1<<WGM00);
TCCR0B = (1 << CS00);
}
void reverse(int D){
pinMode(6,OUTPUT);
pinMode(5,OUTPUT);
digitalWrite(6,LOW);
digitalWrite(7,HIGH);
OCR0B = (unsigned char)((256*D)/100)-1;
TCCR0A = (1 << COM0B1) | (1<<WGM01) | (1<<WGM00);
TCCR0B = (1 << CS00);
}
void stop(){
digitalWrite(8, LOW);
}
void setup () {
Serial.begin(9600);
pinMode(7,OUTPUT);
digitalWrite(7,LOW);
}
int sp;
char dir;
void loop() {
Serial.println("\nEnter Direction(f=forward,r=reverse,s=stop):");
while (Serial.available() == 0){}
dir = Serial.read();
Serial.println(dir);
while(Serial.available() == 0){}
sp = Serial.parseInt();
switch(dir){
case 'f':
Serial.println("Enter Duty Cycle(0 to 100):");
while(Serial.available() == 0){}
sp = Serial.parseInt();
Serial.println(sp);
forward(sp);
break;
case 'r':
Serial.println("Enter Duty Cycle(0 to 100):");
while(Serial.available() == 0){}
sp = Serial.parseInt();
Serial.println(sp);
reverse(sp);
break;
case 's':
Serial.println("motor stopped!");
stop();
break;
default:
while (Serial.available() == 0){}
break;
}
}
In the above arduino code for dc speed and direction control, we have used two functions called forward() and reverse(). The forward() function is used to rotate the motor in forward direction with user specified duty cycle. Similarly the reverse() is used to rotate the motor in reverse direction with user specified duty cycle. In the forward() function, we supply Fast PWM signal on pin 6 or OCA0 pin with some duty cycle. The duty cycle is loaded into the OCR0A register. Also in case of forward direction the pin 5 or OC0B is made low. The fast pwm signal then flows from OCR0A into the motor and out into the OC0B. This is explained in details with duty cycle formula in the tutorial Programming Arduino Timer 0 in Fast PWM mode. Similarly, for reverse direction we output fast pwm signal from OC0B pin and into the motor and out into the OC0A. In this way we can use Arduino for DC motor forward reverse direction control. The stop() function stops the motor from rotating. This is done by disabling the full H-bridge inside the L298D motor driver viz by sending low signal to the ENA pin.
In the main loop, we ask user to enter the direction and speed using the Arduino IDE serial monitor. First we ask user to enter the direction which can be either forward, reverse or stop. After user enters the direction command, we then ask the user to enter the duty cycle. The user can enter duty cycle value from 0 to 100. This duty cycle corresponds to speed of the motor. More duty cycle means more power delivered to the load(the DC motor) and therefore more speed.
The following video shows how one can do speed and direction control of dc motor pwm Arduino and L293D.
The following video shows animation of the DC motor speed and direction control using Arduino and L298N motor driver IC.