Built-in project · Arduino Uno R3

Motor both ways on an Arduino Uno

An L293D H bridge turns a DC motor forward and back from three Uno pins, and shows what braking does that coasting does not. The whole build, an Arduino Uno and 2 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

IntermediateRuns in your browser. Free, and no account needed.

Step by step, with the wiring and the common mistakes: Arduino L293D Motor Driver: Forward and Reverse

Motor both ways · Arduino Uno R3live0.000 s 0.00x
Click to open it in the editor
The circuit itself, running here on the simulator. Press what can be pressed; click anything else to open it in the editor.

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Uno R3
// H bridge: a motor that goes both ways, on an L293D.
//
//   pin 9  EN12, the PWM that sets the speed
//   pin 7  IN1
//   pin 8  IN2
//   L293D  VSS (pin 16) to 5 V, VS (pin 8) to 5 V, any GND pin to GND
//          OUT1 and OUT2 to the motor's two terminals
//
// The transistor in the `motor` example can switch a motor on and off. It
// cannot make it turn the other way, because a transistor only knows how to
// pull one end down. Turning a motor round means being able to put either end
// at the supply and the other at ground, and four switches in an H around the
// motor is the only way to do that. That is what this chip has: four half
// bridges, two of them per motor.
//
//   IN1  IN2   what happens
//    1    0    OUT1 high, OUT2 low: forward
//    0    1    the other way around: reverse
//    0    0    both ends at ground: brake
//    1    1    both ends at 5 V   -- brake
//
// and EN12 low lifts both ends off the motor entirely, which is coasting. The
// difference between braking and coasting is worth watching on the canvas: a
// braked motor stops in a fraction of a second because its own back EMF is
// shorted through the chip, and a coasting one winds down for seconds.
//
// # Where the volts go
//
// The output stages are Darlingtons, and a Darlington keeps about 1.2 V for
// itself. There is one in the high side and another in the low side, so a
// motor across a 5 V supply here sees about 2.6 V and turns at about half the
// speed you were expecting. That is not the model being coy: it is the number
// on the datasheet, and it is why the grown-up answer for anything that
// matters is a MOSFET bridge.
//
// The D on the end of the name is the eight clamp diodes inside, which is why
// this circuit needs none of the flyback diodes the transistor one does.
//
// # The PWM on the enable, and why half throttle is not half speed
//
// Chopping EN with analogWrite is how this chip is usually throttled, and it
// does not brake between pulses; the outputs go high impedance, so the motor
// coasts. With nothing on the shaft there is nothing to slow it down while it
// coasts, so an unloaded motor winds up to the same top speed at any duty,
// just more slowly. Put a load on it and the duty is the throttle it looks
// like. Mokxi's motor has no mechanical load, which is why the last leg of
// this loop reaches the same rpm as the first.

const int ENABLE = 9;
const int IN1 = 7;
const int IN2 = 8;

const int SPEED = 255;
const unsigned long RUN_MS = 2500;
const unsigned long STOP_MS = 800;

void drive(const char *what, int a, int b, int duty) {
  digitalWrite(IN1, a);
  digitalWrite(IN2, b);
  analogWrite(ENABLE, duty);
  Serial.print("motor: ");
  Serial.println(what);
}

void setup() {
  pinMode(ENABLE, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  analogWrite(ENABLE, 0);
  Serial.begin(115200);
  Serial.println("Mokxi Uno: L293D H bridge on pins 7, 8 and 9");
}

void loop() {
  drive("forward", HIGH, LOW, SPEED);
  delay(RUN_MS);

  // Both inputs the same shorts the motor through the chip. Watch it stop.
  drive("brake", LOW, LOW, SPEED);
  delay(STOP_MS);

  drive("reverse", LOW, HIGH, SPEED);
  delay(RUN_MS);

  // Enable low lets go of both terminals. Watch it wind down instead.
  drive("coast", LOW, HIGH, 0);
  delay(STOP_MS * 2);

  // And once round at half throttle, to show the PWM working through it.
  drive("forward, half throttle", HIGH, LOW, SPEED / 2);
  delay(RUN_MS);
  drive("brake", HIGH, HIGH, SPEED);
  delay(STOP_MS);
}

Parts list

4 parts, plus the jumper wires. Every one is in the editor's parts bin.

How it is wired

7 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.

  • Arduino Uno R3 pin 9; Motor driver, L293D pin EN12
  • Arduino Uno R3 pin 8; Motor driver, L293D pin IN2
  • Arduino Uno R3 pin 7; Motor driver, L293D pin IN1
  • Arduino Uno R3 pin 5V; Motor driver, L293D pin VS; Motor driver, L293D pin VSS
  • Ground: Arduino Uno R3 pin GND; Motor driver, L293D pin GND1
  • Motor driver, L293D pin OUT1; DC motor pin 1
  • Motor driver, L293D pin OUT2; DC motor pin 2

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.