Two steppers on a CNC shield, on an Arduino Uno
A CNC shield v3 with A4988 drivers on an Uno: the X and Y NEMA 17s turn a quarter turn each way, stepped on pins 2 and 3, turned on 5 and 6, enabled by pin 8. The whole build, an Arduino Uno and 4 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Intermediate About 20 minutes to build and run. Runs in your browser. Free, and no account needed.
The parts retail for about $63. On Mokxi they're free.
What you'll learn
- STEP and DIR signals for a stepper driver
- Microstepping and steps per turn
- An enable pin that is active low
- Separate motor power from logic power
- Difficulty: Intermediate
- Time: About 20 minutes
- Board: Arduino Uno R3
- Parts: 5
How it works
A CNC shield v3 sits on the Uno with A4988 stepper drivers. Each driver turns two signals into motor moves: a pulse on STEP moves the motor one microstep, and the level on DIR picks the direction. The X driver uses pins 2 and 5, the Y driver pins 3 and 6.
The motor power comes from a separate DC source on VM+ and VM-. The shield holds pin 8 high, which keeps the drivers off, so the sketch drives pin 8 low to enable them.
The jumpers set 1/16 microstepping, so a full turn is 3200 steps. The loop turns both NEMA 17 motors a quarter turn, with X and Y going opposite ways, pauses, and then reverses.
Parts list
5 parts, plus the jumper wires. They retail for about $63; on Mokxi they're free.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × CNC shield v3 with A4988s
- 2 × Stepper motor, NEMA 17
- 1 × DC voltage source
Wiring table
Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.
| Part and pin | Connects to |
|---|---|
| CNC shield v3 with A4988s pin D8 | Arduino Uno R3 pin 8 |
| CNC shield v3 with A4988s pin D6 | Arduino Uno R3 pin 6 |
| CNC shield v3 with A4988s pin D5 | Arduino Uno R3 pin 5 |
| CNC shield v3 with A4988s pin D3 | Arduino Uno R3 pin 3 |
| CNC shield v3 with A4988s pin D2 | Arduino Uno R3 pin 2 |
| CNC shield v3 with A4988s pin 5V | Arduino Uno R3 pin 5V |
| CNC shield v3 with A4988s pin GND | Arduino Uno R3 pin GND |
| DC voltage source pin V+ | CNC shield v3 with A4988s pin VM+ |
| DC voltage source pin V- | CNC shield v3 with A4988s pin VM- |
| Stepper motor, NEMA 17 (1) pin B2 | CNC shield v3 with A4988s pin X2B |
| Stepper motor, NEMA 17 (1) pin B1 | CNC shield v3 with A4988s pin X2A |
| Stepper motor, NEMA 17 (1) pin A1 | CNC shield v3 with A4988s pin X1A |
| Stepper motor, NEMA 17 (1) pin A2 | CNC shield v3 with A4988s pin X1B |
| Stepper motor, NEMA 17 (2) pin B2 | CNC shield v3 with A4988s pin Y2B |
| Stepper motor, NEMA 17 (2) pin B1 | CNC shield v3 with A4988s pin Y2A |
| Stepper motor, NEMA 17 (2) pin A1 | CNC shield v3 with A4988s pin Y1A |
| Stepper motor, NEMA 17 (2) pin A2 | CNC shield v3 with A4988s pin Y1B |
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Two stepper motors on the CNC shield v3, X and Y.
//
// X: STEP 2, DIR 5 Y: STEP 3, DIR 6 enable (all drivers): 8, LOW = on
//
// The shield pulls pin 8 high, so the drivers stay off until the sketch
// drives it low. Its jumpers set 1/16 microstepping: 3200 steps a turn.
const uint8_t X_STEP = 2, Y_STEP = 3, X_DIR = 5, Y_DIR = 6, ENABLE = 8;
const int STEPS_PER_TURN = 3200;
void steps(int count, unsigned int us) {
for (int i = 0; i < count; i++) {
digitalWrite(X_STEP, HIGH);
digitalWrite(Y_STEP, HIGH);
delayMicroseconds(5);
digitalWrite(X_STEP, LOW);
digitalWrite(Y_STEP, LOW);
delayMicroseconds(us);
}
}
void setup() {
pinMode(X_STEP, OUTPUT);
pinMode(Y_STEP, OUTPUT);
pinMode(X_DIR, OUTPUT);
pinMode(Y_DIR, OUTPUT);
pinMode(ENABLE, OUTPUT);
digitalWrite(ENABLE, LOW);
}
void loop() {
// A quarter turn one way, X and Y opposite...
digitalWrite(X_DIR, HIGH);
digitalWrite(Y_DIR, LOW);
steps(STEPS_PER_TURN / 4, 300);
delay(300);
// ...and back.
digitalWrite(X_DIR, LOW);
digitalWrite(Y_DIR, HIGH);
steps(STEPS_PER_TURN / 4, 300);
delay(300);
}
Code walkthrough
The key functions of the sketch, and what each one does.
steps sketch.ino
Sends count pulses to both STEP pins at once. Each pulse is high for 5 microseconds, then low for us microseconds. A longer us means slower motors. Both motors move together because both pins are switched in the same loop.
void steps(int count, unsigned int us) {
for (int i = 0; i < count; i++) {
digitalWrite(X_STEP, HIGH);
digitalWrite(Y_STEP, HIGH);
delayMicroseconds(5);
digitalWrite(X_STEP, LOW);
digitalWrite(Y_STEP, LOW);
delayMicroseconds(us);
}
}setup sketch.ino
Sets the STEP, DIR and ENABLE pins as outputs, then drives ENABLE low. The shield holds that pin high, so without this the drivers stay off and the motors do not move.
void setup() {
pinMode(X_STEP, OUTPUT);
pinMode(Y_STEP, OUTPUT);
pinMode(X_DIR, OUTPUT);
pinMode(Y_DIR, OUTPUT);
pinMode(ENABLE, OUTPUT);
digitalWrite(ENABLE, LOW);
}loop sketch.ino
Sets the two DIR pins to opposite levels, then calls steps for STEPS_PER_TURN / 4 steps at 300 microseconds each, a quarter turn. After a 300 ms pause it flips both directions and steps the same amount back.
void loop() {
// A quarter turn one way, X and Y opposite...
digitalWrite(X_DIR, HIGH);
digitalWrite(Y_DIR, LOW);
steps(STEPS_PER_TURN / 4, 300);
delay(300);
// ...and back.
digitalWrite(X_DIR, LOW);
digitalWrite(Y_DIR, HIGH);
steps(STEPS_PER_TURN / 4, 300);
delay(300);
}Troubleshooting
The usual mistakes with this circuit, and the fix for each.
- The motors do not move at all This project
Check that pin 8 is driven low insetupand that the DC source is wired to VM+ and VM-. - The motors move the wrong amount This project
STEPS_PER_TURNassumes 1/16 microstepping. If you change the jumpers, change that constant too. - The driver or the Arduino dies when you plug in a stepper motor. CNC shield v3 with A4988s
Never connect or disconnect motors while the shield has power. Add a 100 uF capacitor across the motor supply. Supply is typically 12 to 24 V, and the A4988 limit is 35 V. - Motors hum, stall, or run hot. CNC shield v3 with A4988s
Set the current limit with the Vref trimmer on each A4988 before use, to about the motor's rated current. Wire each coil to its own output pair. Cool the drivers with a heatsink. - The motor buzzes, shudders, or only vibrates instead of turning. Stepper motor
Coils are swapped. Find the two coil pairs by measuring resistance with a meter (a few ohms between wires of one coil). Connect each pair to one driver coil output, A to A and B to B. - The motor stalls or loses steps when you speed up. Stepper motor
A stepper cannot jump to a high speed. Start with slow step pulses and ramp up gradually. Check the driver current limit (Vref) and give the supply enough voltage, such as 12 V. - The circuit sees no voltage or the wrong amount. DC voltage source
Make sure V+ and V- go to the right nodes. The source floats, so tie one side to your circuit ground. Check the set voltage matches what your parts allow. - A part gets too much voltage. DC voltage source
Check the rating of every part before raising the supply. Use series resistors with LEDs, and do not connect the source straight across a short.
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.