Stepper motors

Move a 5 V 28BYJ-48 with a ULN2003 driver, starting slowly and accounting for missed steps and backlash.

Stepper motor with driver

Ingredients

Follow a part’s name for an introduction and compatibility notes.

A stepper moves through a sequence of electromagnetic positions. The inexpensive geared 28BYJ-48 is useful for a small dial, camera turntable, or indicator that moves slowly. It is not a fast CNC motor, and the open-loop controller does not know whether the shaft actually followed every command.

Connect the motor driver

ULN2003 board to Uno R3
ConnectionDestination or purpose
IN1, IN2, IN3, IN4D8, D9, D10, D11 respectively.
Driver positive supplyExternal regulated 5 V for the 5 V motor variant.
Driver negative supplyExternal negative and Uno GND.
Motor connectorMatching 5-wire socket on the driver.

Keep the external positive supply separate from the Uno’s USB-fed 5 V rail. The ULN2003 handles coil current; the Uno only supplies logic signals. Do not connect the motor directly to GPIO.

Make a small movement

Install the Arduino Stepper library. Mark the shaft position with a lightweight paper pointer and upload:

Download the complete Arduino sketch

#include <Stepper.h>
const int nominalStepsPerRevolution = 2048;
const byte in1 = 8, in2 = 9, in3 = 10, in4 = 11;
Stepper motor(nominalStepsPerRevolution, in1, in3, in2, in4);

void releaseCoils() {
  digitalWrite(in1, LOW); digitalWrite(in2, LOW);
  digitalWrite(in3, LOW); digitalWrite(in4, LOW);
}

void setup() {
  Serial.begin(9600);
  motor.setSpeed(5);
  releaseCoils();
  Serial.println("Send f or r for 256 steps");
}

void loop() {
  if (Serial.available() > 0) {
    const char command = Serial.read();
    if (command == 'f' || command == 'r') {
      motor.step(command == 'f' ? 256 : -256);
      releaseCoils();
      Serial.println("Move finished; coils released");
    }
  }
}

At 9600 baud, send f or r. The motor should make a slow movement in one direction or the other. The constructor intentionally uses the pin sequence IN1, IN3, IN2, IN4 for this common motor/driver combination. Physical wiring still follows the table.

What the numbers mean

The speed is in output-shaft revolutions per minute based on the supplied steps-per-revolution value. Start at 5 RPM. Asking this geared motor for hundreds of RPM produces missed steps or buzzing, not a faster useful mechanism.

2048 is a convenient nominal full-step count. Actual gear ratios vary, and some libraries use half steps instead. Measure one revolution on your actual assembly before treating the number as a calibration constant.

The sketch releases coils after each move to reduce heating and power use. That also removes electromagnetic holding torque. If your mechanism needs holding torque, account for continuous current and temperature instead of simply deleting the release call.

Troubleshooting

  • Buzzing without rotation: lower speed, remove load, verify the motor voltage, and recheck phase order.
  • Returns to a slightly different point: gearbox backlash and missed steps can both contribute.
  • Gets hot while stopped: check whether the coils remain energized.
  • Other inputs feel unresponsive: step() blocks until the requested move finishes. For concurrent sensing, use a nonblocking motion approach with acceleration support.

Build a dial that moves among a few labeled states, then add a home switch before trusting absolute position after restart. See the Stepper library and ULN2003A documentation for the software and driver roles.