Raspberry Pi Pico · 28BYJ-48 Stepper

Raspberry Pi Pico 28BYJ-48 Stepper Simulator: Wiring, Code and a Live Circuit

This is a 28BYJ-48 stepper motor on its ULN2003 driver board, wired to a Raspberry Pi Pico and turning live in your browser: a quarter turn forward, a quarter turn back, with the shaft angle drawn as it goes.

Four control wires to 10, 11, 12, 13, and the motor’s power from VBUS (5 V from USB). It uses the stock Stepper library.

  • 3.3 V logic
  • Library: Stepper.h
  • IN1 to IN4 on 10, 11, 12, 13
  • 2048 steps a turn
Raspberry Pi Pico · 28BYJ-48 Stepperlive0.000 s 0.00x
Click to open it in the editor
The circuit itself, running on the simulator with the sketch below. Press what can be pressed; click anything else to open it in the editor.

Wiring the 28BYJ-48 Stepper to the Raspberry Pi Pico

Every connection in the circuit above, with the board’s own pin names.

28BYJ-48 Stepper pinRaspberry Pi Pico pinWhy
IN1GP10 (physical pin 14)Coil A, through the ULN2003’s first Darlington.
IN2GP11 (physical pin 15)Coil B.
IN3GP12 (physical pin 16)Coil C.
IN4GP13 (physical pin 17)Coil D.
VCC (+)VBUS (5 V from USB)The motor’s 5 V supply: a couple of hundred milliamps, more than USB likes to spare.
GND (-)GNDCommon ground.

The motor runs from VBUS (5 V from USB), while IN1 to IN4 come from 3.3 V pins. The ULN2003 switches happily from 3.3 V, so no level shifting is needed. On a real bench, a stepper on USB power can brown out the board when it starts; a separate 5 V supply with the grounds joined is safer.

Pins to leave alone on the Raspberry Pi Pico

The numbers in the code are GP numbers, not the physical pin numbers printed beside the header: GP15 is pin 20. GP23 to GP25 are used on the board itself, and GP25 is the LED.

On a real bench

Solder headers on the Pico and press it into the breadboard across the center channel; the 28BYJ-48 Stepper goes in beside it. GND pins sit every fifth pin down both sides (pins 3, 8, 13, 18 and so on), so there is always one close. The first upload needs BOOTSEL held while plugging in.

The code

The sketch the circuit above runs. Open it in the editor, change a line and press Run: it compiles in your browser.

28BYJ-48 stepper on Raspberry Pi Pico
#include <Stepper.h>

// The 28BYJ-48 through its ULN2003 board: 2048 full steps a turn.
const int STEPS_PER_TURN = 2048;

// Note the order: IN1, IN3, IN2, IN4. The Stepper library's sequence
// matches the motor's coils that way.
Stepper motor(STEPS_PER_TURN, 10, 12, 11, 13);

void setup() {
  Serial.begin(115200);
  motor.setSpeed(12);               // rpm; the 28BYJ-48 tops out near 15
  Serial.println("Stepper ready");
}

void loop() {
  Serial.println("Quarter turn forward");
  motor.step(STEPS_PER_TURN / 4);
  delay(300);
  Serial.println("Quarter turn back");
  motor.step(-STEPS_PER_TURN / 4);
  delay(300);
}

Stepper motor(2048, IN1, IN3, IN2, IN4) is the line everybody gets wrong. The library energizes its four pins in a fixed sequence, and for this motor the middle two have to be swapped, or it buzzes in place instead of turning.

setSpeed(12) sets the step rate for 12 revolutions a minute. step(512) blocks until a quarter turn is done, about 1.25 seconds at that speed, then step(-512) comes back. Nothing else in the sketch runs while it steps; AccelStepper.h is the library for moving without blocking.

Serial.begin(115200) opens the serial monitor. Serial is the USB port at 115200 baud in this sketch; on a real Pico it appears once the board has enumerated.

Common mistakes with the 28BYJ-48 Stepper on the Raspberry Pi Pico

The pin order in the constructor

Stepper(steps, IN1, IN2, IN3, IN4) makes the 28BYJ-48 vibrate without turning. The order has to be IN1, IN3, IN2, IN4, as in the sketch.

Asking for more than 15 rpm

The gearbox makes this motor slow. Above about 15 rpm it skips steps or stalls, and because nothing reports the shaft’s position, the sketch never knows. Keep setSpeed() low.

Assuming the motor knows where it is

A stepper has no sensor: the sketch counts the steps it sent. After a stall or a power cycle that count is wrong, which is why real machines home against a limit switch at start-up.

Questions and answers

Can I simulate a 28BYJ-48 stepper with a Raspberry Pi Pico?

Yes. The circuit at the top of this page is a Raspberry Pi Pico with a 28BYJ-48 stepper and ULN2003 driver, running in your browser on a simulated RP2040. The simulated motor follows the coil sequence on the four pins, so a wrong order makes it stall on the drawing too. Press Run it in the editor to change the wiring or the code; it is free and needs no account.

How many steps is one turn?

2048 in full-step mode and 4096 in half-step mode, because of the motor’s 64 to 1 gearbox. The Stepper library uses full steps.

Can I run two steppers at once?

Not with Stepper.h, whose step() blocks. AccelStepper.h moves several motors at once by calling run() for each in loop().

What about a NEMA 17?

A NEMA 17 needs a current-limiting driver such as the A4988, driven with STEP and DIR pins. The simulator has both, and the A4988 tutorial covers it.

Build your own 28BYJ-48 Stepper project

Open this circuit in the editor, change the wiring or the code, and keep your version in a free account.