
Ever had a stepper motor that just… kept going? Or worse, crashed into the end of its track like a runaway train? Yeah, we’ve all been there. That’s where limit switches come in—tiny, lever-style buttons that tell your stepper motor when to stop, reset, and change direction. In this Arduino tutorial, we’ll wire up a NEMA 17 stepper motor, hook it to an Arduino, and use limit switches to give it some boundaries (because even robots need rules).
- Build & Code Along With Me
- What is a Limit Switch?
- Limit Switch Pins: Normally Open (NO) vs. Normally Closed (NC)
- How to Wire a Stepper Motor, A4988 and Limit Switch to Arduino
- Arduino Code Example 1: Stop the Stepper Motor with a Limit Switch
- Arduino Code Example 2: Change Direction Using Two Limit Switches
- Arduino Code Example 3: Homing the Stepper Motor Before Starting the Loop
- Mastering Limit Switches: What’s Next?
Now, in this stepper motor tutorial, we’re focusing exclusively on integrating limit switches—how to wire them, write the code to detect when they’re triggered, and use them for homing, stopping, and direction control.
If this is your first time using a stepper motor with Arduino, or if you need a refresher on wiring, setting the current limit, check out my dedicated guide to controlling a NEMA 17 stepper motor with an A4988 and Arduino:
Recommended Reading:
Control NEMA 17 with A4988: Arduino Wiring & Code Guide
What is a Limit Switch?
A limit switch is a compact mechanical switch used to detect the position of a moving object—like a stepper motor, a robotic arm, or even an elevator. When the moving part reaches a predefined point, the switch is physically pressed, sending an electrical signal to stop, change direction, or trigger an action.
Why is this useful? Well, it gives your stepper motor a reliable way to know when to stop, reset, or change direction—something that counting steps alone can’t guarantee.
Why limit switches are a great addition to your Arduino stepper motor projects:
- Prevents Overtravel & Damage: Without a limit switch, a stepper motor can keep running until it slams into the end of its track, potentially damaging itself, your project, or both. A limit switch acts as a safety stop, preventing collisions before they happen.
- Ensures Accurate Homing: Ever turned off your project, powered it back on, and had no clue where the motor was supposed to start? Limit switches allow for repeatable homing, setting a precise “zero” position every time your system boots up.
- Compensates for Missed Steps: Stepper motors don’t have built-in feedback, so if they miss steps due to friction, resistance, or unexpected obstacles, they can drift out of alignment. A limit switch provides a physical reference point to recalibrate, keeping movements precise.
- Enables Automatic Direction Changes: Need your motor to move back and forth automatically? A limit switch can detect when it reaches the end of its travel and trigger a direction change, perfect for things like CNC machines, robotic arms, and conveyor belts.
- Works as a Failsafe: Sometimes, things don’t go as planned—code bugs out, sensors fail, or power fluctuations cause erratic behavior. A limit switch provides a hardware-level safety feature, making sure your system doesn’t run wild if something goes wrong.
Without them, your motor is just guessing where it is—and that rarely ends well!
Limit Switch Pins: Normally Open (NO) vs. Normally Closed (NC)
A limit switch typically has three pins:
- Common (COM) – The main connection point, like the “hub” of the switch.
- Normally Open (NO) – A pin that connects to COM only when the switch is pressed.
- Normally Closed (NC) – A pin that connects to COM when the switch is NOT pressed and disconnects when it’s pressed.

Which Pin Should You Use?
- Use NO when you want the circuit to activate only when the switch is pressed (safer from electrical noise).
- Use NC when you need a failsafe mechanism, so if the wire disconnects or the switch fails, the system detects it as a stop signal.
When it comes to Arduino projects, the NO configuration is the most common so that’s what we’ll use for the examples below.
How to Wire a Stepper Motor, A4988 and Limit Switch to Arduino
Before we jump into the wiring, a quick note: I’ve already covered stepper motor wiring in detail in my dedicated guide on controlling a NEMA 17 stepper motor with an A4988 and Arduino. So here, I’ll briefly go over the necessary connections and focus more on integrating the limit switch into the circuit.
For a step-by-step breakdown of how to identify your stepper motor wires and wiring the stepper motor and A4988 driver to an Arduino, check out this tutorial:
Recommended Reading:
Control NEMA 17 with A4988: Arduino Wiring & Code Guide
Now, let’s get into wiring everything together!

Step 1: Wire the Stepper Motor to the A4988
The NEMA 17 stepper motor has four wires, which connect to the A4988 motor driver like this:
- Stepper Coil 1 → A4988 Motor Output 1A & 1B
- Stepper Coil 2 → A4988 Motor Output 2A & 2B
| STEPPER MOTOR | A4988 |
|---|---|
| Coil 1, Wire A | 1A |
| Coil 1, Wire B | 1B |
| Coil 2, Wire A | 2A |
| Coil 2, Wire B | 2B |
If your motor runs in the wrong direction, swap the wires of one coil (e.g., switch 1A and 1B).
Step 2: Wire the A4988 to the Arduino
The A4988 stepper motor driver only needs two connections to the Arduino to control the stepper motor.
- DIR: Controls direction (clockwise or counter-clockwise)
- STEP: Controls motor movement
| A4988 MOTOR DRIVER | ARDUINO UNO |
|---|---|
| DIR | 2 |
| STEP | 3 |
A4988 to A4988 Driver Module Connections
- Connect the RST and SLP pins of the A4988 driver module together. This prevents the motor driver from going into sleep mode.
Step 3: Power the A4988 Driver and Stepper Motor
The A4988 motor driver module can be powered directly from the Arduino.
| A4988 MOTOR DRIVER | ARDUINO UNO |
|---|---|
| VDD | 5V |
| GND | GND |
IMPORTANT: Set the current limit on the A4988 motor driver so that it matches the current rating of your stepper motor before powering it. Don’t skip this step! Otherwise, your stepper motor may get too much current, overheat and potentially get damaged.
Don’t know how to set the current limit on an A4988 motor driver? Check out my beginner-friendly step-by-step guide:
Control NEMA 17 with A4988: Arduino Wiring & Code Guide
After you’ve set the current limit, connect a 12V-24V power supply (depending on your stepper motor specs) to the A4988 motor driver.
| A4988 MOTOR DRIVER | POWER SUPPLY |
|---|---|
| VMOT | Positive |
| GND | Negative |
IMPORTANT: Add a 100µF capacitor between VMOT and GND near the A4988 pins to prevent voltage spikes.
Step 4: Wire the Limit Switches to the Arduino
We’ll only be using one limit switch for first code example and then add the other one after that, but we might as well get both limit switches wired up now.
| LIMIT SWITCH | ARDUINO UNO |
|---|---|
| COM (Common) for both Limit Switches | GND |
| NO (Normally Open) of Limit Switch 1 | 7 |
| NO (Normally Open) of Limit Switch 2 | 8 |
In the Arduino code examples below, we’ll be using the built-in pull-up resistor of the Arduino so there’s no need to add an external 10kΩ pull-up or pull-down resistor for either switch in the circuit.
Once everything is wired up, it’s time to write the code to detect limit switch presses and control the stepper motor accordingly. Let’s move on to the fun part—coding!
Arduino Code Example 1: Stop the Stepper Motor with a Limit Switch
This basic example stops the motor when a limit switch is pressed.
How This Arduino Sketch Works
- The motor continuously steps in the initial direction.
- We use a simple flag called
movingto decide if the motor should keep going. - The program constantly checks the limit switch: if it’s pressed (LOW), the motor stops immediately by setting
movingtofalse. - While
movingis stilltrue, the sketch sends a step pulse: a quickHIGHon the step pin, a short pause, aLOW, and another pause.
Arduino Code Explanation
Let’s walk through each line of the code so you can understand exactly how everything works—even if you’re new to Arduino.
Pin Assignments
const int dirPin = 2;
const int stepPin = 3;
const int limit1Pin = 7;
We start by telling the Arduino which pins control the motor and the limit switch. The dirPin sets the motor’s direction, stepPin sends step signals to move the motor, and limit1pin is hooked up to our safety stop—also known as a limit switch.
Motor Speed and Movement Flag
int motorSpeed = 5000;
bool moving = true;
Here, motorSpeed sets how quickly the motor turns. Smaller numbers mean faster stepping. The moving flag decides if the motor should keep running—this is where we’ll use the limit switch to stop the motor!
The Setup()
void setup() {
pinMode(dirPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(limit1Pin, INPUT_PULLUP);
digitalWrite(dirPin, HIGH);
delay(5000);
}
The setup() function runs once when the Arduino starts. Here’s what happens:
- We set the
dirPinandstepPinas outputs to control the motor. - The
limit1Pinis set as an input with a pull-up resistor, which keeps it HIGH when not pressed. - We choose the motor’s initial direction by sending
HIGHto thedirPin. - And finally, we pause for 5 seconds—giving you a moment to make sure everything’s ready before the motor starts.
The Loop()
void loop() {
if (digitalRead(limit1Pin) == LOW) {
moving = false;
}
if (moving) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(stepPin, LOW);
delayMicroseconds(motorSpeed);
}
}
The loop() function runs over and over again. Here’s what it does:
- It checks the limit switch. If the switch is pressed (LOW),
movingis set tofalse—stopping the motor. - If the
movingflag is stilltrue, we send a pulse to the stepper motor: a quickHIGH, a short pause, aLOW, and another pause. This simple pattern keeps the motor stepping until the limit switch is triggered.
This sketch is a great starting point for adding basic emergency stop or end-of-travel features to your Arduino stepper motor projects. As soon as the limit switch is hit, the motor stops safely—no libraries or fancy coding needed!
Arduino Code Example 2: Change Direction Using Two Limit Switches
This example shows how to make your stepper motor change direction automatically using two limit switches. It’s a great way to create an automated back-and-forth motion—perfect for CNC machines, sliding doors, or any project that needs the motor to reverse when it hits the end of its path.
How The Arduino Sketch Works
- The motor runs continuously in the current direction.
- If it hits the limit switch 1, it waits 5 seconds, then reverses to move in the opposite direction.
- If it hits the limit switch 2, it waits 5 seconds and switches back the other way.
Arduino Code Explanation
Let’s break down how this code makes the stepper motor change direction using two limit switches, focusing on what’s new and different compared to the first example. This way, you’ll see exactly how these tweaks can be customized to your project!
const int limit2Pin = 8;
We added a second limit switch pin to handle movement in both directions.
bool direction = true;
Instead of a single moving flag, we now track the direction of the motor.
digitalWrite(dirPin, direction);
This sets the direction pin to the current direction (forward or backward). direction can be either HIGH (true) or LOW (false), telling the motor to rotate one way or the other.
bool ignoreLimit1 = false;
bool ignoreLimit2 = false;
These new variables prevent the motor from instantly stopping at a limit switch it has just reversed away from. Why? When a switch stays pressed, we don’t want to stop again immediately!
if (!ignoreLimit1 && direction && digitalRead(limit1Pin) == LOW) {
delay(5000);
direction = !direction;
digitalWrite(dirPin, direction);
ignoreLimit1 = true;
}
This new block replaces the simple if (digitalRead(limit1pin) == LOW) check. It only triggers if:
- The motor is moving towards Limit 1 (
directionistrue) - Limit 1 is pressed
- We’re not ignoring this switch
It pauses for 5 seconds, then reverses direction (direction = !direction) and starts ignoring Limit 1.
if (!ignoreLimit2 && !direction && digitalRead(limit2Pin) == LOW) {
delay(5000);
direction = !direction;
digitalWrite(dirPin, direction);
ignoreLimit2 = true;
}
This is the same logic for Limit 2 but for the opposite direction!
if (ignoreLimit1 && digitalRead(limit1Pin) == HIGH) {
ignoreLimit1 = false;
}
Once the motor has moved off the limit switch, this resets the ignoreLimit1 flag. This ensures it can stop next time it hits the switch!
digitalWrite(stepPin, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(stepPin, LOW);
delayMicroseconds(motorSpeed);
No need for if (moving) anymore! The motor always steps in the current direction — and the limit switch logic handles when to pause and reverse.
Arduino Code Example 3: Homing the Stepper Motor Before Starting the Loop
In this example, I’ll show you how to home your stepper motor using a single limit switch. Homing makes sure your motor starts from a known position before moving on with the rest of the program.
How This Sketch Works
- In
setup(), the motor moves toward the home switch by continuously stepping in one direction. - When the switch is pressed (LOW), homing is complete, and the direction is reversed.
- The program then enters the
loop(), where it keeps moving in the other direction.
Arduino Code Explanation
Let’s break down how this homing sketch differs from the earlier examples. I’ll focus on the unique parts that handle the homing process so your motor starts from the right spot every time!
bool homingComplete = false;
I’ve added a new flag to track whether the homing process is done. This ensures the main loop only runs after homing is complete.
Serial.begin(9600);
I’m using Serial.begin() to start the serial monitor, so we can see status messages (like “Homing complete”) as the program runs.
Serial.println("Starting homing...");
This line prints a message to the Serial Monitor to let you know the motor is starting the homing routine.
digitalWrite(dirPin, LOW);
Before starting the homing loop, we set the motor’s direction toward the limit switch.
while (digitalRead(limit1Pin) == HIGH) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(stepPin, LOW);
delayMicroseconds(motorSpeed);
}
This while loop continuously steps the motor until the home switch is triggered (LOW). While it’s HIGH (not pressed), the motor keeps moving toward the switch.
Serial.println("Homing complete. Starting main loop...");
homingComplete = true;
After the switch is pressed, we print a message and set the homingComplete flag to true.
digitalWrite(dirPin, HIGH);
Once homing is done, we change the direction of the motor to prepare for normal operation in the main loop.
if (homingComplete) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(stepPin, LOW);
delayMicroseconds(motorSpeed);
}
In the main loop, the motor only runs if homingComplete is true. This ensures that homing has happened before anything else starts.
Mastering Limit Switches: What’s Next?
With these examples, you’re all set to add reliable limit switch control to your Arduino stepper motor projects—perfect for CNCs, sliders, and more. Whether you’re stopping your motor safely, reversing direction, or setting up a homing routine, these Arduino sketches make it easy to add precision and reliability.
Ready to take it even further? Try adding more switches, sensors, or dynamic controls to create your ultimate motor setup!
