Skip to content
Arduino contents

Lesson 1.13: DC motor

The DC motor is the most common actuator: fans, wheels, pumps. Driving one from the Arduino takes two things a pin doesn't have: current, and the ability to reverse polarity.

Parts

How it works

A small motor draws hundreds of milliamps, and quite a lot more when starting. A pin supplies about 20 mA, so connecting it directly would damage the board. On top of that, when the current is cut the motor sends back voltage spikes that have to be absorbed.

An H-bridge is four switches arranged in an H around the motor: closing two diagonally sends current through it one way; closing the other two, the other way. The L293D has two H-bridges and the protection diodes built in.

Inputs 1A and 2A choose the direction: HIGH and LOW turns one way, LOW and HIGH the other, and with both equal the motor brakes. Speed is set with PWM on EN1: analogWrite() between 0 and 255.

The L293D keeps a little over a volt in its transistors, so the motor gets less than the supply provides. For a 3–6 V motor on a 5 V supply that's enough.

Wiring

ComponentConnects toNote
L293D, EN1 (1)Pin 5PWM pin
L293D, 1A (2)Pin 7
L293D, 1Y (3)Motor, terminal 1
L293D, GND (4, 5, 12, 13)GND
L293D, 2Y (6)Motor, terminal 2
L293D, 2A (7)Pin 8
L293D, VCC2 (8)Power module 5V railMotor supply
L293D, VCC1 (16)Power module 5V railLogic supply
Arduino GNDPower module GND railCommon GND

Code

// Speeds up one way, stops and reverses.
const int ENABLE_PIN = 5; // EN1, with PWM
const int IN1_PIN = 7;    // 1A
const int IN2_PIN = 8;    // 2A

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

void spin(bool forward, int speed) {
  digitalWrite(IN1_PIN, forward ? HIGH : LOW);
  digitalWrite(IN2_PIN, forward ? LOW : HIGH);
  analogWrite(ENABLE_PIN, speed); // 0 to 255
}

void stopMotor() {
  analogWrite(ENABLE_PIN, 0);
}

void loop() {
  // Speed ramp, forwards.
  for (int speed = 80; speed <= 255; speed += 5) {
    spin(true, speed);
    delay(50);
  }
  delay(2000);

  stopMotor();
  delay(1000); // let it stop before reversing

  spin(false, 180);
  delay(3000);

  stopMotor();
  delay(1000);
}

What the code does

  • spin() sets the direction with 1A and 2A and the speed with the PWM on EN1.
  • The ramp starts at 80, not 0: below a certain value the motor doesn't have the force to start and just hums.
  • stopMotor() sets EN1 to 0: the motor is left free and coasts to a stop.
  • The pause before reversing avoids changing direction at full speed, which makes the current spike.

Step by step

  1. Seat the power module with its − on the blue line and its + on the red one, and select 5 V.
  2. Place the L293D across the centre channel. The notch marks the side of pins 1 and 16.
  3. Wire it following the table and join the Arduino's GND to the module's.
  4. Plug the adapter into the module and upload the code.

Result

The motor speeds up for a few seconds, runs at full speed, stops and turns the other way at medium speed.

If it doesn't work

  • If the motor hums but doesn't turn, the speed is too low or the supply can't provide enough current.
  • If it always turns the same way, check the 1A and 2A wires.
  • If the Arduino resets when the motor starts, the motor is drawing from the board: VCC2 must go to the power module.
  • If nothing happens, check that the module's jumpers aren't on OFF and that its LED is lit.