# Using a limit switch to stop a stepper motor

I am building a machine with a moving bed, the bed moves forward and backward. I need to incorporate a limit switch at the two ends that makes sure the motors stop at the two extremes. I have 2 stepper motors controlled by TB6600 motor drivers, I am trying to start with 1 limit switch (SS-5Gl2) and advance from there.

My 1st question is how I get the code to stop steppers if limit switch is closed?

``````// Define stepper motor connections and steps per revolution:
#define dirPin1 2
#define stepPin1 3
#define dirPin2 5
#define stepPin2 6
#define stepsPerRevolution 200 // We may need to change 200 to 1600 to get more precise control, i.e. decimals verse integers

#define Lim1 8

int direction = 0;
int remainder = 0;
long travel = 0;
long revolutions = 0;

void setup() {

// Declare pins as output:
pinMode(stepPin1, OUTPUT);
pinMode(dirPin1, OUTPUT);
pinMode(stepPin2, OUTPUT);
pinMode(dirPin2, OUTPUT);

pinMode(Lim1, OUTPUT);

//Desired travel distance, in mm !!!! set here !!!!
travel = 1;
//Desired direction !!!! set here !!!! move die in(ccw) = 1, back out(cw) = 0 !!!!
//direction = 0; did not work, need boolean?

// Set the spinning direction counterclockwise (die in) or clockwise (die out):
//if(direction = 1) digitalWrite(dirPin, HIGH);
//if(direction = 0) digitalWrite(dirPin, LOW);

//set direction manually, uncomment HIGH for die in, LOW for die back out
digitalWrite(dirPin1, LOW);
digitalWrite(dirPin2, LOW);
//digitalWrite(dirPin, LOW);

digitalWrite(Lim1, OFF) //

//calculating number of revolutions based on mm input. Does not yet account for partial revs - variable is truncated, integers are default. Would need another loop to handle the remainder
//6.659 (microns) constant is based on 1.25mm acutator screw pitch, and ratio in gearbox
revolutions = 1000.00*travel/6.659;
//attempt to output the stored value to PC for debug purposes

Serial.print("revolutions = ");
Serial.print(revolutions,4);
}

void loop() {

// Spin the stepper motor X revolutions fast, speed (delay) apparently limited by voltage. 42v should go faster?
//Required a nested loop because integers on the UNO are limited to ~32k
for (int i = 0; i < revolutions; i++) {

else {
for (int j = 0; j < stepsPerRevolution; j++) {
// These four lines result in 1 revolution:
digitalWrite(stepPin1, HIGH);
digitalWrite(stepPin2, HIGH);
delayMicroseconds(250);
digitalWrite(stepPin1, LOW);
digitalWrite(stepPin2, LOW);
delayMicroseconds(250);
}
}
}

while(1){}

}
``````
• `// These four lines result in 1 revolution:` ... that should say `// These six lines result in 1 step:` Dec 20, 2022 at 18:10

You are doing every step manually directly via `digitalWrite()`, so the principal would be to read the limit switch pin on every iteration of the inner `for` loop in an `if` statement. What to do in that `if` statement depends on what you want to do on hitting the limit switch. Currently you have an infinite empty loop after your motor code. So if you want to stop forever in that case you can create another infinite loop there. So something like this:

``````...
for (int j = 0; j < stepsPerRevolution; j++) {
while(true);
}
// These four lines result in 1 revolution:
digitalWrite(stepPin1, HIGH);
digitalWrite(stepPin2, HIGH);
delayMicroseconds(250);
digitalWrite(stepPin1, LOW);
digitalWrite(stepPin2, LOW);
delayMicroseconds(250);
}
``````

Note that this assumes that you have connected the limit switch to ground and use the digital pin with a pullup resistor.

But you have 2 other problems with your limit switch code:

1. You set your limit switch pin `Lim1` as output, though to read a switch you need to configure it as input. And if you want to use a pullup resistor (in contrast to a pulldown resistor) you can activate the internal pullup in the same step:

`````` pinMode(Lim1, INPUT_PULLUP);
``````
2. When reading the limit switch inside the outer `for` loop you write

`````` if (digitalRead(Lim1 == OFF)){}
``````

You are doing the equality comparison between `OFF` and the pin number and not between `OFF` and the return value of `digitalRead()`. You need to place the parentheses here correctly:

`````` if(digitalRead(Lim1) == OFF){}
``````

Above I used the equivalent form

`````` if(!digitalRead(Lim1)){}
``````

with the negation operator `!`

Besides that you are missing the `Serial.begin()` with the baudrate, that you want to use, in `setup()`.

• Thank you for your answer, I am really new and completely confused. Dec 20, 2022 at 17:35
``````// Define stepper motor connections and steps per revolution:
#define dirPin1 5
#define stepPin1 2
#define dirPin2 6
#define stepPin2 3
#define stepsPerRevolution 200 // We may need to change 200 to 1600 to
get more precise control, i.e. decimals verse integers'
#define limPin1 8
#define CW 0x1
#define CCW 0x0

int remainder = 0;
long travel = 0;
long revolutions = 0;
bool homed = false;

void setup() {

// Declare pins as output:
pinMode(stepPin1, OUTPUT);
pinMode(dirPin1, OUTPUT);
pinMode(stepPin2, OUTPUT);
pinMode(dirPin2, OUTPUT);
pinMode(limPin1, INPUT_PULLUP);

//Desired direction !!!! set here !!!! move die in(ccw) = 1, back
out(cw) = 0 !!!!
//direction = 0; did not work, need boolean?

// Set the spinning direction counterclockwise (die in) or clockwise
(die out):
//if(direction = 1) digitalWrite(dirPin, HIGH);
//if(direction = 0) digitalWrite(dirPin, LOW);

//set direction manually, uncomment HIGH for die in, LOW for die back
out
digitalWrite(dirPin1, LOW);
digitalWrite(dirPin2, LOW);

//attempt to output the stored value to PC for debug purposes
Serial.begin(9600);
Serial.println("test");
}

//main routine
void loop() {
Homing();
}

void Homing() {
// Spin the stepper motor X revolutions fast, speed (delay)
apparently limited by voltage. 42v should go faster?
//Required a nested loop because integers on the UNO are limited to
~32k
if (homed == false)
{
//calculating number of revolutions based on mm input. Does not yet
account for partial revs - variable is truncated, integers are
default.
Would need another loop to handle the remainder
//6.659 (microns) constant is based on 1.25mm acutator screw
pitch,
and ratio in gearbox
float travel = 2.0;
float revolutions = 1000.00*travel/6.659;
int totalStepsOut = revolutions * stepsPerRevolution;
Serial.print("revolutions = ");
Serial.println(revolutions,4);
digitalWrite(dirPin1, CCW);
digitalWrite(dirPin2, CCW);
for (int j = 0; j < totalStepsOut; j++) {
if (limState == false)
{
//Limit is triggered
HomingReturn();
break;
}
else
{
//Limit is not triggered
// These six lines result in 1 revolution:
digitalWrite(stepPin1, HIGH);
digitalWrite(stepPin2, HIGH);
delayMicroseconds(250);
digitalWrite(stepPin1, LOW);
digitalWrite(stepPin2, LOW);
delayMicroseconds(250);
}
}
}
//Add stuff here to do whatever you want after homing
Serial.println("Homed");
}

void HomingReturn()
{
//set direction for reverse
digitalWrite(dirPin1, CW);
digitalWrite(dirPin2, CW);
Serial.println("Reversing");
//Desired travel distance, in mm !!!! set here !!!!
float travel = 0.1;
float revolutions = 1000.00*travel/6.659;
int totalStepsOut = revolutions * stepsPerRevolution;
for (int j = 0; j < totalStepsOut; j++) {
//drive back
digitalWrite(stepPin1, HIGH);
digitalWrite(stepPin2, HIGH);
delayMicroseconds(250);
digitalWrite(stepPin1, LOW);
digitalWrite(stepPin2, LOW);
delayMicroseconds(250);
}
homed = true;
Serial.println("Done");
}
``````