Skip to content

Ships from Colorado, USA • $5.95 flat-rate US shipping per order (any number of items) • FREE shipping over $75!

CNC Expansion Shield V3 for A4988 and DRV8825 Stepper Motor Drivers User Guide

CNC Expansion Shield V3 for A4988 and DRV8825 Stepper Motor Drivers for Arduino

📋 Overview

The CNC Expansion Shield V3 transforms your Arduino UNO or MEGA2560 into a powerful 4-axis stepper motor controller. Originally designed by Protoneer, this shield is the industry-standard solution for DIY CNC routers, laser engravers, 3D printers, and multi-axis robotics projects.

The shield provides dedicated sockets for up to four stepper motor driver modules (A4988 or DRV8825), along with connectors for limit switches, a spindle/laser, coolant control, and GRBL control signals — all without any soldering or complex wiring.

Key highlights:

  • 4 independent stepper motor channels (X, Y, Z, and A/clone axis)
  • Plug-and-play sockets for A4988 or DRV8825 driver modules
  • GRBL firmware compatible — converts G-code into precise stepping signals
  • Limit switch headers for all axes (6 total: 2 per axis for X, Y, Z)
  • Spindle enable and direction control pins
  • Coolant enable output pin
  • Abort, Hold, and Resume control pins
  • Onboard microstepping jumpers for each axis
  • Powered by 12–36V DC via screw terminals

Note: The kit from Envistia includes four A4988 stepper motor driver modules with heatsinks. For detailed information about the A4988 drivers themselves (pinout, current limiting, VREF setup), please refer to our dedicated A4988 Stepper Motor Driver User Guide.


📐 Specifications

Parameter Value
Shield Version V3.0 / V3.10 / V3.51
Compatible Boards Arduino UNO-Compatible, Arduino MEGA2560-Compatible, Arduino UNO R4-Compatible (custom sketches only, no GRBL)
Compatible Drivers A4988, DRV8825 (Pololu-compatible pinout)
Stepper Channels 4 (X, Y, Z, A)
Motor Supply Voltage 12V – 36V DC
Logic Supply 5V (derived from Arduino USB or VIN)
Firmware Compatibility GRBL 0.8, 0.9, 1.1 (UNO R3 / MEGA2560 only)
Limit Switch Inputs 6 (X+, X-, Y+, Y-, Z+, Z-)
Control Outputs Spindle Enable, Spindle Direction, Coolant Enable
Control Inputs Abort, Feed Hold, Resume
Microstepping Configurable per axis via jumpers
Board Dimensions ~68mm × 53mm (matches Arduino UNO footprint)

🔌 Shield Layout and Connectors

The CNC Shield V3 plugs directly onto the Arduino UNO's header pins. Here is a breakdown of all the connectors and headers on the board:

Stepper Driver Sockets

The shield has four sets of driver sockets labeled X, Y, Z, and A. Each socket accepts one A4988 or DRV8825 driver module.

⚠️ Critical: Driver orientation matters! When inserting the driver modules, the potentiometer (small brass adjustment screw) must face toward the power screw terminals (away from the Arduino USB port). Inserting a driver backwards will destroy it instantly when power is applied.

Motor Output Headers

Each axis has a 4-pin header for connecting the stepper motor's coil wires. These are typically labeled with color codes on the board:

Header Color Axis
Yellow X-axis
Red Y-axis
Blue Z-axis
Green/White A-axis (4th axis)

Power Input

Terminal Description
12–36V Motor power supply positive (+) via screw terminal
GND Motor power supply negative (−) via screw terminal

End Stop / Limit Switch Headers

Six 2-pin headers for limit switches, arranged in pairs for each axis:

Header Arduino Pin Description
X- D9 X-axis minimum limit switch
X+ D9 X-axis maximum limit switch (shared pin)
Y- D10 Y-axis minimum limit switch
Y+ D10 Y-axis maximum limit switch (shared pin)
Z- D11 Z-axis minimum limit switch
Z+ D11 Z-axis maximum limit switch (shared pin)

Note: By default, the + and − limit switches for each axis share the same Arduino pin. GRBL can be configured to use them as a combined home/limit signal. Each end stop header has two pins: Signal and GND. The switches are "normally open" — they connect the signal pin to GND when triggered.

Control Pin Headers

Header Arduino Pin Function
Abort A0 Emergency stop — immediately halts all motion
Hold A1 Feed hold — pauses motion (can be resumed)
Resume A2 Resumes motion after a feed hold
Coolant Enable A3 Turns on/off a coolant pump or mist system
Spindle Enable D12 Enables/disables the spindle motor or laser
Spindle Direction D13 Controls spindle rotation direction (CW/CCW)

⚙️ Arduino Pin Mapping

The CNC Shield V3 maps specific Arduino UNO pins to each function. This is important whether you're using GRBL firmware or writing your own Arduino sketches.

Stepper Motor Pins

Function Arduino Pin
X-axis STEP D2
X-axis DIR D5
Y-axis STEP D3
Y-axis DIR D6
Z-axis STEP D4
Z-axis DIR D7
Stepper Enable (all axes) D8

A-Axis (4th Axis) — See Jumper Configuration

The 4th axis (A) does not have its own dedicated Arduino pins. Instead, it clones (mirrors) one of the other axes using jumper settings. See the 4th Axis Jumper Configuration section below.

Limit Switch Pins

Function Arduino Pin
X Limit D9
Y Limit D10
Z Limit D11

Control Pins

Function Arduino Pin
Abort A0
Feed Hold A1
Resume A2
Coolant Enable A3
Spindle Enable D12
Spindle Direction D13
Stepper Enable D8 (active LOW — LOW = motors enabled)

🔧 Assembly and Setup

Step 1: Attach the Shield to the Arduino

  1. Align the CNC Shield's header pins with the Arduino UNO's female headers.
  2. Press the shield firmly and evenly onto the Arduino until fully seated.
  3. Ensure all pins are properly aligned — no pins should be bent or hanging off the edge.

Step 2: Install the Heatsinks on the A4988 Drivers

  1. Peel the adhesive backing from each heatsink.
  2. Place each heatsink on the A4988 chip (the largest IC on the driver board).
  3. Press firmly to adhere.

Step 3: Set the Current Limit on Each A4988

Before inserting the drivers into the shield, set the current limit (VREF) on each A4988 module to match your stepper motors. Refer to our A4988 Stepper Motor Driver User Guide for the complete VREF adjustment procedure.

Step 4: Insert the Stepper Drivers

  1. Identify the correct orientation — the potentiometer (brass screw) faces toward the power screw terminals.
  2. Carefully align the driver pins with the socket.
  3. Press the driver straight down into the socket until fully seated.
  4. Install drivers for each axis you plan to use (X, Y, Z, and optionally A).

⚠️ Never insert or remove driver modules while the shield is powered. This will destroy the driver and may damage the Arduino.

Step 5: Configure Microstepping Jumpers

See the Microstepping Jumper Configuration section below.

Step 6: Connect the Power Supply

  1. Connect your 12–36V DC power supply to the screw terminals on the shield.
  2. Observe correct polarity: + to the positive terminal, − to GND.
  3. Use a power supply rated for the total current draw of all your stepper motors combined.

Tip: A 12V 5A power supply is a good starting point for most setups with 2–4 NEMA 17 motors.

Step 7: Connect the Stepper Motors

  1. Connect each stepper motor's 4 wires to the corresponding axis motor header (X, Y, Z, or A).
  2. Identify the coil pairs using a multimeter (see the A4988 User Guide for wire identification instructions).
  3. If a motor spins in the wrong direction, swap the two wires of one coil at the header.

⚙️ Microstepping Jumper Configuration

Below each driver socket on the shield, there are three jumper positions labeled M0, M1, and M2 (corresponding to MS1, MS2, MS3 on the driver). Installing a jumper cap bridges the pins to HIGH.

For A4988 Drivers

M0 M1 M2 Resolution Steps/Rev (1.8° motor)
○ ○ ○ Full step 200
● ○ ○ Half step 400
○ ● ○ Quarter step 800
● ● ○ Eighth step 1,600
● ● ● Sixteenth step 3,200

(● = jumper installed, ○ = no jumper)

For DRV8825 Drivers

M0 M1 M2 Resolution Steps/Rev (1.8° motor)
○ ○ ○ Full step 200
● ○ ○ Half step 400
○ ● ○ Quarter step 800
● ● ○ Eighth step 1,600
○ ○ ● Sixteenth step 3,200
● ● ● 1/32 step 6,400

Tip: For CNC applications, eighth step (1/8) is a popular choice — it provides a good balance between resolution and speed. For 3D printing, sixteenth step (1/16) is common.


🔀 4th Axis Jumper Configuration

The CNC Shield V3 has a set of two jumpers near the A-axis socket that determine how the 4th axis behaves. The 4th axis can be configured to clone (mirror) any of the three main axes:

Jumper Position 4th Axis Clones
Both jumpers on bottom position X-axis (mirrors X step/dir signals)
Both jumpers on middle position Y-axis (mirrors Y step/dir signals)
Both jumpers on top position Z-axis (mirrors Z step/dir signals)

When to Use the 4th Axis

  • Dual-motor axes: If your CNC machine uses two stepper motors on the same axis (e.g., two motors driving the Y-axis gantry), clone that axis to the A-axis and connect the second motor to the A-axis header.
  • Independent 4th axis: For true independent 4th-axis control, you'll need custom firmware or a modified GRBL build that supports 4 axes (standard GRBL supports 3 axes).

🔗 Connecting End Stops / Limit Switches

Limit switches (also called end stops) tell the controller when an axis has reached its physical travel limit. They are essential for homing and for preventing the machine from crashing into its frame.

Wiring

Each end stop header has two pins: Signal and GND.

  1. Connect one terminal of your limit switch to the Signal pin.
  2. Connect the other terminal to the GND pin.
  3. The switches should be normally open (NO) — they close the circuit when triggered.

Configuration in GRBL

By default, GRBL treats the limit switches as active-low with internal pull-up resistors. When a switch is triggered (closed), the signal pin is pulled to GND, and GRBL detects the limit.

To enable limit switches and homing in GRBL, use these configuration commands via the serial terminal:

$20=1    (Enable soft limits)
$21=1    (Enable hard limits)
$22=1    (Enable homing cycle)
$23=0    (Homing direction invert mask — adjust as needed)
$24=25   (Homing feed rate, mm/min)
$25=500  (Homing seek rate, mm/min)

🖥️ Using with GRBL Firmware

The CNC Shield V3 is designed to work seamlessly with GRBL, the open-source G-code interpreter that runs on Arduino. GRBL converts G-code commands into precisely timed stepper motor pulses.

Installing GRBL on Arduino UNO

  1. Download the latest GRBL release from github.com/grbl/grbl.
  2. Open the Arduino IDE.
  3. Go to Sketch → Include Library → Add .ZIP Library and select the downloaded GRBL .zip file.
  4. Go to File → Examples → grbl → grblUpload.
  5. Select your Arduino board (Tools → Board → Arduino UNO) and the correct COM port.
  6. Click Upload.

Connecting to GRBL

Once GRBL is uploaded, you can communicate with it via any serial terminal at 115200 baud:

  • Arduino IDE Serial Monitor (set to 115200 baud, "Newline" line ending)
  • Universal G-code Sender (UGS) — a popular free GUI
  • bCNC — another popular open-source CNC controller
  • Easel (by Inventables) — web-based, beginner-friendly
  • CNCjs — web-based CNC controller

Essential GRBL Configuration Commands

Type these commands in the serial terminal to configure GRBL for your machine:

Command Description Example
$$ View all current settings $$
$0 Step pulse time (µs) $0=10
$1 Step idle delay (ms) $1=25
$100 X steps/mm $100=250
$101 Y steps/mm $101=250
$102 Z steps/mm $102=250
$110 X max rate (mm/min) $110=500
$111 Y max rate (mm/min) $111=500
$112 Z max rate (mm/min) $112=500
$120 X acceleration (mm/sec²) $120=10
$121 Y acceleration (mm/sec²) $121=10
$122 Z acceleration (mm/sec²) $122=10

Calculating Steps Per Millimeter

Use this formula to determine the correct $100, $101, $102 values:

Steps/mm = (Motor steps per rev × Microstepping) / (Belt pitch × Pulley teeth)

Example: A 1.8° motor (200 steps/rev) with 1/8 microstepping, a GT2 belt (2mm pitch), and a 20-tooth pulley:

Steps/mm = (200 × 8) / (2 × 20) = 1600 / 40 = 40 steps/mm

For lead screw drives:

Steps/mm = (Motor steps per rev × Microstepping) / Lead screw pitch (mm)


💻 Using with Arduino IDE (Without GRBL)

You can also control the CNC Shield directly from Arduino sketches without GRBL. This is useful for simple automation, testing, or custom motion control projects.

Basic Example: Move X and Y Axes

// CNC Shield V3 - Direct Arduino Control
// Envistia Mall - envistiamall.com

// Pin definitions (CNC Shield V3 mapping)
#define X_STEP  2
#define X_DIR   5
#define Y_STEP  3
#define Y_DIR   6
#define Z_STEP  4
#define Z_DIR   7
#define EN_PIN  8   // Stepper enable (active LOW)

void setup() {
  // Set all pins as outputs
  pinMode(X_STEP, OUTPUT);
  pinMode(X_DIR, OUTPUT);
  pinMode(Y_STEP, OUTPUT);
  pinMode(Y_DIR, OUTPUT);
  pinMode(Z_STEP, OUTPUT);
  pinMode(Z_DIR, OUTPUT);
  pinMode(EN_PIN, OUTPUT);

  // Enable stepper drivers (active LOW)
  digitalWrite(EN_PIN, LOW);
}

void loop() {
  // Move X-axis 200 steps forward
  digitalWrite(X_DIR, HIGH);
  for (int i = 0; i < 200; i++) {
    digitalWrite(X_STEP, HIGH);
    delayMicroseconds(800);
    digitalWrite(X_STEP, LOW);
    delayMicroseconds(800);
  }

  delay(500);

  // Move Y-axis 200 steps forward
  digitalWrite(Y_DIR, HIGH);
  for (int i = 0; i < 200; i++) {
    digitalWrite(Y_STEP, HIGH);
    delayMicroseconds(800);
    digitalWrite(Y_STEP, LOW);
    delayMicroseconds(800);
  }

  delay(500);

  // Move both axes back
  digitalWrite(X_DIR, LOW);
  digitalWrite(Y_DIR, LOW);
  for (int i = 0; i < 200; i++) {
    digitalWrite(X_STEP, HIGH);
    digitalWrite(Y_STEP, HIGH);
    delayMicroseconds(800);
    digitalWrite(X_STEP, LOW);
    digitalWrite(Y_STEP, LOW);
    delayMicroseconds(800);
  }

  delay(1000);
}

Example: Using AccelStepper Library with CNC Shield

⚠️ UNO R4 owners: This AccelStepper example is for the Arduino UNO R3 and MEGA2560. AccelStepper does not run reliably on the Arduino UNO R4, so see the "Using the CNC Shield with an Arduino UNO R4" section below for a working alternative.

For smoother motion with acceleration, use the AccelStepper library (install via Arduino IDE Library Manager):

// CNC Shield V3 with AccelStepper Library
// Envistia Mall - envistiamall.com

#include <AccelStepper.h>

// Define steppers using CNC Shield pin mapping
AccelStepper stepperX(AccelStepper::DRIVER, 2, 5);  // STEP=D2, DIR=D5
AccelStepper stepperY(AccelStepper::DRIVER, 3, 6);  // STEP=D3, DIR=D6
AccelStepper stepperZ(AccelStepper::DRIVER, 4, 7);  // STEP=D4, DIR=D7

#define EN_PIN 8

void setup() {
  // Enable drivers
  pinMode(EN_PIN, OUTPUT);
  digitalWrite(EN_PIN, LOW);

  // Configure X-axis
  stepperX.setMaxSpeed(1000);
  stepperX.setAcceleration(500);

  // Configure Y-axis
  stepperY.setMaxSpeed(1000);
  stepperY.setAcceleration(500);

  // Configure Z-axis
  stepperZ.setMaxSpeed(800);
  stepperZ.setAcceleration(300);
}

void loop() {
  // Move X to position 1600, Y to 800, Z to 400
  stepperX.moveTo(1600);
  stepperY.moveTo(800);
  stepperZ.moveTo(400);

  // Run all steppers simultaneously until they reach targets
  while (stepperX.isRunning() || stepperY.isRunning() || stepperZ.isRunning()) {
    stepperX.run();
    stepperY.run();
    stepperZ.run();
  }

  delay(1000);

  // Return all axes to home
  stepperX.moveTo(0);
  stepperY.moveTo(0);
  stepperZ.moveTo(0);

  while (stepperX.isRunning() || stepperY.isRunning() || stepperZ.isRunning()) {
    stepperX.run();
    stepperY.run();
    stepperZ.run();
  }

  delay(1000);
}

💻 Using the CNC Shield with an Arduino UNO R4

The CNC Shield V3 was designed for the classic Arduino UNO (R3) and MEGA2560, but it also plugs onto the newer UNO R4 Minima and UNO R4 WiFi, including our UNO R4-Compatible WiFi Board. The R4 keeps the same 5V logic and the same UNO header layout, so the shield fits and the pin mapping in this guide stays the same.

The catch is software. The R4 uses a different processor (a 32-bit Renesas RA4M1 instead of the 8-bit ATmega328P), and two popular CNC tools, GRBL and the AccelStepper library, do not run properly on it. This section explains what does work and how to get your stepper motors moving.

⚠️ Important: GRBL cannot be installed on an Arduino UNO R4, which means G-code sender programs such as Universal G-code Sender, bCNC, CNCjs, and Easel will not work with it. If you want to run G-code on a CNC router or laser engraver, use this shield with an Arduino UNO R3 or MEGA2560 and GRBL. The UNO R4 approach below is for custom sketches: robotics, automation, camera sliders, test rigs, and learning projects.

What Works on the UNO R4 and What Doesn't

Software On the UNO R4 Notes
GRBL (classic) Does not work Written for the ATmega328P processor. The build stops with an "avr/io.h: No such file or directory" error. We are not aware of a working port to the RA4M1.
AccelStepper Not recommended It compiles, but Arduino's own hardware testing marked it as failing, and users report motors stuttering or running erratically. The exact cause is not documented.
Arduino Stepper library Works, but limited It moves one motor at a time and has no acceleration, so it is a poor fit for multi-axis motion.
MobaTools Works Officially supports the UNO R4 Minima and UNO R4 WiFi (RA4M1). Supports acceleration ramps, up to 6 steppers, and synchronized multi-axis moves.

Why MobaTools?

MobaTools is a free, open-source Arduino library (originally written for model railroaders) with a stepper class that works with step/direction drivers like the A4988 and DRV8825 on this shield. Here is what makes it a good fit:

  • Non-blocking motion — the library generates step pulses in the background with a hardware timer, so your sketch can keep reading buttons, sensors, or Wi-Fi while the motors move. You do not need to call a "run" function over and over.
  • Acceleration and deceleration ramps — smooth starts and stops that reduce missed steps.
  • Absolute and relative moves — move to a position, or move a number of steps from where you are.
  • Synchronized moves — a separate group class makes several axes start and finish together, so the tool travels in a straight line.
  • Room to grow — the default maximum step rate on the UNO R4 is 12,000 steps per second, compared with 2,500 on classic AVR boards. Your motor and power supply will usually be the limit first.

MobaTools is a motion-control library, not a G-code interpreter. It moves motors where your sketch tells them to go, but it does not read G-code files.

Hardware Notes for the UNO R4

  • Pin mapping is unchanged — STEP and DIR pins (D2 through D7), the enable pin (D8), and the limit switch pins (D9 through D11) are the same as in the Arduino Pin Mapping section of this guide.
  • Logic levels match — the R4 runs its pin headers at 5V, just like the UNO R3. The shield's STEP, DIR, and enable lines only drive the logic inputs of the driver modules, which draw very little current, well within the R4's 8 mA per-pin rating.
  • Shared pins — on the R4, D10 and D13 double as CAN bus pins, and A1 through A3 double as the op-amp pins. The shield uses those pins for limit switches, spindle direction, and control headers, so avoid using the R4's CAN or op-amp features at the same time as those shield functions.
  • Power — power the R4 over USB-C while testing, and connect your 12–36V motor supply to the shield's screw terminals as described in the Power Supply Requirements section.
  • Driver setup is the same — set the current limit (VREF) on each driver before inserting it, and check the driver orientation before applying power.

Installing MobaTools

  1. Open the Arduino IDE and make sure the UNO R4 board package is installed (see the UNO R4-Compatible WiFi Board User Guide).
  2. Go to Sketch → Include Library → Manage Libraries.
  3. In the search bar, type "MobaTools".
  4. Find "MobaTools" by MicroBahner and click Install.
  5. Select your board under Tools → Board (Arduino UNO R4 WiFi for our UNO R4-Compatible WiFi Board) and the correct port.

📝 Note: Use version 2.6.0 or newer. The Library Manager installs the latest version automatically.

Steps per Revolution

MobaTools needs to know how many steps make one full turn of your motor. This depends on your motor and the microstepping jumpers (M0, M1, M2) under each driver socket. For a standard 1.8° motor (200 full steps per turn) with A4988 drivers:

Jumpers Installed Resolution Steps per Revolution
None Full step 200
M0 + M1 1/8 step 1,600
M0 + M1 + M2 1/16 step 3,200

The examples below assume 1/8 microstepping (jumpers on M0 and M1), which is a good all-around choice. If you use a different setting, change the STEPS_PER_REV value in the sketch to match.

Key MobaTools Commands

Command What It Does
MoToStepper stepperX(1600, STEPDIR); Creates a stepper that uses a step/direction driver, with 1,600 steps per turn
stepperX.attach(stepPin, dirPin); Connects the stepper to its STEP and DIR pins
stepperX.setMaxSpeed(1000); Sets the top speed in steps per second
stepperX.setSpeed(300); Sets the top speed in revolutions per minute times 10 (300 = 30 rpm)
stepperX.setRampLen(400); Sets how many steps the motor takes to speed up or slow down (0 = no ramp)
stepperX.doSteps(800); Moves 800 steps from the current position (negative numbers go backward)
stepperX.moveTo(3200); Moves to an absolute position, measured in steps from the zero point
stepperX.rotate(1); Turns continuously (1 = forward, -1 = backward) until stopped; rotate(0) stops with a ramp
stepperX.stop(); Stops immediately
stepperX.moving(); Returns 0 when the motor is stopped, so you can wait for a move to finish
stepperX.setZero(); Makes the current position the zero point
stepperX.currentPosition(); Returns the current position in steps

Coming from AccelStepper?

If you have an existing AccelStepper sketch, most of it carries over with small changes:

AccelStepper MobaTools
AccelStepper s(AccelStepper::DRIVER, step, dir); MoToStepper s(stepsPerRev, STEPDIR); then s.attach(step, dir);
setMaxSpeed(n) setMaxSpeed(n) (same name, steps per second)
setAcceleration(n) setRampLen(steps) (set as a ramp length in steps instead of an acceleration value)
moveTo(n) moveTo(n) (same)
move(n) move(n) or doSteps(n)
run() Not needed. MobaTools runs in the background.
isRunning() moving()
distanceToGo(), currentPosition() Same names
setCurrentPosition(0) setZero()

Example 1: Single Axis Test

Start here to confirm everything is wired correctly. The X-axis motor turns one full revolution forward, pauses, then turns one revolution back. Install one driver in the X socket, place jumpers on M0 and M1, and connect a motor and your motor power supply.

// CNC Shield V3 + UNO R4 - Single Axis Test (MobaTools)
// Envistia Mall - envistiamall.com

#include <MobaTools.h>

const byte X_STEP = 2;     // CNC Shield V3: X STEP = D2
const byte X_DIR  = 5;     // CNC Shield V3: X DIR  = D5
const byte EN_PIN = 8;     // Enable pin for all drivers (active LOW)

const int STEPS_PER_REV = 200 * 8;   // 1600 steps per turn at 1/8 microstepping

MoToStepper stepperX(STEPS_PER_REV, STEPDIR);   // STEPDIR = step/direction driver

void setup() {
  pinMode(EN_PIN, OUTPUT);
  digitalWrite(EN_PIN, LOW);              // LOW = drivers enabled

  stepperX.attach(X_STEP, X_DIR);         // connect library to the STEP and DIR pins
  stepperX.setSpeed(300);                 // speed in rpm x 10, so 300 = 30 rpm
  stepperX.setRampLen(STEPS_PER_REV / 4); // ramp up/down over a quarter turn
}

void loop() {
  stepperX.doSteps(STEPS_PER_REV);        // one full turn forward
  while (stepperX.moving()) { }           // wait until the move is finished
  delay(1000);

  stepperX.doSteps(-STEPS_PER_REV);       // one full turn back
  while (stepperX.moving()) { }
  delay(1000);
}

💡 Tip: If the motor turns the opposite way from what you want, either swap the two wires of one coil at the motor header, or add INV_DIR to the attach line: stepperX.attach(X_STEP, X_DIR, INV_DIR);

Example 2: Three Axes Moving Independently

Each axis gets its own speed and ramp and finishes on its own schedule. The move commands return immediately, so all three motors start at the same moment.

// CNC Shield V3 + UNO R4 - Three Axes Moving Independently (MobaTools)
// Envistia Mall - envistiamall.com

#include <MobaTools.h>

const byte X_STEP = 2, X_DIR = 5;
const byte Y_STEP = 3, Y_DIR = 6;
const byte Z_STEP = 4, Z_DIR = 7;
const byte EN_PIN = 8;

const int STEPS_PER_REV = 200 * 8;    // 1600 at 1/8 microstepping

MoToStepper stepperX(STEPS_PER_REV, STEPDIR);
MoToStepper stepperY(STEPS_PER_REV, STEPDIR);
MoToStepper stepperZ(STEPS_PER_REV, STEPDIR);

void setup() {
  pinMode(EN_PIN, OUTPUT);
  digitalWrite(EN_PIN, LOW);            // enable all drivers

  stepperX.attach(X_STEP, X_DIR);
  stepperY.attach(Y_STEP, Y_DIR);
  stepperZ.attach(Z_STEP, Z_DIR);

  stepperX.setMaxSpeed(1000);           // steps per second
  stepperY.setMaxSpeed(1000);
  stepperZ.setMaxSpeed(800);

  stepperX.setRampLen(400);             // ramp length in steps
  stepperY.setRampLen(400);
  stepperZ.setRampLen(300);
}

void loop() {
  // Start all three moves - the calls return immediately
  stepperX.moveTo(3200);
  stepperY.moveTo(1600);
  stepperZ.moveTo(800);

  // Wait until every axis has arrived
  while (stepperX.moving() || stepperY.moving() || stepperZ.moving()) { }
  delay(1000);

  // Return all axes to the starting point
  stepperX.moveTo(0);
  stepperY.moveTo(0);
  stepperZ.moveTo(0);

  while (stepperX.moving() || stepperY.moving() || stepperZ.moving()) { }
  delay(1000);
}

📝 Note: These examples set the shared enable pin (D8) directly instead of using MobaTools' automatic enable feature. Because all four driver sockets share one enable pin, the automatic feature on one axis could switch the drivers off while another axis is still moving.

Example 3: Synchronized X/Y Moves

When two axes need to arrive at the same time, such as drawing a diagonal line, use the synchronized stepper group. The axis with the longest distance runs at the speed you set, and the other axes are slowed automatically so everything finishes together.

// CNC Shield V3 + UNO R4 - Synchronized X/Y Move (MobaTools)
// Envistia Mall - envistiamall.com

#include <MobaTools.h>

const byte X_STEP = 2, X_DIR = 5;
const byte Y_STEP = 3, Y_DIR = 6;
const byte EN_PIN = 8;

const int STEPS_PER_REV = 200 * 8;

MoToStepper stepperX(STEPS_PER_REV, STEPDIR);
MoToStepper stepperY(STEPS_PER_REV, STEPDIR);
MoToSyncStepper xyMove;                 // group object that keeps the axes in step

void setup() {
  pinMode(EN_PIN, OUTPUT);
  digitalWrite(EN_PIN, LOW);

  stepperX.attach(X_STEP, X_DIR);
  stepperY.attach(Y_STEP, Y_DIR);

  xyMove.addStepper(stepperX);          // order matters: X is first, Y is second
  xyMove.addStepper(stepperY);

  // Speed is in steps per 10 seconds: 10000 = 1000 steps/sec for the longest axis
  xyMove.setMaxSpeedSteps(10000, 400);  // second value = ramp length in steps
}

void loop() {
  long target[2] = { 3200, 1600 };      // absolute targets in steps: X, Y
  xyMove.moveTo(target);
  while (xyMove.moving()) { }
  delay(1000);

  long home[2] = { 0, 0 };
  xyMove.moveTo(home);
  while (xyMove.moving()) { }
  delay(1000);
}

📝 Note: A synchronized move can only start when all the axes in the group are standing still, and you should not command an individual axis while the group is moving.

Example 4: Homing to a Limit Switch

Limit switches let the controller find a known starting position. Connect a normally-open switch between the X limit header's Signal pin (D9) and GND. The sketch drives the X axis toward the switch, stops the instant it is pressed, backs off, and calls that spot position zero.

// CNC Shield V3 + UNO R4 - Homing the X Axis to a Limit Switch (MobaTools)
// Envistia Mall - envistiamall.com

#include <MobaTools.h>

const byte X_STEP = 2, X_DIR = 5;
const byte EN_PIN = 8;
const byte X_LIMIT = 9;

const int STEPS_PER_REV = 200 * 8;

MoToStepper stepperX(STEPS_PER_REV, STEPDIR);

void homeX() {
  stepperX.setMaxSpeed(400);            // slow and gentle for homing
  stepperX.setRampLen(0);               // no ramp
  stepperX.rotate(-1);                  // turn toward the switch (-1 = backward)
  while (digitalRead(X_LIMIT) == HIGH) { }   // HIGH = not pressed (pull-up)
  stepperX.stop();                      // stop immediately
  stepperX.setZero();                   // this spot is now position 0

  stepperX.doSteps(400);                // back off the switch
  while (stepperX.moving()) { }
  stepperX.setZero();                   // final zero, just clear of the switch
}

void setup() {
  pinMode(EN_PIN, OUTPUT);
  digitalWrite(EN_PIN, LOW);
  pinMode(X_LIMIT, INPUT_PULLUP);       // switch pulls the pin to GND when pressed

  stepperX.attach(X_STEP, X_DIR);
  homeX();

  // Normal moves from here on
  stepperX.setMaxSpeed(1000);
  stepperX.setRampLen(400);
}

void loop() {
  stepperX.moveTo(8000);                // 5 revolutions from home
  while (stepperX.moving()) { }
  delay(1000);
  stepperX.moveTo(0);
  while (stepperX.moving()) { }
  delay(1000);
}

⚠️ Warning: If the axis drives away from the switch instead of toward it, press the switch by hand or cut power right away. Then reverse the direction by adding INV_DIR to the attach line, or swap one motor coil's wires, before trying again. Test with the switch within easy reach the first time.

Tips for Smooth, Reliable Motion

  • Start slow — begin with 300–1000 steps per second and increase gradually. Stepper motors lose torque as speed rises, and a motor that cannot keep up will stall or skip steps.
  • Use a ramp — a ramp length of a quarter to a half revolution (400–800 steps at 1/8 microstepping) helps the motor start and stop without missing steps, especially with a load.
  • Keep your sketch responsive — because MobaTools works in the background, you can read sensors or buttons while the motors move. Avoid very long delay() calls if you need to react quickly.
  • Turn off the drivers when idle — with D8 LOW the motors hold position and stay warm. Set digitalWrite(EN_PIN, HIGH); when the machine is at rest to cut heat and power use. The motors will then be free to move by hand.
  • Stay within the limits — the default maximum step rate on the UNO R4 is 12,000 steps per second, and that figure is shared across all active steppers.

UNO R4 Troubleshooting

Error: "avr/io.h: No such file or directory"

  • You are trying to build GRBL or another AVR-only program for the R4. These programs are not compatible with the RA4M1 processor. Use MobaTools sketches instead, or switch to an UNO R3 or MEGA2560 for GRBL.

Motor stutters or runs erratically with an AccelStepper sketch

  • This is a known problem with AccelStepper on the UNO R4. Rewrite the sketch with MobaTools using the "Coming from AccelStepper?" table above.

Motor does not move

  • Confirm the enable pin (D8) is LOW and the 12–36V motor power supply is on.
  • Check the driver orientation (potentiometer toward the power terminals).
  • Make sure the correct board and port are selected in the Arduino IDE.

Motor moves the wrong distance

  • The STEPS_PER_REV value in your sketch does not match your microstepping jumpers or motor. Check the Steps per Revolution table above.

Motor hums, vibrates, or skips steps

  • Lower the speed, lengthen the ramp, and check that the driver's current limit (VREF) is set correctly for your motor.
  • Wrong coil wiring can also cause vibration. Try swapping the two wires of one coil.

Motor turns the wrong direction

  • Add INV_DIR to the attach line, for example stepperX.attach(X_STEP, X_DIR, INV_DIR);, or swap the two wires of one coil.

⚡ Power Supply Requirements

Supply Source Voltage Purpose
Logic Power Arduino USB or VIN 5V Powers the Arduino and shield logic
Motor Power Screw terminals on shield 12–36V DC Powers all stepper motors via the drivers

Important Power Notes

  • Use an adequate power supply. Each NEMA 17 motor can draw 0.5–2A. With four motors, you may need a supply rated for 5A or more at 12V.
  • Do NOT power the motors from the Arduino's 5V rail. The screw terminals on the shield provide a separate motor power path.
  • A 12V 5A–10A power supply is recommended for most 3-axis CNC setups with NEMA 17 motors.
  • ATX computer power supplies work well — use the 12V rail and connect the GND.
  • The shield does not have a built-in voltage regulator for the motor supply — the voltage goes directly to the driver modules.

⚠️ Never exceed 35V when using A4988 drivers, or 45V when using DRV8825 drivers.


🌡️ Thermal Considerations

  • Always install the included heatsinks on the A4988 driver chips before use.
  • For sustained operation at higher currents (above 1A per phase), add a small cooling fan directed at the driver modules.
  • If drivers are overheating, reduce the current limit (VREF) on the A4988 potentiometer.
  • Ensure adequate ventilation around the shield in any enclosure.

❓ Troubleshooting

No motors move

  • Verify the 12–36V motor power supply is connected and turned on.
  • Check that the Enable pin (D8) is LOW. In GRBL, motors are enabled automatically. In custom Arduino code, add digitalWrite(8, LOW);.
  • Confirm the A4988 drivers are inserted in the correct orientation (potentiometer toward power terminals).
  • Ensure GRBL firmware is properly uploaded to the Arduino.

Only some axes move

  • Check that a driver module is installed in the socket for the non-working axis.
  • Verify the motor is properly connected to the correct axis header.
  • Test the driver by swapping it with a known working driver from another axis.

Motors vibrate but don't rotate

  • The coil wires are swapped. Try swapping the two wires of one coil at the motor header.
  • The current limit (VREF) may be too low — increase it slightly on the A4988 potentiometer.

Motors are very hot

  • The current limit is set too high. Reduce the VREF on the A4988 driver. Stepper motors do get warm during normal operation, but they should not be too hot to touch.

GRBL doesn't respond

  • Verify the correct COM port is selected in your serial terminal software.
  • Set the baud rate to 115200.
  • Try pressing the Reset button on the Arduino.
  • Re-upload the GRBL firmware.

Limit switches don't work

  • Verify wiring: one switch terminal to Signal, the other to GND.
  • Enable hard limits in GRBL: $21=1.
  • Enable homing: $22=1.
  • Test the switch by manually triggering it and checking the signal with ? status report in GRBL.

A4988 driver burns out

  • The driver was likely inserted backwards — always verify the potentiometer faces the power terminals.
  • The motor was connected or disconnected while powered — always power off before changing motor connections.
  • The motor supply voltage exceeded 35V (including voltage spikes).
  • No decoupling capacitor — while the shield has some onboard capacitance, adding a 100µF electrolytic capacitor across the motor power terminals is recommended for additional protection.

⚠️ Important Safety Warnings

  1. Verify driver orientation before powering on. Inserting an A4988 or DRV8825 backwards will destroy it immediately.
  2. Never connect or disconnect stepper motors while the shield is powered. Always turn off the power supply first.
  3. Do not exceed the voltage rating of your driver modules (35V for A4988, 45V for DRV8825).
  4. Set the current limit (VREF) before running motors to prevent overheating.
  5. Use an appropriately rated power supply for the total current draw of all motors.
  6. Keep hands and loose clothing away from moving CNC components during operation.
  7. Wear safety glasses when operating CNC routers or laser engravers.

🏪 Where to Buy

Buy the A4988 CNC Expansion Shield at Envistia Mall.

Buy Now
  • 📦 Fast US Shipping
  • 🔄 Hassle-Free Returns
  • 📧 Responsive Customer Support

📚 References and Additional Resources

Envistia Mall Guides

Firmware and Software

Hardware References

Community and Learning

  • GRBL Wiki — Comprehensive GRBL documentation

This guide is provided by Envistia Mall for educational and technical reference purposes. The manufacturer and Envistia LLC (dba Envistia Mall) are not responsible for any damages or losses resulting from the use of this product. Always follow proper electrical safety practices when working with electronic components. Specifications are based on manufacturer data and are subject to change without notice.

Share this guide:
in

🛒 Related Products

Find the components mentioned in this guide in our store.

Browse Products →