Skip to content
Arduino contents

Lesson 1.9: Stepper motor with a remote

This lesson brings two parts together: the infrared receiver from lesson 1.7 and a stepper motor. Press a key on the remote and the motor makes exactly one turn one way or the other.

Parts

How it works

A stepper motor has several coils around the rotor. Energising them in order moves the rotor one step at a time, so counting steps is measuring the angle, with no sensor at all.

The 28BYJ-48 makes 32 steps per turn of its internal shaft and has a gearbox of roughly 64:1, so the output shaft needs about 2048 steps per turn. The trade-off is speed: about 15 turns per minute at most.

Each coil draws more than a pin can supply, which is why the ULN2003 sits between the Arduino and the motor. And the motor gets its own supply: running it from the Arduino's 5V can cause resets.

Specifications

Steps per turn
2048, with the gearbox
Gear ratio
≈ 64:1
Supply
5 V
Top speed
≈ 15 rpm

Wiring

ComponentConnects toNote
ULN2003, IN1Pin 8
ULN2003, IN2Pin 9
ULN2003, IN3Pin 10
ULN2003, IN4Pin 11
ULN2003, +Power module 5V rail
ULN2003, −Power module GND rail
MotorULN2003 white connector
IR receiver, SPin 12
IR receiver, + and −Arduino 5V and GND
Arduino GNDPower module GND railEssential: without a common GND the signals have no reference

Code

// One turn each way depending on the remote key.
#include <Stepper.h>
#include <IRremote.hpp>

const int STEPS_PER_REV = 2048; // one turn of the output shaft
const int IR_PIN = 12;

// Replace these with the codes you read in the receiver lesson.
const uint16_t KEY_CLOCKWISE = 0x46;
const uint16_t KEY_COUNTERCLOCKWISE = 0x15;

// IN1, IN3, IN2, IN4 order: the one the 28BYJ-48 needs.
Stepper stepper(STEPS_PER_REV, 8, 10, 9, 11);

void setup() {
  stepper.setSpeed(10); // turns per minute
  IrReceiver.begin(IR_PIN);
}

void release() {
  // Cut the coil current so they don't heat up at rest.
  for (int pin = 8; pin <= 11; pin++) digitalWrite(pin, LOW);
}

void loop() {
  if (!IrReceiver.decode()) return;

  uint16_t command = IrReceiver.decodedIRData.command;
  bool repeat = IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT;
  IrReceiver.resume();

  if (repeat) return;

  if (command == KEY_CLOCKWISE) stepper.step(STEPS_PER_REV);
  if (command == KEY_COUNTERCLOCKWISE) stepper.step(-STEPS_PER_REV);

  release();
}

What the code does

  • Stepper stepper(2048, 8, 10, 9, 11); takes the pins in the order IN1, IN3, IN2, IN4. In natural order the motor vibrates without turning.
  • setSpeed(10) is turns per minute of the output shaft. Above 15 the motor starts skipping steps.
  • step() blocks the program until the turn is done: while it spins, the remote is ignored.
  • release() switches the coils off at the end. Without it, the motor keeps drawing current and heating up even when it's still.

Step by step

  1. Seat the power module on the breadboard, its − on the blue line and its + on the red one, and select 5 V with the jumpers.
  2. Connect the motor to the ULN2003, and the ULN2003 to the Arduino and the module following the table.
  3. Join the Arduino's GND to the module's GND rail.
  4. Replace the two key codes in the sketch with your remote's.
  5. Plug the adapter into the module, upload the code and press the keys.

Result

One key makes a full turn one way and the other key the opposite way. While it turns, the driver's LEDs light up in sequence.

If it doesn't work

  • If the motor vibrates but doesn't turn, the pin order in the code isn't IN1, IN3, IN2, IN4.
  • If the driver's LEDs light but the motor doesn't move, check the white connector and the on/off jumper on the driver board.
  • If it doesn't react to the keys, check their codes with the sketch from lesson 1.7.
  • If the board resets as it turns, the motor is drawing from the Arduino's 5V: power it from the module.