If you build motion systems for robotics, CNC prototypes, or 3D-printer style mechanics, a bipolar stepper motor gives you repeatable positioning that plain DC motors cannot provide. The practical challenge is current: a typical Arduino pin cannot drive a NEMA 17 coil directly.
The A4988 solves that by handling coil commutation, current limiting, and microstepping on a compact breakout. This guide is written as a complete bring-up flow: power and wiring, safe current-limit setup, and working code for one and two motors.
[PHOTO PLACEHOLDER: A4988 module top view with labeled pins and trimmer]
A4988 Overview
The A4988 is a microstepping bipolar stepper driver IC from Allegro. With the common breakout modules, Arduino control is simplified to two core signals:
- STEP: one rising edge advances one microstep/full step (depending on mode)
- DIR: controls rotation direction
Instead of generating a four-phase coil sequence in software, you send pulse timing only. That reduces firmware complexity and keeps timing predictable.
Integrated protection mechanisms include undervoltage lockout, overcurrent protection, thermal shutdown, short-to-ground protection, and cross-conduction prevention in the output stage.
Typical Electrical Specs
| Parameter | Typical Range / Value |
|---|---|
| Motor supply (VMOT) | 8V to 35V |
| Logic supply (VDD) | 3V to 5.5V |
| Continuous current (practical) | about 1A per phase without aggressive cooling |
| Peak current (chip-level, cooling dependent) | up to 2A per phase |
| Microstepping modes | full, 1/2, 1/4, 1/8, 1/16 |
Datasheet: Allegro A4988 Datasheet
Pin Groups and Behavior
[SKETCH PLACEHOLDER: complete A4988 pinout with VMOT, VDD, STEP, DIR, MS1-MS3, EN, RST, SLP, 1A-2B]
Power Pins
- VDD / GND: logic supply from MCU side
- VMOT / GND: motor supply input
Use a local electrolytic capacitor near VMOT and GND (at least 47uF) to suppress destructive supply spikes caused by cable inductance and fast current changes.
Important: low-ESR ceramics on many modules can allow LC spikes that exceed 35V at VMOT even with a nominal 12V supply, so place the electrolytic capacitor close to the driver.
Control Pins
- STEP: pulse input, step on edge
- DIR: direction select
Do not leave STEP or DIR floating. Drive them from MCU pins or tie to a defined logic level.
Microstep Pins (MS1, MS2, MS3)
These inputs select step resolution. Internal pull-down resistors make the default mode full-step when pins are left open.
| MS1 | MS2 | MS3 | Resolution |
|---|---|---|---|
| LOW | LOW | LOW | Full step |
| HIGH | LOW | LOW | Half step |
| LOW | HIGH | LOW | Quarter step |
| HIGH | HIGH | LOW | Eighth step |
| HIGH | HIGH | HIGH | Sixteenth step |
Power-State Pins
- EN: active-low enable (LOW = outputs active), usually pulled LOW on common modules
- SLP: active-low sleep, must be HIGH for normal operation
- RST: active-low reset and often floating on breakouts, tie to SLP if reset is unused
After SLP returns HIGH, allow at least 1ms for the charge pump to stabilize before issuing STEP pulses.
Motor Outputs
- 1A, 1B: coil A
- 2A, 2B: coil B
Wiring A4988 to Arduino
Recommended Baseline Mapping
| A4988 | Arduino UNO | Note |
|---|---|---|
| VDD | 5V | Logic supply |
| GND (logic) | GND | Common reference |
| STEP | D3 | Step pulses |
| DIR | D2 | Direction control |
| SLP | 5V (or controlled pin) | Must be HIGH for normal run |
| RST | SLP | Tie together if reset is unused |
Connect VMOT and motor GND to an external supply sized for your motor. Always share GND between Arduino and motor supply.
Never connect or disconnect a stepper motor while VMOT is energized. Interrupting an energized winding can generate destructive transients and can damage the driver immediately. Power down VMOT before moving motor wires, changing coil pairs, or inserting/removing a plug-in carrier.
Driver orientation warning: do not use potentiometer position as orientation reference because board variants differ. Use printed pin labels and especially EN marking to verify insertion direction.
[SKETCH PLACEHOLDER: full wiring with external motor PSU and 47uF capacitor near VMOT]
Identifying Coil Pairs
- Use continuity mode: wires that measure as one coil belong together.
- Or short-test by hand: short one pair, shaft gets harder to rotate.
- Connect one coil to 1A/1B and the other to 2A/2B.
STEP and DIR Timing
The A4988 requires STEP to remain HIGH for at least 1us and LOW for at least 1us. Set DIR at least 200ns before a rising STEP edge and keep it unchanged for at least 200ns afterward. The example pulses are deliberately much longer, but timer-based firmware must still enforce these minimums.
Cooling and Thermal Reality
Many tutorials quote up to 2A per phase, but real sustained current depends on cooling and PCB design. Without a heatsink and airflow, thermal shutdown appears much earlier.
- For currents above about 1A/phase, use at least a heatsink.
- For enclosed systems, add airflow or derate current.
- After tuning, run a 10-15 minute stress test and verify driver temperature margin.
[PHOTO PLACEHOLDER: A4988 with installed heatsink and fan direction]
Current Limit Setup
Phase Current Is Not Supply Current
A stepper motor's current rating applies to each winding. The A4988 uses a chopper regulator to convert a higher VMOT supply into controlled winding current, so the current drawn from the power supply is not the same as either phase current and may be substantially lower. Set the current limit from the motor's rated phase current, not from a current measurement at the supply input. The motor's low nameplate voltage is likewise not the VMOT ceiling when current regulation is configured correctly.
You can run motors from higher supply voltage for better high-speed torque, but only if phase current is limited correctly. Otherwise motor and driver overheat quickly.
A motor that only pulses, stalls, or moves erratically may have an incorrectly adjusted current limit. If the behavior improves as the trimmer setting is reduced, stop testing and tune the current deliberately rather than continuing by feel. The same symptoms can also come from a misidentified coil pair, insufficient supply current, or pulse timing that is too aggressive, so Vref is an important check rather than a diagnosis by itself.
Method 1: Measure Coil Current (full-step hold)
- Read motor rated phase current from the datasheet.
- Set full-step mode (MS1-MS3 LOW or open).
- Hold position with STEP/DIR configured so the driver energizes coils.
- With VMOT switched off, insert an ammeter in series with one coil lead. Then energize the driver and adjust the trimmer until the measured hold current is approximately 70.7% of the intended current limit.
In full-step mode the A4988 regulates both energized coils to approximately 0.707 × I_limit. Therefore a desired 1.0A current limit should produce about 0.707A in either coil during a full-step hold. Do not adjust the measured hold current to the full 1.0A: doing so would set the internal current limit to about 1.41A. Verify thermal behavior again in the final microstep mode.
Method 2: Set Vref (most practical)
Determine the sense resistor value from the markings on the carrier. Depending on the manufacturer, the two resistors may be located near labels such as R5, S1, or S2. Common top markings include R050, R068, R10, R100, and R200, corresponding to 0.05, 0.068, 0.10, 0.10, and 0.20 ohm. Verify unfamiliar SMD codes against the carrier documentation or an SMD resistor code reference instead of assuming that every A4988 module uses the same value. Then calculate the target reference voltage:
Vref = I_limit × 8 × R_s
- I_limit: target phase current in ampere
- R_s: sense resistor in ohm
This equation is specific to the A4988 current regulator and the actual sense resistors fitted to its carrier. Do not reuse it for DRV8825, TMC2208, TMC2209, or another nominally pin-compatible module. Trinamic carriers may use different sense networks, and UART-configured systems can set motor current digitally instead of relying on the potentiometer alone.
For long motor life, many builds run with 10-20% current headroom below the motor nameplate current.
For example, an A4988 carrier with R_s = 0.10 ohm driving a 1.5A-per-phase motor at 80% of its rating has the target current
I_limit = 1.5A × 0.8 = 1.2A
and therefore
Vref = 1.2A × 8 × 0.10 ohm = 0.96V.
[PHOTO PLACEHOLDER: top-down close-up of the A4988 trimmer potentiometer with the GND test pad labeled, showing exactly where to place the two multimeter probes]
Adjusting the motor current on an A4988 always follows the same three steps:
- Look up the motor's maximum rated phase current in its datasheet.
- Disconnect the motor and switch VMOT off. Power VDD from the microcontroller, set the multimeter to DC volts, secure its black probe to GND, and touch the red probe to the trimmer wiper.
- Turn the trimmer slowly with a ceramic or otherwise insulated adjustment tool until Vref matches the calculated target. Avoid slipping onto adjacent components, do not force the potentiometer past its end stop, and verify on the meter whether clockwise raises or lowers Vref on your carrier.
- Connect the stepper motor and verify smooth, quiet operation while monitoring driver temperature.
Driver Vref Calculator
Enter motor phase current and safety margin. The calculator applies the margin first and then computes Vref.
- Effective current after margin: 0.850 A
- Used factor: 0.800 (factor = 8 * R_s)
- A4988 Vref: 0.680 V (Vref = I * factor)
Example Calculations
| Target Current | Sense Resistor | Vref |
|---|---|---|
| 1.0A | 0.10 ohm (R100) | 0.80V |
| 0.8A | 0.05 ohm (R050) | 0.32V |
| 1.5A | 0.10 ohm (R100) | 1.20V |
NEMA 17 Quick-Start Profile (Concrete Values)
If you want a reliable first run with a typical 200-steps/rev NEMA 17 motor, start with conservative values and only increase after thermal checks.
| Parameter | Recommended Start Value |
|---|---|
| Supply voltage (VMOT) | 12V |
| Microstep mode | Full-step for bring-up, then 1/8 if smoothness is required |
| Target current limit | 1.0A per phase for initial tests |
| Vref at R100 sense resistors | 0.8V (from Vref = I_limit * 8 * R_s) |
| Pulse timing (basic test) | 1200us to 2000us HIGH/LOW spacing |
- Set Vref before aggressive motion tests.
- Run 30 to 60 seconds unloaded and check driver temperature by hand carefully.
- Add load and increase speed stepwise.
- If stalls occur, reduce acceleration first, then top speed.
Arduino Example 1: Direct Pulses (No Library)
This minimal sketch demonstrates direction control and speed changes by pulse timing.
// A4988 + Arduino UNO basic pulse demo
const int dirPin = 2;
const int stepPin = 3;
const int stepsPerRevolution = 200;
void setup() {
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
}
void singleTurn(bool cw, int pulseDelayUs) {
digitalWrite(dirPin, cw ? HIGH : LOW);
for (int i = 0; i < stepsPerRevolution; ++i) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(pulseDelayUs);
digitalWrite(stepPin, LOW);
delayMicroseconds(pulseDelayUs);
}
}
void loop() {
singleTurn(true, 1800); // slower clockwise turn
delay(700);
singleTurn(false, 900); // faster reverse turn
delay(700);
} Shorter pulse delays increase speed. If the motor stalls, reduce speed or increase acceleration ramping.
Arduino Example 2: AccelStepper for Smooth Motion
For controlled ramps and cleaner movement, use AccelStepper. Install it through Arduino IDE Library Manager.
- Open Arduino IDE and launch Library Manager.
- Search for AccelStepper by Mike McCauley.
- Install the library and restart the IDE if required.
#include <AccelStepper.h>
const int dirPin = 2;
const int stepPin = 3;
const int motorInterfaceType = 1;
AccelStepper stepper(motorInterfaceType, stepPin, dirPin);
void setup() {
stepper.setMaxSpeed(1200);
stepper.setAcceleration(120);
stepper.moveTo(400);
}
void loop() {
if (stepper.distanceToGo() == 0) {
stepper.moveTo(-stepper.currentPosition());
}
stepper.run();
} The key point: run() must be called continuously, otherwise no steps are generated.
Arduino Example 3: Two Steppers at the Same Time
Each motor needs its own A4988. Share logic ground and motor ground, then assign separate STEP/DIR pins.
#include <AccelStepper.h>
const int motorInterfaceType = 1;
AccelStepper stepper1(motorInterfaceType, 3, 2);
AccelStepper stepper2(motorInterfaceType, 5, 4);
void setup() {
stepper1.setMaxSpeed(1000);
stepper1.setAcceleration(80);
stepper1.moveTo(320);
stepper2.setMaxSpeed(1000);
stepper2.setAcceleration(80);
stepper2.moveTo(-320);
}
void loop() {
if (stepper1.distanceToGo() == 0) {
stepper1.moveTo(-stepper1.currentPosition());
}
if (stepper2.distanceToGo() == 0) {
stepper2.moveTo(-stepper2.currentPosition());
}
stepper1.run();
stepper2.run();
} [SKETCH PLACEHOLDER: dual-driver wiring with separate STEP/DIR pairs]
Troubleshooting Checklist
- Motor only vibrates: coil pairs mixed up, re-check continuity pairs.
- No motion at all: verify SLP/RST state and shared GND.
- Random direction changes: STEP/DIR line noise or floating inputs.
- Driver resets under load: VMOT supply dip, add bulk capacitance and shorter wiring.
- Overheating: current limit too high, no heatsink, or enclosure lacks airflow.
Start conservative: lower current, lower speed, and full-step mode. Then increase one parameter at a time.