Stepper Motors

Driving stepper motors from an ESP32 for precise cockpit gauge needles, VOR indicators, and motorised controls.

Stepper Motors vs Servos

A stepper motor moves in discrete steps rather than a continuous sweep. Each pulse to the driver advances the motor by one step, so position is tracked by counting steps — no position feedback sensor is needed for open-loop control.

FeatureStepper motorServo
Position accuracyPrecise (open-loop)Good (closed-loop internally)
Holding torqueExcellent (energised)Good
SpeedModerateFast
Wiring complexity4–6 wires + driver board3 wires
Power consumptionAlways drawing current when holdingOnly when moving under load
28BYJ-48 + ULN2003A Driver

The 28BYJ-48 is the most common starter stepper motor. It runs on 5 V, has an internal gear reduction of ~64:1, and comes bundled with a ULN2003A driver board that accepts 3.3 V logic directly from the ESP32.

SpecificationValue
Supply voltage5 V DC
Phase resistance~200 Ω
Steps per revolution (half-step)4 096 (64 elec. steps × ~64 gear ratio)
No-load speed~15 RPM at 5 V
Stall torque~300–350 g·cm
ULN2003A GPIO 23 IN1 GPIO 22 IN2 GPIO 21 IN3 GPIO 19 IN4 5 V / GND VCC/GND OUT1 OUT2 OUT3 OUT4 28BYJ-48 5 V (COM)
// 28BYJ-48 with ULN2003 — Library Manager → "AccelStepper" by Mike McCauley
#include <AccelStepper.h>

// HALF4WIRE (8-step) mode: IN1=23, IN3=21, IN2=22, IN4=19
// Note: AccelStepper expects (pin1, pin2, pin3, pin4) = (IN1, IN3, IN2, IN4)
AccelStepper stepper(AccelStepper::HALF4WIRE, 23, 21, 22, 19);

// 28BYJ-48: 64 electrical steps × gear ratio ≈ 64 = 4096 steps/rev (half-step)
const int STEPS_PER_REV = 4096;

void setup() {
    stepper.setMaxSpeed(1000);       // steps/second
    stepper.setAcceleration(500);    // steps/second²
}

void loop() {
    stepper.moveTo(STEPS_PER_REV);   // one full clockwise revolution
    while (stepper.distanceToGo() != 0) {
        stepper.run();
    }
    delay(500);
    stepper.moveTo(0);               // return to home position
    while (stepper.distanceToGo() != 0) {
        stepper.run();
    }
    delay(500);
}
NEMA 17 + A4988 Driver

NEMA 17 is the industry-standard bipolar stepper motor for 3D printers and CNC machines. It delivers significantly more torque than the 28BYJ-48 and supports up to 1/16 microstepping for smooth motion. The A4988 driver requires a separate high-voltage motor supply (8–35 V) and a 3.3 V logic supply.

A4988 GPIO 23 STEP GPIO 22 DIR GPIO 21 EN (active LOW) 3.3 V VDD (+ RST, SLP) 8–35 V VMOT (+ 100 µF cap) 1A / 1B 2A / 2B NEMA 17 Coil A Coil B
A4988 PinConnect toNotes
STEPGPIO 23One pulse = one step
DIRGPIO 22HIGH / LOW sets rotation direction
ENGPIO 21Active LOW — drive LOW to enable, HIGH to coast
RST, SLP3.3 V (VDD)Tie together and pull HIGH to keep driver active
VDD3.3 VLogic supply from ESP32
VMOT8–35 V external supplyPlace 100 µF cap across VMOT / GND
MS1, MS2, MS3GND (full step) or see table000=full, 100=half, 010=¼, 110=⅛, 111=1/16
1A, 1B / 2A, 2BMotor coil A / Motor coil B4-wire bipolar motor
// NEMA 17 with A4988 driver — STEP / DIR interface
#include <AccelStepper.h>

const int STEP_PIN = 23;
const int DIR_PIN  = 22;
const int EN_PIN   = 21;  // active LOW — pull LOW to enable

AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);

// NEMA 17 standard: 200 full steps/rev (1.8° per step)
// With 1/16 microstepping on A4988: 3200 steps/rev
const int STEPS_PER_REV = 200;

void setup() {
    pinMode(EN_PIN, OUTPUT);
    digitalWrite(EN_PIN, LOW);       // enable the driver

    stepper.setMaxSpeed(800);
    stepper.setAcceleration(400);
}

void loop() {
    stepper.moveTo(STEPS_PER_REV);
    while (stepper.distanceToGo() != 0) { stepper.run(); }
    delay(500);
    stepper.moveTo(0);
    while (stepper.distanceToGo() != 0) { stepper.run(); }
    delay(500);
}
Cockpit Applications
ApplicationMotor choiceNotes
Compass / heading indicator28BYJ-48High gear ratio gives fine resolution for slow rotation
Altimeter drum counter28BYJ-48Drives rotating digit drums via shaft coupler
VOR / ILS needle28BYJ-48 / NEMA 17Map deviation value (−2.5 to +2.5 dots) to steps
Throttle / mixture leverNEMA 17Requires feedback force; consider holding-torque spec
Motorised trim wheelNEMA 17Continuously tracks simulator trim dataref