0

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++) {


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


   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){}
  
}
1
  • // These four lines result in 1 revolution: ... that should say // These six lines result in 1 step:
    – jsotola
    Dec 20, 2022 at 18:10

2 Answers 2

0

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++) {
   if(!digitalRead(Lim1)){
       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().

1
  • Thank you for your answer, I am really new and completely confused.
    – 303jw1095
    Dec 20, 2022 at 17:35
-1
// 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++) {
      bool limState = digitalRead(limPin1);
      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");
   }
1
  • 1
    As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Dec 20, 2022 at 21:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.