The A4988 is the small red or green stepper driver used in 3D printers and CNC kits. It drives a NEMA 17 from a 12 V supply and needs only two signals: STEP and DIR.
On the ESP32 DevKit V1 power the driver’s logic (VDD) from 3V3, so STEP and DIR connect straight to GPIO26 and GPIO27. The motor supply goes to VMOT with a 100 µF capacitor at the driver. Set the current limit before the first run. The sketch uses AccelStepper’s acceleration ramps to turn the motor two revolutions forward and back.
Wiring
| ESP32 DevKit V1 | A4988 stepper motor driver | Wire | Notes |
|---|---|---|---|
| — | 1A | — | To Motor coil 1 (often black) (not drawn) |
| — | 1B | — | To Motor coil 1 (often green) (not drawn) |
| — | 2A | — | To Motor coil 2 (often red) (not drawn) |
| — | 2B | — | To Motor coil 2 (often blue) (not drawn) |
| 12 V 2 A adapter (100 µF capacitor at VMOT) · +12V | VMOT | red | Fit a 100 µF / 25 V electrolytic across VMOT–GND right at the driver. Without it, the supply spike when you plug in can kill the A4988. |
| 12 V 2 A adapter (100 µF capacitor at VMOT) · GND | GND | black | |
| 3V3 | VDD | orange | Logic supply. At 3.3 V the A4988’s logic matches the ESP32 — no level shifting. |
| GND | GND | black | The A4988 has two GND pins on the same net: one for the motor supply, one for the ESP32. |
| — | RST → SLP | orange | Short jumper between the two pins. RST floats on the board; SLP is pulled up there, so the bridge holds both HIGH. |
| D26 | STEP | yellow | |
| D27 | DIR | green | |
| D25 | EN | purple | Optional: LOW = driver on. The sketch switches the coils off between moves. |
Motor 8–35 V on VMOT; logic 3–5.5 V on VDD part, 3.3 V board. Logic levels follow VDD. Power VDD from 3.3 V on ESP32 and Pico and from 5 V on Uno, and STEP/DIR/EN connect directly. The motor supply on VMOT is separate.
Board quirks
- Set the current limit before the first run. Turn the trimpot until Vref (pot to GND) is about
I × 8 × Rsense— with the usual 0.1 Ω sense resistors (R100), 0.8 V for 1 A. Too high cooks the driver; too low and the motor misses steps. - Never connect or disconnect the motor while VMOT is powered. The coil’s voltage spike destroys the A4988 instantly.
- MS1–MS3 are left open: they are pulled LOW on the board, giving full steps (200 per turn). Tie all three to 3V3 for 1/16 steps (3200 per turn) and smoother, quieter motion.
- Find the coil pairs with a multimeter: a pair shows a few ohms between its two wires. Each pair goes to 1A/1B or 2A/2B; swapping one pair only reverses direction.
- AccelStepper’s
run()must be called constantly. Adelay()anywhere inloop()while the motor moves stalls it. For Wi-Fi projects, run the stepper in its own FreeRTOS task. - STEP, DIR and EN avoid the strapping pins (D2, D5, D12, D15) so the motor doesn’t jerk when the ESP32 boots.
Code
// NEMA 17 stepper + A4988 driver on an ESP32 DevKit V1 with AccelStepper.
// STEP → D26, DIR → D27, EN → D25 (LOW = driver on), VDD → 3V3, RST → 3V3 (or bridge RST–SLP).
// VMOT from a 12 V supply with 100 µF across VMOT–GND. MS1–MS3 open = full step (200 steps/rev).
#include <AccelStepper.h>
constexpr uint8_t STEP_PIN = 26, DIR_PIN = 27, EN_PIN = 25;
constexpr long STEPS_PER_REV = 200; // 1.8° motor, full step
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
void setup() {
Serial.begin(115200);
stepper.setEnablePin(EN_PIN);
stepper.setPinsInverted(false, false, true); // EN is active-LOW on the A4988
stepper.enableOutputs();
stepper.setMaxSpeed(800); // steps/s
stepper.setAcceleration(400); // steps/s² — ramps stop a 12 V motor stalling at start
stepper.moveTo(2 * STEPS_PER_REV);
Serial.println("A4988: 2 turns forward, 2 back, then rest");
}
void loop() {
stepper.run(); // must be called as often as possible — no delay() while moving
if (stepper.distanceToGo() == 0) {
Serial.printf("At position %ld steps\n", stepper.currentPosition());
stepper.disableOutputs(); // coils off while resting: motor and driver stay cool
delay(1500);
stepper.enableOutputs();
stepper.moveTo(stepper.currentPosition() == 0 ? 2 * STEPS_PER_REV : 0);
}
}// NEMA 17 stepper + A4988 driver on an ESP32 DevKit V1 with AccelStepper.
// STEP → D26, DIR → D27, EN → D25 (LOW = driver on), VDD → 3V3, RST → 3V3 (or bridge RST–SLP).
// VMOT from a 12 V supply with 100 µF across VMOT–GND. MS1–MS3 open = full step (200 steps/rev).
#include <AccelStepper.h>
constexpr uint8_t STEP_PIN = 26, DIR_PIN = 27, EN_PIN = 25;
constexpr long STEPS_PER_REV = 200; // 1.8° motor, full step
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
void setup() {
Serial.begin(115200);
stepper.setEnablePin(EN_PIN);
stepper.setPinsInverted(false, false, true); // EN is active-LOW on the A4988
stepper.enableOutputs();
stepper.setMaxSpeed(800); // steps/s
stepper.setAcceleration(400); // steps/s² — ramps stop a 12 V motor stalling at start
stepper.moveTo(2 * STEPS_PER_REV);
Serial.println("A4988: 2 turns forward, 2 back, then rest");
}
void loop() {
stepper.run(); // must be called as often as possible — no delay() while moving
if (stepper.distanceToGo() == 0) {
Serial.printf("At position %ld steps\n", stepper.currentPosition());
stepper.disableOutputs(); // coils off while resting: motor and driver stay cool
delay(1500);
stepper.enableOutputs();
stepper.moveTo(stepper.currentPosition() == 0 ? 2 * STEPS_PER_REV : 0);
}
}Library: AccelStepper (Mike McCauley) — compiled with AccelStepper 1.64.
Expected serial output
A4988: 2 turns forward, 2 back, then rest
At position 400 steps
At position 0 steps
At position 400 stepsA4988: 2 turns forward, 2 back, then rest At position 400 steps At position 0 steps At position 400 steps
Common errors
Motor doesn’t move at all, no holding torque
RST not held HIGH (floating), EN high, or no VMOT. Check the RST–SLP jumper, 3V3 on VDD, and 12 V at VMOT.
Motor vibrates back and forth instead of turning
Coil pairs mixed up — one wire from each coil on the same pair of pins. Re-pair the wires with a multimeter.
Driver gets very hot, motor misses steps
Current limit too high. Lower Vref, add the stick-on heatsink, and switch the coils off between moves (the sketch does this with EN).