Arduino Nano - Stepper Motor Limit Switch

This tutorial instructs you how to use Arduino Nano to control a stepper motor via a limit switch and an L298N driver. Specifically, we will cover:

Hardware Preparation

1×Arduino Nano
1×USB A to Mini-B USB cable
1×Limit Switch (KW12-3)
1×Limit Switch (V-156-1C25)
1×Stepper Motor Nema 17
1×L298N Motor Driver Module
1×12V Power Adapter
1×DC Power Jack
1×Jumper Wires
1×(Optional) 9V Power Adapter for Arduino Nano
1×(Recommended) Screw Terminal Adapter for Arduino Nano

Or you can buy the following sensor kit:

1×DIYables Sensor Kit 30 types, 69 units
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you. We appreciate your support.

Overview of Stepper Motor and Limit Switch

If you are unfamiliar with stepper motor and limit switch (including pinout, functionality, and programming), the following tutorials can help you learn:

Wiring Diagram

This tutorial provides the wiring diagram for two cases: One stepper motor + one limit switch, One stepper motor + two limit switches.

  • Wiring Diagram between ESP8266, stepper motor and, and a limit switch.
The wiring diagram between Arduino Nano and stepper motor and limit switch

This image is created using Fritzing. Click to enlarge image

  • Wiring Diagram between ESP8266, stepper motor and, and two limit switches.
The wiring diagram between Arduino Nano and stepper motor and two limit switches

This image is created using Fritzing. Click to enlarge image

※ NOTE THAT:

The wiring connection between the stepper motor and L298N can vary depending on the type of stepper motor. To ensure a successful connection, please refer to the Arduino Nano - Stepper Motor tutorial for instructions on how to connect the stepper motor to the L298N motor driver.

Arduino Nano Code - Stop Stepper Motor by a Limit Switch

One can stop a stepper motor in several ways:

  • Invoke the stepper.stop() function: This will not bring the motor to an immediate stop, but will cause it to decelerate gradually
  • Do not call the stepper.run() function: This will cause the stepper motor to come to a stop immediately

The code below causes a stepper motor to spin continuously until a limit switch is touched.

/* * This Arduino Nano code was developed by newbiely.com * * This Arduino Nano code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano/arduino-nano-stepper-motor-limit-switch */ #include <ezButton.h> #include <AccelStepper.h> #define MAX_POSITION 0x7FFFFFFF // maximum of position we can set (long type) ezButton limit_switch(5); // create ezButton object for pin D5 AccelStepper stepper(AccelStepper::FULL4WIRE, A3, A2, A1, A0); bool is_stopped = false; void setup() { Serial.begin(9600); limit_switch.setDebounceTime(50); // set debounce time to 50 milliseconds stepper.setMaxSpeed(500.0); // set the maximum speed stepper.setAcceleration(50.0); // set acceleration stepper.setSpeed(100); // set initial speed stepper.setCurrentPosition(0); // set position stepper.moveTo(MAX_POSITION); } void loop() { limit_switch.loop(); // MUST call the loop() function first if (limit_switch.isPressed()) { Serial.println(F("The limit switch: TOUCHED")); is_stopped = true; } if (is_stopped == false) { // without this part, the move will stop after reaching maximum position if (stepper.distanceToGo() == 0) { // if motor moved to the maximum position stepper.setCurrentPosition(0); // reset position to 0 stepper.moveTo(MAX_POSITION); // move the motor to maximum position again } stepper.run(); // MUST be called in loop() function } else { // If the stepper.run() function is not invoked, the motor stops immediately // NOTE: invoking the stepper.stop() does NOT stop the motor immediately. Serial.println(F("The stepper motor is STOPPED")); } }

Detailed Instructions

  • Connect the Arduino Nano to a computer using a USB cable.
  • Open the Arduino IDE, choose the correct board and port.
  • Click to the Libraries icon on the left bar of the Arduino IDE.
  • Search for “ezButton” and locate the button library from ArduinoGetStarted.com.
  • Press the Install button to install the ezButton library.
Arduino Nano button library
  • Look for “AccelStepper” and locate the AccelStepper library created by Mike McCauley.
  • Then, press the Install button to add it.
Arduino Nano AccelStepper library
  • Copy the code above and open it in the Arduino IDE.
  • Click the Upload button in the Arduino IDE to compile and upload the code to the Arduino Nano.
  • If the wiring is correct, the motor should rotate in a clockwise direction.
  • When the limit switch is touched, the motor should stop immediately.
  • The result displayed on the Serial Monitor should look like this.
COM6
Send
The limit switch: TOUCHED The stepper motor is STOPPED The stepper motor is STOPPED The stepper motor is STOPPED The stepper motor is STOPPED
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Code Explanation

Check out the line-by-line explanation contained in the comments of the source code!

Arduino Nano Code - Change Direction of Stepper Motor by a Limit Switch

A stepper motor is made to spin continuously, and its direction is altered when a limit switch is touched. This is accomplished with the following code:

/* * This Arduino Nano code was developed by newbiely.com * * This Arduino Nano code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano/arduino-nano-stepper-motor-limit-switch */ #include <ezButton.h> #include <AccelStepper.h> #define DIRECTION_CCW -1 #define DIRECTION_CW 1 #define MAX_POSITION 0x7FFFFFFF // maximum of position we can set (long type) ezButton limit_switch(5); // create ezButton object for pin D5 AccelStepper stepper(AccelStepper::FULL4WIRE, A3, A2, A1, A0); int direction = DIRECTION_CW; long target_pos = 0; void setup() { Serial.begin(9600); limit_switch.setDebounceTime(50); // set debounce time to 50 milliseconds stepper.setMaxSpeed(500.0); // set the maximum speed stepper.setAcceleration(50.0); // set acceleration stepper.setSpeed(100); // set initial speed stepper.setCurrentPosition(0); // set position target_pos = direction * MAX_POSITION; stepper.moveTo(target_pos); } void loop() { limit_switch.loop(); // MUST call the loop() function first if (limit_switch.isPressed()) { Serial.println(F("The limit switch: TOUCHED")); direction *= -1; // change direction Serial.print(F("The direction -> ")); if (direction == DIRECTION_CW) Serial.println(F("CLOCKWISE")); else Serial.println(F("ANTI-CLOCKWISE")); target_pos = direction * MAX_POSITION; stepper.setCurrentPosition(0); // set position stepper.moveTo(target_pos); } // without this part, the move will stop after reaching maximum position if (stepper.distanceToGo() == 0) { // if motor moved to the maximum position stepper.setCurrentPosition(0); // reset position to 0 stepper.moveTo(target_pos); // move the motor to maximum position again } stepper.run(); // MUST be called in loop() function }

Detailed Instructions

  • Copy the code and open it with the Arduino IDE.
  • Click the Upload button in the IDE to upload the code to the Arduino Nano.
  • If the wiring is correct, the motor will rotate clockwise.
  • Touch the limit switch and the stepper motor's direction will be reversed to counterclockwise.
  • Touch the limit switch again and the stepper motor will turn clockwise.
  • The result on the Serial Monitor should look like this.
COM6
Send
The limit switch: TOUCHED The direction -> ANTI-CLOCKWISE The limit switch: TOUCHED The direction -> CLOCKWISE
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Arduino Nano Code - Change Direction of Stepper Motor by two Limit Switches

Make a stepper motor spin continuously and switch its direction when either of two limit switches is touched.

/* * This Arduino Nano code was developed by newbiely.com * * This Arduino Nano code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano/arduino-nano-stepper-motor-limit-switch */ #include <ezButton.h> #include <AccelStepper.h> #define DIRECTION_CCW -1 #define DIRECTION_CW 1 #define STATE_CHANGE_DIR 1 #define STATE_MOVE 2 #define STATE_MOVING 3 #define MAX_POSITION 0x7FFFFFFF // maximum of position we can set (long type) ezButton limit_switch_1(5); // create ezButton object for pin D5 ezButton limit_switch_2(12); // create ezButton object for pin D12 AccelStepper stepper(AccelStepper::FULL4WIRE, A3, A2, A1, A0); int stepper_state = STATE_MOVE; int direction = DIRECTION_CW; long target_pos = 0; void setup() { Serial.begin(9600); limit_switch_1.setDebounceTime(50); // set debounce time to 50 milliseconds limit_switch_2.setDebounceTime(50); // set debounce time to 50 milliseconds stepper.setMaxSpeed(500.0); // set the maximum speed stepper.setAcceleration(50.0); // set acceleration stepper.setSpeed(100); // set initial speed stepper.setCurrentPosition(0); // set position } void loop() { limit_switch_1.loop(); // MUST call the loop() function first limit_switch_2.loop(); // MUST call the loop() function first if (limit_switch_1.isPressed()) { stepper_state = STATE_CHANGE_DIR; Serial.println(F("The limit switch 1: TOUCHED")); } if (limit_switch_2.isPressed()) { stepper_state = STATE_CHANGE_DIR; Serial.println(F("The limit switch 2: TOUCHED")); } switch (stepper_state) { case STATE_CHANGE_DIR: direction *= -1; // change direction Serial.print(F("The direction -> ")); if (direction == DIRECTION_CW) Serial.println(F("CLOCKWISE")); else Serial.println(F("ANTI-CLOCKWISE")); stepper_state = STATE_MOVE; // after changing direction, go to the next state to move the motor break; case STATE_MOVE: target_pos = direction * MAX_POSITION; stepper.setCurrentPosition(0); // set position stepper.moveTo(target_pos); stepper_state = STATE_MOVING; // after moving, go to the next state to keep the motor moving infinity break; case STATE_MOVING: // without this state, the move will stop after reaching maximum position if (stepper.distanceToGo() == 0) { // if motor moved to the maximum position stepper.setCurrentPosition(0); // reset position to 0 stepper.moveTo(target_pos); // move the motor to maximum position again } break; } stepper.run(); // MUST be called in loop() function }

Detailed Instructions

  • Copy the above code and open it in the Arduino IDE.
  • Click the Upload button to send the code to the Arduino Nano.
  • If the wiring is correct, the motor should spin in a clockwise direction.
  • When you touch limit switch 1, the stepper motor's direction should be reversed to anti-clockwise.
  • When you touch limit switch 2, the stepper motor's direction should be changed back to clockwise.
  • The result on the Serial Monitor should look like this.
COM6
Send
The limit switch 1: TOUCHED The direction -> ANTI-CLOCKWISE The limit switch 2: TOUCHED The direction -> CLOCKWISE
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Video Tutorial