If you’re planning to build a two-wheel drive robot, one of the first things you’ll need to figure out is how to control DC motors. They’re the simplest type of motor to use—just apply voltage, and they spin.
So, if DC motors just need voltage, why can’t we connect them directly to the Arduino? The problem is current. Motors usually draw much more current than an Arduino’s output pins are designed to handle. If you try to drive a motor directly from an Arduino pin, you’ll risk overloading it—and possibly damaging your microcontroller.
That’s where the L293D motor driver comes in. It acts as a bridge between your Arduino and the motor. You send small control signals from the Arduino, and the L293D safely handles the higher current required by the motor. Everyone’s happy—the motor gets the power it needs, and the Arduino stays safe.
In this tutorial, you’ll learn everything you need to know about using the L293D with an Arduino. We’ll show you how to control both the speed and direction of two DC motors using simple code and easy-to-follow wiring.
Whether you’re building a robot or just experimenting with motors, this guide will get you moving—literally. Let’s get started!
Understanding Motor Control Basics
Before learning about the L293D motor driver, it’s important to understand two key concepts:
- H-Bridge circuit – allows us to control the direction of the motor’s rotation
- PWM (Pulse Width Modulation) – helps control the speed of a DC motor
Controlling Direction with an H-Bridge
As mentioned earlier, DC motors are the easiest motors to use! If you connect a battery to a DC motor, it will spin in one direction. If you swap the wires, it spins in the other direction. But you can’t always physically swap the wires every time you want to change direction. That’s where an H-bridge comes in handy!
An H-bridge is a special circuit with four electronic switches arranged in an “H” shape, with the motor in the middle.
By turning these switches on and off in a specific order, you can make electricity flow through the motor in one direction or the opposite direction. This clever trick lets you control which way the motor spins without having to physically reverse any wires.
The animation below shows how an H-bridge works.

Controlling Speed with PWM (Pulse Width Modulation)
When a fixed voltage is given to a DC motor, it spins at a fixed speed. If you want to change the speed, you need to adjust the voltage. A higher voltage makes the motor spin faster, while a lower voltage makes it slower.
However, physically changing the voltage all the time isn’t very practical. That’s where PWM, or Pulse Width Modulation, comes in.
PWM is a smart way to control the average amount of power sent to the motor. Instead of sending a fixed voltage, PWM rapidly turns the voltage ON and OFF in very quick pulses.
The “width” of each ON pulse, also called the duty cycle, determines how long the voltage is “ON” during each cycle.
- If the voltage is ON for most of the time (a wider pulse), the motor receives a higher average voltage and spins faster.
- If the voltage is OFF for most of the time (a narrower pulse), the motor receives a lower average voltage and spins slower.
The image below shows how different duty cycles produce different average voltages, which in turn affect the motor speed.

L293D Motor Driver IC
The L293D is a highly popular and widely used integrated circuit (IC) primarily designed for driving inductive loads such as DC motors, stepper motors, relays, and solenoids. It works as a current amplifier, meaning it takes the low-current control signals from a microcontroller (like an Arduino) and boosts them to the higher current and voltage levels that motors need to operate.

At its core, the L293D has two separate H-bridge circuits. Remember how an H-bridge helps control the direction of a DC motor? Well, since the L293D has two of them, it can control two different DC motors at the same time. You can even combine these two H-bridges to control a bipolar stepper motor.
Power
The L293D is pretty flexible when it comes to power. It can work with a wide range of voltages, from 4.5V up to 36V, which means it’s compatible with many different types of motors.
In addition, the L293D is also capable of handling a decent amount of current. Each channel of the L293D can provide up to 600 milliamps (mA) of continuous current, and can handle short bursts of up to 1.2 amps (A) per channel. While these numbers might seem small, they are actually perfect for most small motors that hobbyists and students typically use in their projects.
Built-in Flyback Diodes
One of the most important safety features of the L293D is its built-in flyback diodes (also called freewheeling or kickback diodes). These are very important when working with inductive loads like motors.
When you suddenly turn off a motor, its magnetic field collapses. This can send a voltage spike back into the circuit. This backward voltage (called back EMF or Electro-Motive Force) can damage your microcontroller or other sensitive components.
The flyback diodes in the L293D give this dangerous backward current a safe path to flow, protecting both the IC and the rest of your circuit.
Thermal Protection
The L293D also includes built-in thermal protection. This means that if the chip gets too hot — maybe because a motor is drawing too much current or the chip isn’t cooled well — the L293D will automatically shut down its outputs temporarily to prevent damage. Once the chip cools down to a safe temperature, it automatically starts working again.
Technical Specifications
Here are the specifications:
Motor output voltage | 4.5V – 36V |
Logic input voltage | 5V |
Output Current per channel | 600mA |
Peak Output Current per Channel | 1.2A |
For more details, please refer below datasheet.
L293D Motor Driver IC Pinout
The L293D has 16 pins in total.

Let’s go over each group of pins to understand what they do and how they work.
Power Pins
The L293D requires two separate power sources:

VSS (VCC1) powers the internal logic circuitry of the IC. You’ll connect this pin to a 5V power supply.
VS (VCC2) supplies power to the motors. You can connect any voltage between 4.5V and 36V, depending on the motor you are using.
GND pins are the common ground connections. The IC has four ground pins, and all of them are internally connected. These pins serve two important purposes—They provide a common reference point for all voltages in the circuit and, equally important, they help with heat dissipation.
Motors are inductive loads and can draw significant currents, especially during start-up, changes in direction, or under heavy load. This high current flow through the internal H-bridge transistors generates heat. These multiple ground pins act as thermal pathways, allowing heat generated within the IC to be conducted away to the copper traces on the Printed Circuit Board (PCB) to which they are soldered. By connecting these pins to a large copper pour or ground plane on the PCB, the PCB itself acts as a heatsink, helping to prevent the IC from overheating and entering its thermal shutdown state.
Motor Output Pins
These are the pins where you actually connect your DC motors.

The OUT1 and OUT2 pins connect to your first motor (motor A), while the OUT3 and OUT4 pins connect to your second motor (motor B). You can connect any DC motor that runs on 5 to 36 volts to these pins.
Direction Control Pins
These pins control the spinning direction of the motors by turning the internal H-Bridge switches on and off:

The chip has two direction control pins for each motor. The IN1 and IN2 pins control the spinning direction of motor A, while the IN3 and IN4 pins control the spinning direction of motor B.
By setting different combinations of HIGH or LOW signals on these pins, you can make the motors spin forward, backward, or stop. The chart below shows exactly how this works:
IN1 | IN2 | Spinning 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
The ENA and ENB pins control how fast your motors spin.

Actually, these pins work as simple on/off switches. When you pull one of them HIGH, the corresponding motor is enabled and spins at full speed based on its direction inputs. When you pull it LOW, the motor is completely disabled and won’t spin at all.
But these pins can do more than just switch the motors on or off. By sending a PWM (Pulse Width Modulation) signal to ENA or ENB, you can actually control the speed of each motor.
With PWM, you’re rapidly enabling and disabling the motor many times per second. The key is the duty cycle, or how long the signal stays ON in each cycle. A longer ON time means the motor is active for more of the cycle, so it spins faster. A shorter ON time means it’s enabled for less time per cycle, so it spins more slowly.
Connecting Motors to Arduino Using the L293D
Now it’s time to connect the L293D motor driver to an Arduino and control some motors!
We’ll begin by connecting power to the motors. In this experiment, we’re using TT motors which are commonly used in two-wheel drive robots. These motors usually work well with voltages between 3V and 6V. Since we’ll be using an external 5V power supply for our motors, we need to connect that 5V to the VS (VCC2) pin of the L293D.
Next, we need to power the logic circuitry inside the L293D. For this, we’ll connect the VSS (VCC1) pin to the 5V output pin on the Arduino.
Also, it’s super important to make sure that everything shares a common ground; this means connecting a ground pin from your Arduino to a ground connection on your external motor power supply, and also connecting the GND pin on the L293D to the Arduino’s ground.
Once power connections are in place, we can connect the control pins. The L293D has two enable pins (ENA and ENB) and four input pins (IN1, IN2, IN3, and IN4). We’ll connect ENA to Arduino pin 9, IN1 to pin 8, IN2 to pin 7, IN3 to pin 5, IN4 to pin 4, and ENB to pin 3.
It’s worth noting that pins 9 and 3 on the Arduino are PWM-enabled, which means we can use them later to control the speed of the motors using PWM.
Finally, we’ll connect our motors. Take one motor and connect its two wires to the OUT1 and OUT2 pins on the L293D. Then, connect the second motor to the OUT3 and OUT4 pins. Don’t worry too much about which wire goes to which output pin on the motor; you can swap them around if the motor spins in the opposite direction from what you expect, as there’s no single “right” or “wrong” way to connect them.
Here’s a quick reference table for the pin connections:
L293D Motor Driver | Arduino | |
GND | GND | |
ENA | 9 | |
IN1 | 8 | |
IN2 | 7 | |
IN3 | 5 | |
IN4 | 4 | |
ENB | 3 |
The image below shows the complete wiring diagram for this setup.

Arduino Example Code
Here’s a simple Arduino sketch that shows how to control the direction and speed of two DC motors using the L293D motor driver and an Arduino. You don’t need any special libraries for this sketch; it uses only the basic built-in functions of the Arduino IDE.
This example is a great way to get hands-on experience with using the L293D to control both speed and direction of motors. Once you understand this, you can easily build more complex motor control systems, like those used in basic robots or remote-controlled cars.
// 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
digitalWrite(enA, HIGH);
digitalWrite(enB, HIGH);
// 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);
}
When you speed up or slow down a DC motor, you might hear a humming sound, especially at lower PWM values. Don’t worry—this is completely normal. It happens because DC motors need a certain minimum amount of voltage to start spinning, and at low PWM values, the voltage might not be high enough to keep the motor operating smoothly.
Code Explanation:
At the start of the sketch, we define which Arduino pins will be used to control Motor A and Motor B. For Motor A, we have a pin to enable it (allowing us to control its speed with PWM) and two pins for direction control. Similarly, for Motor B, we have an enable pin and two direction control pins.
// 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 the setup()
function, we configure all six motor control pins as outputs, because we are sending signals from the Arduino to the L293D. We also make sure that both motors are turned off by setting all the direction control pins to LOW. This ensures the motors don’t suddenly start spinning when the Arduino powers on.
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 the loop()
function, we call two custom functions with a delay of one second between them. The first function is directionControl()
, and the second is speedControl()
.
void loop() {
directionControl();
delay(1000);
speedControl();
delay(1000);
}
Let’s break down what each of these functions does.
The directionControl()
function demonstrates how to control the direction of both motors. First, we set both motors to their maximum possible speed by setting both enable pins to HIGH. Then, we send the necessary signals to the direction control pins to make both Motor A and Motor B spin forward. After they spin in that direction for two seconds, we change the signals to their direction pins, which causes both motors to reverse their spinning direction for another two seconds. Finally, we stop the motors by setting all direction control pins to LOW.
void directionControl() {
// Set motors to maximum speed
digitalWrite(enA, HIGH);
digitalWrite(enB, HIGH);
// 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);
}
The speedControl()
function demonstrates how to control the speed of the motors using PWM. We start by setting the direction control pins so that both motors spin in one direction. Then, we slowly increase the motor speed by gradually raising the PWM value from 0 to 255. This simulates an acceleration effect. Once the motors reach full speed, we reverse the process—slowly decreasing the PWM value from 255 back to 0, which causes the motors to gradually slow down and stop. Finally, we stop the motors by setting all direction control pins to LOW.
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);
}
Alternatives to the L293D
The L293D motor driver IC was first introduced way back in 1986. Even though it’s been around for a long time, the L293D is still widely used today. That’s because it’s simple to use, very reliable, and available at a low cost, which makes it a popular choice—especially in schools, hobby projects, and beginner electronics.
However, there are now more modern alternatives that offer improved performance for certain situations. For example, the L298N is a similar motor driver but can handle higher currents, which is useful if you’re powering bigger motors. The DRV8833 is based on MOSFET technology, which makes it more efficient and allows it to stay cooler. Another good option is the TB6612FNG, which offers better efficiency, works at lower voltages, and has a smaller footprint, making it ideal for compact or battery-powered projects.
That said, the L293D is still a great choice for learning, experimenting, or working with small robots and other low-power applications. However, if you’re curious about these other drivers, we already have tutorials on each of them. Feel free to explore and see which one fits your project best.