Learn

Drive a DC motor with an Arduino

Intermediate

Or see every lesson.

  • 465parts on the bench
  • 43boards running now
  • 1.00xreal time, on every board
Arduino Uno: a DC motor on a transistorlive0.000 s 0.00x
Click to open it in the editor
Pin 9 drives a 2N2222 through 1 k, the transistor switches the motor and a 1N4007 sits across it. Press Run and watch the shaft follow the PWM ramp.

A small DC gear motor is the first thing most people want an Arduino to move, and the first thing they wire wrong: straight to a pin. A pin gives about 20 mA. A gear motor wants most of an amp to start. The circuit above does it the way that works on a desk: pin 9 drives a 2N2222 transistor through a 1 k resistor, the transistor switches the motor’s low side to ground, and a 1N4007 diode sits across the motor.

Press Run and the sketch ramps analogWrite on pin 9 from 0 to 255 and back, about four seconds each way, printing the duty as it goes. Watch the shaft. On the way up it stays still at "duty 100 / 255", only just starts at 150, turns at about 90 rpm at 200 and about 146 rpm at 250. On the way down it is still turning at about 112 rpm at "duty 100 / 255" and 74 rpm at 50. The same duty that would not start it keeps it going.

What you need

  • An Arduino Uno
  • A small DC gear motor (the yellow TT motor, or similar)
  • A 2N2222 or PN2222A NPN transistor
  • A 1 k resistor for the base
  • A 1N4007 diode across the motor
  • A breadboard and jumper wires

Wiring

Part and pinGoes toNote
Pin 9Transistor base, through 1 kA PWM pin, so analogWrite sets the speed
Transistor emitterGND
Transistor collectorMotor terminal 2The transistor switches the motor’s low side
Motor terminal 15VA separate motor supply on a real bench, its ground joined to the Uno’s
1N4007Across the motorBand (cathode) toward 5V

Why the motor cannot go straight on a pin

The motor here is the yellow gearbox kind: 6 ohms of winding, so stalled on 5 V it would take most of an amp. An ATmega328P pin is rated for 20 mA in normal use and 40 mA at the absolute limit. Wire the motor straight to a pin in Mokxi and it does not start, for the same reason it does not on a desk: the pin cannot push the current.

The transistor fixes that. About 4 mA of base current from the pin, through the 1 k resistor, lets the collector pass the motor’s current from 5 V to ground. At full speed the collector sits at about a quarter of a volt, so almost all of the 5 V is across the motor. On a real bench, power the motor from its own supply (a battery pack) and join its ground to the Uno’s, so the motor’s current never goes through the board.

Speed with analogWrite

Pin 9 is a PWM pin. analogWrite(9, duty) switches it on and off about 490 times a second, on for duty out of 255 of the time, and the motor’s own inertia averages that into a speed. 0 is off, 255 is full on. Any of the Uno’s PWM pins works: 3, 5, 6, 9, 10 and 11.

The sketch the circuit runs: ramp the speed up and down
const int DRIVE = 9;
const int STEP = 5;
const int STEP_MS = 40;

int duty = 0;
int direction = STEP;

void setup() {
  pinMode(DRIVE, OUTPUT);
  analogWrite(DRIVE, 0);
  Serial.begin(115200);
  Serial.println("Mokxi Uno: motor on a transistor, pin 9 PWM");
}

void loop() {
  analogWrite(DRIVE, duty);
  if (duty % 50 == 0) {
    Serial.print("duty ");
    Serial.print(duty);
    Serial.println(" / 255");
  }
  duty += direction;
  if (duty >= 255) {
    duty = 255;
    direction = -STEP;
  } else if (duty <= 0) {
    duty = 0;
    direction = STEP;
  }
  delay(STEP_MS);
}

Why a low duty does nothing

A gear motor has friction in its brushes, bearings and gears, and it takes more to unstick it than to keep it turning. Below that point the motor hums and stays put. That is why the ramp above passes 100 out of 255 with the shaft still, and why on the way down it keeps turning at 50: once moving, the motor needs less, and the shaft’s own momentum carries it a little further too.

Mokxi models both: a running friction, a breakaway at one and a half times it, and a lag of 120 ms for the gearbox and wheel. Every robot sketch has a minimum speed for this reason. Find yours by ramping up slowly and noting the duty where the shaft first moves, then never ask for less than that except 0. To start at a low speed, kick the motor at a higher duty for a moment and then drop to the speed you want.

The diode across the motor

A motor is a coil. When the transistor turns off, a real coil keeps its current flowing for an instant and the collector voltage jumps well above the supply, which is what kills transistors. The 1N4007 across the motor, band toward 5 V, gives that current a way around: it is reverse biased while the motor runs and only conducts on the kick.

Mokxi’s motor has no inductance, so here the circuit runs the same with the diode taken out. Leave it in anyway. The flyback diode page puts an inductor on a scope and shows the spike the diode stops.

Both directions: use an H bridge

One transistor turns the motor one way only. To reverse it, the current through the motor has to reverse, and that takes four switches in an H shape. A driver chip does it for you: the L293D for small motors, the L298N module for a robot car’s two wheels, or the TB6612FNG, which wastes less of the battery. Each has a running circuit and a tutorial on this site.

A logic-level MOSFET module such as the D4184 is the other one-direction choice: it switches far more current than a 2N2222, straight from a 3.3 V or 5 V pin.

Questions

Can I connect a DC motor directly to an Arduino pin?

No. A pin is rated for 20 mA and a small gear motor wants most of an amp to start, so it will not turn and the pin can be damaged. Switch the motor with a transistor, a MOSFET or a motor driver.

Which transistor should I use to drive a DC motor?

A 2N2222 or PN2222A with a 1 k base resistor runs a small gear motor from 5 V. For bigger motors use a TIP120 Darlington or a logic-level MOSFET, and for two directions an H bridge such as the L293D or L298N.

How do I control a DC motor’s speed with an Arduino?

Drive the transistor from a PWM pin and call analogWrite(pin, 0 to 255). On an Uno the PWM pins are 3, 5, 6, 9, 10 and 11.

Why does my motor hum but not turn at low speed?

Friction. Below a certain duty the motor cannot overcome its gearbox from rest. In the circuit here it is still at 100 out of 255 on the way up, yet keeps turning at 50 on the way down. Set a minimum speed in your sketch.

Do I need a diode across a DC motor?

Yes, on real hardware. It catches the voltage spike the motor’s coil makes when the transistor turns off. Mokxi’s motor has no inductance, so the simulation runs without it, but your transistor would not.

Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.