Interface L298N DC Motor Driver Module with Arduino

If you are planning on assembling your new robot friend, you will eventually want to learn about controlling DC motors. One of the easiest and inexpensive way to control DC motors is to interface L298N Motor Driver with Arduino. It can control both speed and spinning direction of two DC motors.

And as a bonus, it can even control a bipolar stepper motor like NEMA 17.

Tutorial for Controlling NEMA 17 Stepper Motor With L298N & Arduino
Control Stepper Motor with L298N Motor Driver & Arduino
One of the easiest and inexpensive way to control stepper motors is to interface L298N Motor Driver with Arduino. It can control both speed and...

Controlling a DC Motor

In order to have a complete control over DC motor, we have to control its speed and rotation direction. This can be achieved by combining these two techniques.

  • PWM – For controlling speed
  • H-Bridge – For controlling rotation direction

PWM – For controlling speed

The speed of a DC motor can be controlled by varying its input voltage. A common technique for doing this is to use PWM (Pulse Width Modulation)

PWM is a technique where average value of the input voltage is adjusted by sending a series of ON-OFF pulses.

The average voltage is proportional to the width of the pulses known as Duty Cycle.

The higher the duty cycle, the greater the average voltage being applied to the dc motor(High Speed) and the lower the duty cycle, the less the average voltage being applied to the dc motor(Low Speed).

Below image illustrates PWM technique with various duty cycles andaverage voltages.

Pulse Width Modulation PWM Technique with Duty Cycles
Pulse Width Modulation(PWM) Technique

H-Bridge – For controlling rotation direction

The DC motor’s spinning direction can be controlled by changing polarity of its input voltage. A common technique for doing this is to use an H-Bridge.

An H-Bridge circuit contains four switches with the motor at the center forming an H-like arrangement.

Closing two particular switches at the same time reverses the polarity of the voltage applied to the motor. This causes change in spinning direction of the motor.

Below animation illustrates H-Bridge circuit working.

H-Bridge Working Motor Direction Control Animation
Working of H-Bridge

L298N Motor Driver IC

L298N Motor Driver Module - IC

At the heart of the module is the big, black chip with chunky heat sink is an L298N.

The L298N is a dual-channel H-Bridge motor driver capable of driving a pair of DC motors. That means it can individually drive up to two motors making it ideal for building two-wheel robot platforms.

Power Supply

L298N Motor Driver Module - 5V Jumper, Power Supply Pins & Regulator

The L298N motor driver module is powered through 3-pin 3.5mm-pitch screw terminals. It consists of pins for motor power supply(Vs), ground and 5V logic power supply(Vss).

The L298N motor driver IC actually has two input power pins viz. ‘Vss’ and ‘Vs’.

From Vs pin the H-Bridge gets its power for driving the motors which can be 5 to 35V. Vss is used for driving the logic circuitry which can be 5 to 7V. And they both sink to a common ground named ‘GND’.

The module has an on-board 78M05 5V regulator from STMicroelectronics. It can be enabled or disabled through a jumper.

When this jumper is in place, the 5V regulator is enabled, supplying logic power supply(Vss) from the motor power supply(Vs). In this case, 5V input terminal acts as an output pin and delivers 5V 0.5A. You can use it to power up the Arduino or other circuitry that requires 5V power supply.

When the jumper is removed, the 5V regulator gets disabled and we have to supply 5 Volts separately through 5 Volt input terminal.

Warning:

You can put the jumper in place, if the motor power supply is below 12V. If it is greater than 12V, you should remove the jumper to avoid the onboard 5V regulator from getting damaged.

Also DO NOT supply power to both the motor power supply input and 5V power supply input when jumper is in place.

Voltage Drop of L298N

L298N Motor Driver Module Internal Voltage Drop

The voltage drop of the L298N motor driver is about 2V. This is due to the internal voltage drop in the switching transistors in the H-Bridge circuit.

So, if we connect 12V to the motor power supply terminal, the motors will receive voltage around 10V. This means that a 12V DC motor will never spin at its maximum speed.

To get maximum speed out of motor, the motor power supply should be bit higher voltage(2V) than motor’s actual voltage requirement.

Considering the voltage drop of 2V, if you are using 5V motors you’ll need to provide 7V at motor power supply terminal. If you have 12V motors then your motor supply voltage should be 14V.

Output Pins

L298N Motor Driver Module - Motor Connection Pinout

The L298N motor driver’s output channels for the motor A and B are broken out to the edge of the module with two 3.5mm-pitch screw terminals.

You can connect two DC motors having voltages between 5 to 35V to these terminals.

Each channel on the module can deliver up to 2A to the DC motor. However, the amount of current supplied to the motor depends on system’s power supply.

Control Pins

For each of the L298N’s channels, there are two types of control pins which allow us to control speed and spinning direction of the DC motors at the same time viz. Direction control pins & Speed control pins.

Direction Control Pins

L298N Motor Driver Module - Spinning Direction Control Pins

Using the direction control pins, we can control whether the motor spins forward or backward. These pins actually control the switches of the H-Bridge circuit inside L298N IC.

The module has two direction control pins for each channel. The IN1 and IN2 pins control the spinning direction of the motor A while IN3 and IN4 control motor B.

The spinning direction of a motor can be controlled by applying either a logic HIGH(5 Volts) or logic LOW(Ground) to these inputs. The below chart illustrates how this is done.

Input1Input2Spinning Direction
Low(0)Low(0)Motor OFF
High(1)Low(0)Forward
Low(0)High(1)Backward
High(1)High(1)Motor OFF

Speed Control Pins

L298N Motor Driver Module - Speed Control Pins

The speed control pins viz. ENA and ENB are used to turn the motors ON, OFF and control its speed.

Pulling these pins HIGH will make the motors spin, pulling it LOW will make them stop. But, with Pulse Width Modulation (PWM), we can actually control the speed of the motors.

The module usually comes with a jumper on these pins. When this jumper is in place, the motor is enabled and spins at maximum speed. If you want to control the speed of motors programmatically, you need to remove the jumpers and connect them to PWM-enabled pins on Arduino.

L298N Motor Driver Module Pinout

Before diving into hookup and example code, let’s first take a look at its Pinout.

L298N Motor Driver Module Pinout

VCC pin supplies power for the motor. It can be anywhere between 5 to 35V. Remember, if the 5V-EN jumper is in place, you need to supply 2 extra volts than motor’s actual voltage requirement, in order to get maximum speed out of your motor.

GND is a common ground pin.

5V pin supplies power for the switching logic circuitry inside L298N IC. If the 5V-EN jumper is in place, this pin acts as an output and can be used to power up your Arduino. If the 5V-EN jumper is removed, you need to connect it to the 5V pin on Arduino.

ENA pins are used to control speed of Motor A. Pulling this pin HIGH(Keeping the jumper in place) will make the Motor A spin, pulling it LOW will make the motor stop. Removing the jumper and connecting this pin to PWM input will let us control the speed of Motor A.

IN1 & IN2 pins are used to control spinning direction of Motor A. When one of them is HIGH and other is LOW, the Motor A will spin. If both the inputs are either HIGH or LOW the Motor A will stop.

IN3 & IN4 pins are used to control spinning direction of Motor B. When one of them is HIGH and other is LOW, the Motor B will spin. If both the inputs are either HIGH or LOW the Motor B will stop.

ENB pins are used to control speed of Motor B. Pulling this pin HIGH(Keeping the jumper in place) will make the Motor B spin, pulling it LOW will make the motor stop. Removing the jumper and connecting this pin to PWM input will let us control the speed of Motor B.

OUT1 & OUT2 pins are connected to Motor A.

OUT3 & OUT4 pins are connected to Motor B.

Wiring L298N motor driver module with Arduino UNO

Now that we know everything about the module, we can begin hooking it up to our Arduino!

Start by connecting power supply to the motors. In our experiment we are using DC Gearbox Motors(also known as ‘TT’ motors) that are usually found in two-wheel-drive robots. They are rated for 3 to 12V. So, we will connect external 12V power supply to the VCC terminal. Considering internal voltage drop of L298N IC, the motors will receive 10V and will spin at slightly lower RPM. But, that’s OK.

Next, we need to supply 5 Volts for the L298N’s logic circuitry. We will make use of the on-board 5V regulator and derive the 5 volts from the motor power supply so, keep the 5V-EN jumper in place.

Now, the input and enable pins(ENA, IN1, IN2, IN3, IN4 and ENB) of the L298N module are connected to six Arduino digital output pins(9, 8, 7, 5, 4 and 3). Note that the Arduino output pins 9 and 3 are both PWM-enabled.

Finally, connect one motor to terminal A(OUT1 & OUT2) and the other motor to terminal B(OUT3 & OUT4). You can interchange your motor’s connections, technically, there is no right or wrong way.

When you’re done you should have something that looks similar to the illustration shown below.

Wiring L298N Motor Driver Module with DC TT motors and Arduino UNO
Wiring DC motors to L298N motor driver & Arduino

Arduino Code – Controlling a DC Motor

The following sketch will give you complete understanding on how to control speed and spinning direction of a DC motor with L298N motor driver and can serve as the basis for more practical experiments and projects.

// Motor A connections
int enA = 9;
int in1 = 8;
int in2 = 7;
// Motor B connections
int enB = 3;
int in3 = 5;
int in4 = 4;

void setup() {
	// Set all the motor control pins to outputs
	pinMode(enA, OUTPUT);
	pinMode(enB, OUTPUT);
	pinMode(in1, OUTPUT);
	pinMode(in2, OUTPUT);
	pinMode(in3, OUTPUT);
	pinMode(in4, OUTPUT);
	
	// Turn off motors - Initial state
	digitalWrite(in1, LOW);
	digitalWrite(in2, LOW);
	digitalWrite(in3, LOW);
	digitalWrite(in4, LOW);
}

void loop() {
	directionControl();
	delay(1000);
	speedControl();
	delay(1000);
}

// This function lets you control spinning direction of motors
void directionControl() {
	// Set motors to maximum speed
	// For PWM maximum possible values are 0 to 255
	analogWrite(enA, 255);
	analogWrite(enB, 255);

	// Turn on motor A & B
	digitalWrite(in1, HIGH);
	digitalWrite(in2, LOW);
	digitalWrite(in3, HIGH);
	digitalWrite(in4, LOW);
	delay(2000);
	
	// Now change motor directions
	digitalWrite(in1, LOW);
	digitalWrite(in2, HIGH);
	digitalWrite(in3, LOW);
	digitalWrite(in4, HIGH);
	delay(2000);
	
	// Turn off motors
	digitalWrite(in1, LOW);
	digitalWrite(in2, LOW);
	digitalWrite(in3, LOW);
	digitalWrite(in4, LOW);
}

// This function lets you control speed of the motors
void speedControl() {
	// Turn on motors
	digitalWrite(in1, LOW);
	digitalWrite(in2, HIGH);
	digitalWrite(in3, LOW);
	digitalWrite(in4, HIGH);
	
	// Accelerate from zero to maximum speed
	for (int i = 0; i < 256; i++) {
		analogWrite(enA, i);
		analogWrite(enB, i);
		delay(20);
	}
	
	// Decelerate from maximum speed to zero
	for (int i = 255; i >= 0; --i) {
		analogWrite(enA, i);
		analogWrite(enB, i);
		delay(20);
	}
	
	// Now turn off motors
	digitalWrite(in1, LOW);
	digitalWrite(in2, LOW);
	digitalWrite(in3, LOW);
	digitalWrite(in4, LOW);
}

Code Explanation:

The arduino code is pretty straightforward. It doesn’t require any libraries to get it working. The sketch starts with declaring Arduino pins to which L298N’s control pins are connected.

// Motor A connections
int enA = 9;
int in1 = 8;
int in2 = 7;
// Motor B connections
int enB = 3;
int in3 = 5;
int in4 = 4;

In setup section of code, all the motor control pins are declared as digital OUTPUT and pulled LOW to turn both the motors OFF.

void setup() {
	// Set all the motor control pins to outputs
	pinMode(enA, OUTPUT);
	pinMode(enB, OUTPUT);
	pinMode(in1, OUTPUT);
	pinMode(in2, OUTPUT);
	pinMode(in3, OUTPUT);
	pinMode(in4, OUTPUT);
	
	// Turn off motors - Initial state
	digitalWrite(in1, LOW);
	digitalWrite(in2, LOW);
	digitalWrite(in3, LOW);
	digitalWrite(in4, LOW);
}

In loop section of the code we call two user defined functions at an interval of a second.

void loop() {
	directionControl();
	delay(1000);
	speedControl();
	delay(1000);
}

These functions are:

  • directionControl() – This function spins both motors forward at maximum speed for two seconds. It then reverses the motor’s spinning direction and spins for another two seconds. Finally it turns the motors off.

    void directionControl() {
    	// Set motors to maximum speed
    	// For PWM maximum possible values are 0 to 255
    	analogWrite(enA, 255);
    	analogWrite(enB, 255);
    
    	// Turn on motor A & B
    	digitalWrite(in1, HIGH);
    	digitalWrite(in2, LOW);
    	digitalWrite(in3, HIGH);
    	digitalWrite(in4, LOW);
    	delay(2000);
    	
    	// Now change motor directions
    	digitalWrite(in1, LOW);
    	digitalWrite(in2, HIGH);
    	digitalWrite(in3, LOW);
    	digitalWrite(in4, HIGH);
    	delay(2000);
    	
    	// Turn off motors
    	digitalWrite(in1, LOW);
    	digitalWrite(in2, LOW);
    	digitalWrite(in3, LOW);
    	digitalWrite(in4, LOW);
    }
  • speedControl() – This function accelerates both the motors from zero to maximum speed by producing PWM signals using analogWrite() function, then it decelerates them back to zero. Finally it turns the motors off.

    void speedControl() {
    	// Turn on motors
    	digitalWrite(in1, LOW);
    	digitalWrite(in2, HIGH);
    	digitalWrite(in3, LOW);
    	digitalWrite(in4, HIGH);
    	
    	// Accelerate from zero to maximum speed
    	for (int i = 0; i < 256; i++) {
    		analogWrite(enA, i);
    		analogWrite(enB, i);
    		delay(20);
    	}
    	
    	// Decelerate from maximum speed to zero
    	for (int i = 255; i >= 0; --i) {
    		analogWrite(enA, i);
    		analogWrite(enB, i);
    		delay(20);
    	}
    	
    	// Now turn off motors
    	digitalWrite(in1, LOW);
    	digitalWrite(in2, LOW);
    	digitalWrite(in3, LOW);
    	digitalWrite(in4, LOW);
    }