There are lots of ways to control DC motors with an Arduino. But one of the easiest and most popular is with an L293D motor driver. The L293D motor driver is designed specifically to control DC motors, stepper motors, solenoids, and any other load with a high impedance. One of its main advantages is that it can control the speed and direction of two DC motors independently.

In this tutorial we will cover the following:

  • How the L293D motor driver works
  • How to connect an L293D and DC motor to the Arduino
  • How to control the direction of a single DC motor
  • How to control the speed of two DC motors

How the L293D Works

The L293D is a dual channel H-Bridge IC capable of controlling two DC motors. The L293D can control up to two DC motors rated from 4.5V to 36V.

The schematic diagram below shows a simplified version of the internal circuitry that controls one motor:

Two pairs of Darlington transistors (Q1/Q4, and Q2/Q3) are set up as an H-bridge. There’s a diode across the emitter and collector of each transistor, to prevent back EMF from the motor causing damage to the transistors.

When transistors Q1 and Q4 are both switched ON, and transistors Q2 and Q3 are OFF, current flows through the motor from Vcc to ground like this:

This causes the motor to spin either clockwise or counter-clockwise. The direction of spin depends on the polarity of the motor and how you connect it to the power supply.

When transistors Q2 and Q3 are ON, and Q1 and Q4 are OFF, the current through the motor is reversed. By reversing the current flow through the motor, the direction of its rotation will be reversed.

L293D Pin Diagram

Here’s a pin diagram of the L293D:

L293D Pin Diagram

The L293D has two separate H-bridges. One H-bridge is on the left, and the other is on the right:

L293D Pin Diagram - Two H-Bridges

H-bridge 1 can control one motor, and H-bridge 2 can control another motor.

Each pin has the following function:

  • Output 1: power for H-bridge 1 motor
  • Output 2: power for H-bridge 1 motor
  • Output 3: power for H-bridge 2 motor
  • Output 4: power for H-bridge 2 motor
  • Vcc 1: 5V supply for the L293D chip
  • Vcc 2: power supply for the motors (4.5V to 36V DC)
  • Enable 1, 2: turns ON/OFF H-bridge 1 (HIGH enables, LOW disables)
  • Enable 3, 4: turns ON/OFF H-bridge 2 (HIGH enables, LOW disables)
  • Input 1: motor control signal for H-bridge 1
  • Input 2: motor control signal for H-bridge 1
  • Input 3: motor control signal for H-bridge 2
  • Input 4: motor control signal for H-bridge 2

To turn the H-bridge 1 motor ON, send a HIGH signal to the input 1 pin, and LOW signal to the input 2 pin. This will cause the motor to spin in one direction. To make the motor spin in the opposite direction, send a LOW signal to the input 1 pin, and a HIGH signal to the input 2 pin. To turn the motor OFF, send a LOW signal to the input 2 pin.

Setting Up a DC Motor With the L293D

In this tutorial, we’re going to build a few example projects to demonstrate how to use the L293D to control DC motors on the Arduino. To build the example projects, you’ll need the following parts:

Connect the DC Motor and L293D to the Arduino

Let’s build an example project that will make a DC motor spin in one direction for two seconds, stop, then spin in the opposite direction for two seconds. To build this project, connect the DC motor, L293D, and Arduino like this:

You will probably need a separate power supply for the motor. Here, we’re using a 12V supply to power the motor, and a separate 5V supply to power the Arduino and L293D.

Arduino Code to Control a DC Motor

Once you’ve built the circuit above, upload this code to your Arduino:

int in1 = 10;
int in2 = 11;

void setup() {
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
}

void loop() {
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  delay(2000);
  digitalWrite(in1, LOW);
  delay(1000);

  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  delay(2000);
  digitalWrite(in2, LOW);
  delay(1000);
}

The first two lines of code assign the in1 variable to Arudino pin 10, and the in2 variable to pin 11. Then in the setup section, we set in1 and in2 as outputs with the pinMode() function.

In the loop section, digitalWrite(in1, HIGH) and digitalWrite(in2, LOW) turns in1 HIGH, and in2 LOW, which makes the motor spin in one direction. The delay(2000) function keeps the motor spinning for two seconds. Then, digitalWrite(in1, LOW) turns the motor OFF by setting in1 LOW. The delay(1000) function keeps the motor OFF for one second.

After the motor is OFF for one second, we reverse the direction of the motor by setting in1 LOW, and in2 HIGH with digitalWrite(in1, LOW) and digitalWrite(in2, HIGH). We use delay(2000) to keep the motor spinning in reverse for two seconds. Then we turn the motor OFF by setting in2 LOW with digitalWrite(in2, LOW).

Control the Direction of Two Motors

Now let’s add a second motor to the circuit. Follow the wiring diagram below to connect everything:

Arduino Code to Control the Direction of Two Motors

This sketch will make one of the motors spin forward and reverse for two seconds, then make the other motor spin forward and reverse for two seconds.

int in1 = 10;
int in2 = 11;
int in3 = 12;
int in4 = 13;
int ena = 9;
int enb = 6;

void setup() {
  pinMode(ena, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(ena, INPUT);
  pinMode(enb, INPUT);
}

void loop() {
  digitalWrite(ena, HIGH); 
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  delay(2000);
  digitalWrite(in1, LOW);   
  delay(1000);
  
  digitalWrite(in1, LOW);   
  digitalWrite(in2, HIGH);
  delay(2000);
  digitalWrite(in2, LOW); 
  delay(2000);
                         
  digitalWrite(enb, HIGH); 
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW); 
  delay(2000);
  digitalWrite(in3, LOW);  
  delay(1000);
  
  digitalWrite(in3, LOW);  
  digitalWrite(in4, HIGH);
  delay(2000);
  digitalWrite(in4, LOW); 
  delay(2000);
}

Control the Speed of Two Motors

Now let’s add the ability to control the speed of the two motors. You will need to add two 10K Ohm potentiometers to the previous circuit. Connect all of the components according to this wiring diagram:

Arduino Code to Control the Speed of Two Motors

After you’ve connected the circuit above, upload this code to the Arduino:

int in1 = 10;
int in2 = 11;
int in3 = 12;
int in4 = 13;
int speedControl1 = A2;
int speedControl2 = A1;
int ena = 9;
int enb = 6;
int setting1 = 0;      
int setting2 = 0;    

void setup() {
  pinMode(ena, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(ena, INPUT);
  pinMode(enb, INPUT);
}

void loop() {
  setting1 = analogRead(speedControl1);  
  analogWrite(ena, setting1);
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  delay(2000);
  digitalWrite(in1, LOW);   
  delay(1000);
  
  digitalWrite(in1, LOW);   
  digitalWrite(in2, HIGH);
  delay(2000);
  digitalWrite(in2, LOW); 
  delay(2000);
                        
  setting2 = analogRead(speedControl2);
  analogWrite(enb, setting2); 
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW); 
  delay(2000);
  digitalWrite(in3, LOW);  
  delay(1000);
  
  digitalWrite(in3, LOW);  
  digitalWrite(in4, HIGH);
  delay(2000);
  digitalWrite(in4, LOW); 
  delay(2000);
}

To use the potentiometers to control the speed of the DC motors, we take an analogRead() of the pins connected to the potentiometers – speedControl1 and speedControl2. The analogRead() value measured from those pins will be an integer between 0 and 1023, depending on the position of the potentiometer. This value is stored in the setting1 and setting2 variables.

The L293D will send power to the motors depending on the voltage applied to the enable pins. The higher the voltage applied to the enable pin, the more power will be supplied to the motor, and the faster it will spin. So we use analogWrite(ena, setting1) and analogWrite(enb, setting2) to send the voltage readings from the potentiometers to the DC motors. This will change the speed of the motors as the potentiometers are turned.