Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

28BYJ-48 stepper and ULN2003 with Arduino Nano — smooth half-steps

Drive a 28BYJ-48 stepper through a ULN2003 board from an Arduino Nano on D8–D11, with AccelStepper half-stepping and acceleration, one turn each way.

Arduino C++Verified — core avr 1.8.8, AccelStepper 1.64, 3 Nov 2026Compile-only

Community draft — report a mistake

The 28BYJ-48 with its ULN2003 board is the cheapest stepper motor around — ₹120 for both — and it’s geared, so it is slow but strong. It suits blinds, a rotating display or a dial pointer.

The ULN2003 takes four logic inputs from D8–D11. Instead of the basic Stepper library this guide uses AccelStepper in half-step mode, which runs smoother and quieter and ramps the speed up and down.

Wiring

Arduino NanoOnly the pins used are shown · 5 V logic28BYJ-48 stepper motor + ULN2003 driver5VGNDD11D10D9D8IN1IN2IN3IN4+-
Every connection
Arduino Nano28BYJ-48 stepper motor + ULN2003 driverWireNotes
D8IN1blue
D9IN2purple
D10IN3yellow
D11IN4orange
5V+redAbout 240 mA while stepping — OK from USB for one motor. Two motors: separate 5 V supply, common GND.
GND-black

5 V for the 5 V version of the motor (about 200–250 mA while stepping) part, 5 V board. The ULN2003 inputs accept 3.3 V or 5 V logic, so ESP32 and Pico drive IN1–IN4 directly. Power the motor from 5 V — not from a 3.3 V pin — and share GND with the board.

Board quirks

  • AccelStepper needs the coil order IN1, IN3, IN2, IN4 for this motor — that is why the constructor reads (8, 10, 9, 11). With 8, 9, 10, 11 the motor just buzzes.
  • The gearbox makes one output turn ≈ 4096 half-steps (the ratio is about 63.7:1, so it is a hair off). Above ~1000 half-steps/s the motor stalls.
  • The sketch switches the coils off between moves. Holding position would keep 240 mA flowing and make the motor hot.
  • The four LEDs on the ULN2003 board show the coil pattern — a quick way to check each wire.

Code

uln2003-nano.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// 28BYJ-48 stepper + ULN2003 board on an Arduino Nano with AccelStepper (half-step, smooth ramps).
// IN1 → D8, IN2 → D9, IN3 → D10, IN4 → D11, + → 5V, − → GND.
#include <AccelStepper.h>

const long STEPS_PER_REV = 4096;  // half-steps per output-shaft turn (gear ratio ~64:1)
// AccelStepper wants the coil order IN1, IN3, IN2, IN4 for this motor.
AccelStepper stepper(AccelStepper::HALF4WIRE, 8, 10, 9, 11);

void setup() {
  Serial.begin(115200);
  stepper.setMaxSpeed(800);      // half-steps/s; above ~1000 the 28BYJ-48 stalls
  stepper.setAcceleration(400);
  stepper.moveTo(STEPS_PER_REV);
  Serial.println(F("One turn clockwise..."));
}

void loop() {
  if (stepper.distanceToGo() == 0) {
    Serial.print(F("Reached "));
    Serial.println(stepper.currentPosition());
    stepper.disableOutputs();  // coils off between moves: the motor stays cool
    delay(1000);
    stepper.enableOutputs();
    stepper.moveTo(stepper.currentPosition() == 0 ? STEPS_PER_REV : 0);
  }
  stepper.run();
}

Library: Stepper (Arduino) — compiled with AccelStepper 1.64.

Expected serial output

Serial Monitor · 115200Output
One turn clockwise...
Reached 4096
Reached 0

Common errors

Motor vibrates but does not turn

Wrong pin order in the constructor, or running too fast. Use (8, 10, 9, 11) and lower setMaxSpeed.

Nano resets when the motor starts

The USB port can’t supply the motor current. Power the ULN2003 board from a separate 5 V supply, common GND.

↑↓ to move · Enter to open