L293D Motor Driver IC
The L293D is a quadruple half-H driver IC that can drive two DC motors bidirectionally or one stepper motor. Each channel is rated for 600 mA continuous (1.2 A peak) and includes built-in flyback diodes (the D in L293D). The IC operates from 4.5–36 V on the motor supply and uses a separate 5V logic supply. Two enable pins (1, 9) allow PWM speed control, and the four input pins per channel select direction. The L293D is pin-compatible with the higher-current L293 (no diodes, 1A) and the SN754410 (1A with diodes).
For this interfacing you need the following components:
- Arduino board (Uno, Nano, Mega, etc.)
- L293D motor driver IC (DIP-16)
- Two small DC motors (3–9V, 100–500 mA each)
- External power supply (battery pack matching motor voltage)
- 100 µF electrolytic capacitor (across motor supply)
- Breadboard and jumper wires
- USB cable to connect Arduino to your computer
Pinouts
Schematic
+Motor VCC (4.5–36V) +5V (Arduino)
| |
+| |
| |
+-+---------------------+--+
| 16 (VSS) 8 (VCC) | |
| | |
| 1 (EN1) -------- Pin 9 | |
| 2 (IN1) -------- Pin 8 | |
| 7 (IN2) -------- Pin 7 | |
| 9 (EN2) -------- Pin 6 | |
| 10 (IN3) -------- Pin 5 | |
| 15 (IN4) -------- Pin 4 | |
| | |
| 3 (OUT1) ----- Motor A+ |
| 6 (OUT2) ----- Motor A- |
| 11 (OUT3) ----- Motor B+ |
| 14 (OUT4) ----- Motor B- |
| | |
| 4,5,12,13 (GND) -------+--+--- Arduino GND
| |
+-----------------------------+
Pins 4, 5, 12, and 13 are all GND — connect them together and to the Arduino’s GND and the battery’s negative terminal.
Pin Map
| IC Pin | Name | Arduino Connection |
|---|---|---|
| 1 | EN1 (Enable A) | Pin 9 (PWM) |
| 2 | IN1 | Pin 8 |
| 7 | IN2 | Pin 7 |
| 9 | EN2 (Enable B) | Pin 6 (PWM) |
| 10 | IN3 | Pin 5 |
| 15 | IN4 | Pin 4 |
| 3 | OUT1 | Motor A terminal + |
| 6 | OUT2 | Motor A terminal - |
| 11 | OUT3 | Motor B terminal + |
| 14 | OUT4 | Motor B terminal - |
| 8 | VCC | 5V (Arduino 5V) |
| 16 | VSS | Motor supply (4.5–36V) |
| 4, 5, 12, 13 | GND | GND |
Motor control truth table (per channel)
| EN | IN1 | IN2 | Motor A |
|---|---|---|---|
| 0 | X | X | Coast (free-run) |
| 1 | 0 | 0 | Brake (active low) |
| 1 | 0 | 1 | Reverse |
| 1 | 1 | 0 | Forward |
| 1 | 1 | 1 | Brake (active high) |
Install necessary Library
No library is required. Motor control uses digitalWrite() for direction and analogWrite() for PWM speed.
Code with complete explanation
This sketch demonstrates bidirectional PWM speed control for two DC motors with serial commands.
// Motor A
#define EN1 9 // PWM — speed
#define IN1 8
#define IN2 7
// Motor B
#define EN2 6 // PWM — speed
#define IN3 5
#define IN4 4
void setup()
{
Serial.begin(9600);
pinMode(EN1, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(EN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
// Start: all motors off
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
analogWrite(EN1, 0);
analogWrite(EN2, 0);
Serial.println("L293D Dual Motor Control");
Serial.println("Commands: F=forward, R=reverse, B=brake, C=coast");
Serial.println("Speed: 0–9 (0=stop, 9=max)");
}
void loop()
{
if (Serial.available())
{
char cmd = Serial.read();
if (cmd >= '0' && cmd <= '9')
{
int speed = map(cmd - '0', 0, 9, 0, 255);
analogWrite(EN1, speed);
analogWrite(EN2, speed);
Serial.print("Speed set to: ");
Serial.println(speed);
}
else
{
switch (cmd)
{
case 'F':
case 'f':
setMotor(IN1, IN2, HIGH, LOW);
setMotor(IN3, IN4, HIGH, LOW);
Serial.println("Forward");
break;
case 'R':
case 'r':
setMotor(IN1, IN2, LOW, HIGH);
setMotor(IN3, IN4, LOW, HIGH);
Serial.println("Reverse");
break;
case 'B':
case 'b':
setMotor(IN1, IN2, HIGH, HIGH);
setMotor(IN3, IN4, HIGH, HIGH);
Serial.println("Brake");
break;
case 'C':
case 'c':
setMotor(IN1, IN2, LOW, LOW);
setMotor(IN3, IN4, LOW, LOW);
Serial.println("Coast");
break;
}
}
}
}
void setMotor(int in1, int in2, int val1, int val2)
{
digitalWrite(in1, val1);
digitalWrite(in2, val2);
}
Differential drive (robot steering)
void setMotors(int leftSpeed, int rightSpeed)
{
// Clamp and configure motor A (left)
if (leftSpeed >= 0)
{
setMotor(IN1, IN2, HIGH, LOW);
analogWrite(EN1, constrain(leftSpeed, 0, 255));
}
else
{
setMotor(IN1, IN2, LOW, HIGH);
analogWrite(EN1, constrain(-leftSpeed, 0, 255));
}
// Motor B (right)
if (rightSpeed >= 0)
{
setMotor(IN3, IN4, HIGH, LOW);
analogWrite(EN2, constrain(rightSpeed, 0, 255));
}
else
{
setMotor(IN3, IN4, LOW, HIGH);
analogWrite(EN2, constrain(-rightSpeed, 0, 255));
}
}
Code breakdown
EN1(Pin 9) andEN2(Pin 6) are PWM-capable pins that control motor speed. Setting the enable to 0 disables the motor (coast).IN1/IN2control direction:(HIGH, LOW)= forward,(LOW, HIGH)= reverse,(HIGH, HIGH)or(LOW, LOW)= brake/coast.- The truth table shows two braking modes: both inputs HIGH (active-high brake) and both inputs LOW (active-low brake or coast). Active-high brake shorts the motor terminals through the lower transistors, providing stronger braking. Coast disconnects the motor entirely (it spins freely).
- PWM should be applied to the enable pins (EN1, EN2), not the input pins. Applying PWM to the input pins while the enable is HIGH also works but produces less predictable results.
- The
setMotor()helper function sets both input pins on a channel simultaneously. constrain(value, 0, 255)— limits the speed value to the valid PWM range.
Independent motor control
void loop()
{
// Motor A forward, 75% speed
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(EN1, 191);
// Motor B reverse, 50% speed
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
analogWrite(EN2, 128);
}
Driving a bipolar stepper motor
The L293D can drive a bipolar stepper motor (e.g., NEMA 17) using both channels as a full-bridge:
void stepSequence()
{
int steps[4][4] = {
{1, 0, 0, 1}, // Phase 1
{0, 1, 0, 1}, // Phase 2
{0, 1, 1, 0}, // Phase 3
{1, 0, 1, 0} // Phase 4
};
for (int i = 0; i < 4; i++)
{
digitalWrite(IN1, steps[i][0]);
digitalWrite(IN2, steps[i][1]);
digitalWrite(IN3, steps[i][2]);
digitalWrite(IN4, steps[i][3]);
delay(5); // Step delay — controls speed
}
}
Steps to perform this interfacing
- Place the L293D IC in the centre of the breadboard straddling the gap.
- Wire the IC as shown in the schematic. Connect all four GND pins (4, 5, 12, 13) together.
- Connect the enable pins to PWM-capable Arduino pins (9, 6).
- Connect two small DC motors to OUT1/OUT2 and OUT3/OUT4.
- Power the motor supply (VSS) from a battery — do not draw motor current through the Arduino’s 5V rail.
- Power the logic supply (VCC) from the Arduino’s 5V pin.
- Connect a common GND between the battery, the L293D, and the Arduino.
- Copy the code into the Arduino IDE.
- Select the correct board and port (
Tools > BoardandTools > Port). - Upload the sketch to the Arduino.
- Open the Serial Monitor (
Tools > Serial Monitor, set baud rate to 9600). - Type F → motors run forward. Type R → reverse. Type B → brake. Type C → coast.
- Type 0–9 to set speed (0 = stop, 9 = max).
Caution
- Built-in flyback diodes: The L293D includes clamping diodes on each output (the D suffix distinguishes it from the L293 which lacks them). For most hobby motors these internal diodes are sufficient. However, for large inductive loads (> 1A), add external Schottky diodes (1N5819) from each output to VSS to handle the recirculation current without overheating the IC.
- 600 mA per channel limit: The L293D is rated for 600 mA continuous per channel (1.2 A peak). Exceeding this causes thermal shutdown — the IC gets very hot (can reach 100°C+) and the outputs disable until it cools. If your motors draw > 500 mA, use an L298N (2A), SN754410 (1A), or discrete MOSFET H-bridge instead.
- Heat dissipation: At 600 mA per channel with a 12V motor supply, the L293D dissipates approximately 1–2W as heat (saturation voltage ≈ 1.4V per transistor pair). In a DIP-16 package without a heatsink, this leads to temperatures of 60–80°C. This is within the absolute maximum rating (150°C junction) but very hot to touch. If the IC is uncomfortably hot, reduce the motor current, add a heatsink (glued to the top), or switch to a more efficient driver.
- Enable pin PWM: Always apply PWM to the enable pins (1 and 9). PWM on the input pins (IN1–IN4) with the enable held HIGH can cause shoot-through in some configurations and generates more heat. The enable pins switch the H-bridge’s low-side transistors directly — this is the intended PWM control method.
- Motor supply voltage: VSS (pin 16) can be 4.5V to 36V, but the L293D’s saturation voltage drop (≈ 1.4V per transistor × 2 = 2.8V total) reduces the voltage actually delivered to the motor. A 5V motor powered from 5V VSS only receives ≈ 2.2V — it will run slowly and with low torque. Provide at least 2–3V of headroom above the motor’s rated voltage to compensate for the drop (e.g., 9V supply for a 6V motor).
- Common ground: The motor supply GND and the Arduino GND must be connected. Without a common ground, the input logic levels from the Arduino will not be referenced correctly, and the motor current path is incomplete. Connect all four L293D GND pins (4, 5, 12, 13) to each other and to both the battery negative and Arduino GND.
- Capacitor on motor supply: Place a 100–470 µF electrolytic capacitor as close as possible to the L293D’s VSS and GND pins. The motors draw large current spikes when starting and reversing; without the capacitor, these spikes cause voltage dips that can reset the Arduino or corrupt sensor readings.
- L293D vs L293 vs SN754410: The L293D has built-in diodes (600 mA). The L293 has no diodes (1A, requires external diodes). The SN754410 is a drop-in replacement with diodes (1A). If your project draws > 600 mA per motor, prefer the SN754410.