Kinetic work needs motion you can trust. A piece that moves beautifully for an hour and drifts out of alignment by the end of the day is a piece that needs a technician on call.
Stepper motors solve that. They move in discrete, counted steps — no drift, no accumulating error, and they hold position when stopped. They are why 3D printers land on the same coordinate ten thousand times.
Stepper vs servo vs DC — pick correctly
- DC motor — spins when powered. No position control. Fine for a fan or a continuously rotating element.
- Hobby servo — positions within a limited arc (usually ~180°), cheap, easy, but noisy, low-precision, and it hunts and buzzes when holding.
- Stepper — precise positioning, unlimited rotation, holds firmly and silently at rest, smooth slow motion.
For sculpture, the decider is usually slow, quiet, exact motion. Steppers win that outright. A servo asked to move very slowly jitters; a stepper glides.
What you need
- NEMA 17 stepper — the standard size, widely available, plenty of torque for most work
- A4988 driver module — a microstepping driver for bipolar steppers with a built-in translator
- Arduino (Uno, Nano, anything)
- Power supply: 8–35V, sized for your motor. A 12V 2A supply suits one NEMA 17.
- A 100µF electrolytic capacitor across the motor power input — not optional, see below
Wiring
The A4988’s appeal is that it needs only two control pins:
- DIR — rotation direction
- STEP — one pulse, one step
Plus:
- VMOT / GND — motor power (8–35V), with the 100µF capacitor across it
- VDD / GND — logic power from the Arduino’s 5V
- 1A, 1B, 2A, 2B — the two motor coils
- RESET and SLEEP — bridge these together, or the driver stays asleep and nothing happens
- MS1, MS2, MS3 — microstepping mode
- EN — enable, active low; tie to GND or leave floating
Two rules that destroy drivers, learned by everyone the hard way:
- Never disconnect the motor while powered. Back-EMF from an unplugged coil kills A4988s instantly.
- Fit the capacitor before first power-up. Voltage spikes on the motor supply are the other main cause of death.
Set the current limit — do not skip this
This is the step beginners skip and then wonder why their motor is too hot to touch.
The A4988 has a small trimpot that sets maximum coil current. Too high and the motor cooks; too low and it skips steps under load.
Method:
- Look up your motor’s rated current per phase (a typical NEMA 17 is ~1.5A).
- Target about 70% of that to start — so ~1.05A.
- With the motor connected and the board powered but not stepping, measure voltage at the Vref pin.
Vref = Current × 8 × Rsense. Most A4988 boards use Rsense = 0.1Ω, givingVref = Current × 0.8. For 1.05A, target 0.84V.- Adjust the trimpot to that voltage.
Then run it and feel the motor after ten minutes. Warm is fine. Too hot to hold is not — turn it down.
Microstepping
MS1/MS2/MS3 select full, 1/2, 1/4, 1/8 or 1/16 steps. A 200-step motor at 1/16 microstepping gives 3,200 positions per revolution.
For kinetic work, use 1/16 as the default. Microstepping costs a little torque and buys a lot of smoothness and near-silence — and for a gallery piece, audible stepping noise is a real problem. Full-stepping is loud and visibly notchy.
Code
Use the AccelStepper library, not the built-in Stepper. Acceleration ramps matter: a stepper commanded to jump instantly to speed will skip steps and lose position, which defeats the entire point.
#include <AccelStepper.h>
// DRIVER interface, STEP pin 3, DIR pin 2
AccelStepper stepper(AccelStepper::DRIVER, 3, 2);
void setup() {
stepper.setMaxSpeed(1000); // steps/sec
stepper.setAcceleration(500); // steps/sec^2 — ramps, no skipping
stepper.moveTo(3200); // one full rev at 1/16
}
void loop() {
if (stepper.distanceToGo() == 0) {
stepper.moveTo(-stepper.currentPosition()); // reverse, forever
}
stepper.run(); // must be called constantly — non-blocking
}
stepper.run() is non-blocking and must be called every loop, which means no delay() anywhere in your loop. Use millis() timing instead.
Failure modes in long-running pieces
Things that work on a bench and fail in a three-month exhibition:
- Thermal shutdown. The A4988 throttles when hot. Add a heatsink — most boards ship with one, unused, in the bag — and airflow.
- No homing. Power-cycle and the controller thinks it’s at zero wherever it stopped. Add a limit switch and home on startup, or your piece slowly walks itself into a wall.
- Lost steps under unexpected load. Something binds, steps are lost, and position is silently wrong with no feedback. Design mechanically so nothing can jam, and home periodically.
- Resonance. Steppers have speed bands where they vibrate badly and can stall. If it sounds awful at one speed, change the speed or add mechanical damping.
- Coupling slip. Set screws on shaft couplers loosen over thousands of cycles. Threadlock them.
For anything long-running or load-bearing, consider the DRV8825 instead — higher current, 1/32 microstepping, same wiring pattern and the same current-limit procedure with a different Rsense value.
Related Reading
- Control a NEMA 17 Stepper Motor with A4988 Driver and Arduino — Rachel De Barros (YouTube)
- In-Depth: Control Stepper Motor with A4988 Driver Module & Arduino — Last Minute Engineers
- A4988 stepper motor driver Arduino tutorial — Makerguides
- AccelStepper library documentation
- Exercise: A4988 Stepper Motor Driver — 16-223 Creative Kinetic Systems, CMU IDeATe
- Stepper motor — Kinetic Sculpture Club