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){}
}
2 Answers 2
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:
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);
When reading the limit switch inside the outer
for
loop you writeif (digitalRead(Lim1 == OFF)){}
You are doing the equality comparison between
OFF
and the pin number and not betweenOFF
and the return value ofdigitalRead()
. 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.303jw1095– 303jw10952022年12月20日 17:35:08 +00:00Commented 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++) {
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");
}
-
1As 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.2022年12月20日 21:53:34 +00:00Commented Dec 20, 2022 at 21:53
// These four lines result in 1 revolution:
... that should say// These six lines result in 1 step: