raw Software

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)

  1. Read motor rated phase current from the datasheet.
  2. Set full-step mode (MS1-MS3 LOW or open).
  3. Hold position with STEP/DIR configured so the driver energizes coils.
  4. 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:

  1. Look up the motor's maximum rated phase current in its datasheet.
  2. 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.
  3. 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.
  4. 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
  1. Set Vref before aggressive motion tests.
  2. Run 30 to 60 seconds unloaded and check driver temperature by hand carefully.
  3. Add load and increase speed stepwise.
  4. 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.

  1. Open Arduino IDE and launch Library Manager.
  2. Search for AccelStepper by Mike McCauley.
  3. 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.