Stepper Motors
1. How a Stepper Works
A stepper has multiple coil groups (phases) around the stator and a toothed/magnetized rotor. Energizing phases in a fixed sequence pulls the rotor from tooth to tooth, one discrete step at a time.
- Common resolution: 200 steps/revolution = 1.8 degrees per step (also 0.9 deg = 400 steps).
- No feedback needed: count the steps you send and you know the position (as long as you never lose one).
- Very high holding torque at standstill; the rotor is magnetically latched.
| Type | Description | Notes |
|---|---|---|
| Permanent Magnet | Magnetized rotor, coarse steps. | Cheap, low res. |
| Variable Reluctance | Soft-iron toothed rotor, no magnet. | Legacy. |
| Hybrid | PM + reluctance; fine steps, high torque. | The common NEMA type. |
2. Coil Configuration: Bipolar vs. Unipolar
| Type | Wires | Drive | Torque |
|---|---|---|---|
| Bipolar | 4 | Needs an H-bridge per phase (current reverses). | Higher |
| Unipolar | 5-6 | Center-tapped; simpler switching, no reversal. | Lower |
Most modern NEMA-17/23 steppers are 4-wire bipolar driven by a dedicated chip (A4988, DRV8825, TMC2209) that handles the H-bridges and current regulation for you.
3. Step Modes and Microstepping
How the driver energizes the coils sets the smoothness and resolution:
| Mode | Coil pattern | Effect |
|---|---|---|
| Full step (wave) | One phase on at a time. | Lowest torque. |
| Full step (2-phase) | Two phases on. | Full rated torque. |
| Half step | Alternate 1 and 2 phases. | 2x resolution, smoother. |
| Microstepping | Sine/cosine current levels per phase. | Up to 256x resolution, very smooth. |
Microstepping drives each coil with a graded current (approximating sine/cosine) so the rotor settles between full steps. It improves smoothness and reduces resonance/noise, but the incremental holding torque per microstep is small, so effective positioning accuracy does not scale 1:1 with microstep count.
4. How Drivers Are Controlled: Step / Direction
The dominant interface is STEP + DIR: the microcontroller does not switch coils directly; it just pulses a wire.
MCU ---> STEP pin: each rising edge = advance one (micro)step
MCU ---> DIR pin : HIGH = clockwise, LOW = counter-clockwise
MCU ---> EN pin : enable/disable the driver outputs
MS1/MS2/MS3 pins : set microstep resolution (full ... 1/16, 1/32...)
Speed = STEP pulse frequency. Distance = number of STEP pulses. A key setting is the driver’s current limit (via a Vref potentiometer or register), which must match the motor’s rated coil current to avoid overheating or lost torque.
STEP: _|-|_|-|_|-|_|-|_|-|_ (5 pulses = 5 microsteps)
DIR: --------------------- (held HIGH = one direction)
5. Programming a Stepper
5.1. Arduino, raw STEP/DIR (A4988 / DRV8825)
#define STEP_PIN 3
#define DIR_PIN 4
void setup() {
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
digitalWrite(DIR_PIN, HIGH); // pick a direction
}
void loop() {
// 200 pulses = one full revolution at full step
for (int i = 0; i < 200; i++) {
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(800); // shorter delay = faster
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(800);
}
delay(1000);
}5.2. Arduino with AccelStepper (accel/decel profiles)
Manual pulsing gives no acceleration; AccelStepper ramps speed so the motor does not stall or lose steps.
#include <AccelStepper.h>
AccelStepper stepper(AccelStepper::DRIVER, 3, 4); // STEP=3, DIR=4
void setup() {
stepper.setMaxSpeed(1000); // steps/sec
stepper.setAcceleration(500); // steps/sec^2
stepper.moveTo(2000); // target position (absolute)
}
void loop() {
if (stepper.distanceToGo() == 0)
stepper.moveTo(-stepper.currentPosition()); // reverse
stepper.run(); // call often; steps as needed
}5.3. Raspberry Pi (Python, RPi.GPIO)
import RPi.GPIO as GPIO
from time import sleep
STEP, DIR = 20, 21
GPIO.setmode(GPIO.BCM)
GPIO.setup([STEP, DIR], GPIO.OUT)
def move(steps, clockwise=True, delay=0.001):
GPIO.output(DIR, clockwise)
for _ in range(steps):
GPIO.output(STEP, GPIO.HIGH)
sleep(delay)
GPIO.output(STEP, GPIO.LOW)
sleep(delay)
move(200, clockwise=True) # one revolution
GPIO.cleanup()5.4. Silent driver (TMC2209)
TMC drivers add UART configuration, StealthChop (near-silent) and StallGuard (sensorless homing) on top of the same STEP/DIR interface, so the code above still works while you tune current/microsteps over serial.
6. Practical Considerations
- Lost steps: If load exceeds torque or acceleration is too aggressive, the motor skips steps and position is silently wrong. Ramp speed and size with margin.
- Torque vs. speed: Holding torque is highest at standstill and falls as step rate rises; there is a top speed beyond which it stalls.
- Heat: Steppers draw full current even when holding still. Lower the hold current if the driver supports it.
- Resonance: Mid-speed resonance can cause missed steps; microstepping and damping help.
- Closed-loop steppers: Adding an encoder (e.g. servo-stepper hybrids) recovers lost steps and gives servo-like reliability while keeping stepper simplicity.
7. Summary
| Aspect | Stepper |
|---|---|
| Feedback | None (open loop) by default |
| Resolution | 200 full steps/rev, up to 256x microstepping |
| Interface | STEP + DIR + EN, microstep select pins |
| Strength | Precise, cheap, strong holding torque |
| Weakness | Loses steps if overloaded; torque drops at speed |
| Programming | Pulse STEP; use AccelStepper for ramps |
Steppers trade the feedback loop of a [[02-servos]] for dead-simple open-loop counting. When they lose steps or you need higher speed/efficiency, step up to a [[04-brushless-motors]] servo.