Bench NotesUno handbook

Driving a DC Motor with an L293D

Control speed and direction of a small DC motor through an H-bridge driver, never straight from a pin.

IntermediateDC motorL293D

Overview

A DC motor can draw hundreds of milliamps and generates voltage spikes when switched, so it must never connect to an Arduino pin. The L293D is an H-bridge chip: two direction inputs choose which way current flows through the motor, and a PWM signal on the enable pin sets the speed. The "D" version has built-in protection diodes.

You will need

  • Arduino Uno R3
  • L293D (DIP-16)
  • Small 3–6 V DC motor
  • Separate motor supply (e.g. 4×AA pack)
  • 0.1 µF capacitor across the motor terminals (optional)
  • Breadboard

Wiring

Uno pinConnects toNotes
5L293D pin 1 (EN1,2)PWM sets speed
7L293D pin 2 (1A)Direction input
8L293D pin 7 (2A)Direction input
5VL293D pin 16 (VCC1, logic)
GNDL293D pins 4, 5, 12, 13 and motor supply −Common ground
—L293D pin 8 (VCC2) ← motor supply +4.5–36 V; not the Uno's 5V for real motors
—Motor between pin 3 (1Y) and pin 6 (2Y)
Wiring for Driving a DC Motor with an L293DArduino Uno D5 (~PWM) to L293D 1 EN1,2; Arduino Uno D7 to L293D 2 (1A); Arduino Uno D8 to L293D 7 (2A); Arduino Uno 5V to L293D 16 VCC1 (logic); Arduino Uno GND to L293D 4/5/12/13 GND; Motor supply − to L293D 4/5/12/13 GND; Motor supply + to L293D 8 VCC2 (motor).Connections (each line is one wire)Arduino UnoMotor supplyL293DD5 (~PWM)1 EN1,2D72 (1A)D87 (2A)5V16 VCC1 (logic)GND4/5/12/13 GND−+8 VCC2 (motor)
Original wiring diagram. Each line is one jumper wire; boxes on a line are series resistors.

The sketch

l293d_motor.ino
const int ENABLE_PIN = 5;   // PWM: speed
const int IN1_PIN = 7;      // direction
const int IN2_PIN = 8;      // direction

void setMotor(int speed) {  // -255..255; negative = reverse
  if (speed > 0) {
    digitalWrite(IN1_PIN, HIGH);
    digitalWrite(IN2_PIN, LOW);
  } else if (speed < 0) {
    digitalWrite(IN1_PIN, LOW);
    digitalWrite(IN2_PIN, HIGH);
  } else {
    digitalWrite(IN1_PIN, LOW);
    digitalWrite(IN2_PIN, LOW);
  }
  analogWrite(ENABLE_PIN, constrain(abs(speed), 0, 255));
}

void setup() {
  pinMode(ENABLE_PIN, OUTPUT);
  pinMode(IN1_PIN, OUTPUT);
  pinMode(IN2_PIN, OUTPUT);
  setMotor(0);
}

void loop() {
  for (int speed = 0; speed <= 255; speed += 5) {   // speed up forwards
    setMotor(speed);
    delay(40);
  }
  setMotor(0);
  delay(1000);
  for (int speed = 0; speed >= -255; speed -= 5) {  // speed up in reverse
    setMotor(speed);
    delay(40);
  }
  setMotor(0);
  delay(1000);
}

How the code works

Both inputs LOW lets the motor coast; both HIGH brakes it. The L293D is rated 600 mA per channel and drops roughly 1.5–3 V internally, so a 6 V supply may give the motor only about 4 V. For bigger motors use a MOSFET-based driver such as the TB6612FNG or DRV8833. Low PWM values may not overcome the motor's friction, so it starts turning only partway up the ramp.

What you should observe

  • The motor speeds up in one direction, stops, speeds up in the other, stops.
  • Motor never turns but the chip gets warm: check VCC2 has power and that all grounds are joined.