I need to put 2 limit switches on a stepper motor, There is a pot connected to the motor that controls speed and direction. I just want to stop it when it reaches a point in either direction but allow it to go back the opposite direction. This code works well for 2 different motors, I'm not sure how to add something like this in the code. I appreciate any good advice.
if right limit switch is hit stop motor from continuing right but allow to go left.
if left limit switch is hit stop motor from continuing left but allow to go right.
#include <AccelStepper.h> //accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)
AccelStepper stepper2(1, 10, 11); // direction Digital 11 (CCW), pulses Digital 10 (CLK)
//Pins
const byte Analog_X_pin = A0; //x-axis readings
const byte Analog_Y_pin = A1; //y-axis readings
//Variables
int Analog_X = 0; //x-axis value
int Analog_Y = 0; //y-axis value
int Analog_X_AVG = 0; //x-axis value average
int Analog_Y_AVG = 0; //y-axis value average
void setup()
{
//SERIAL
Serial.begin(9600);
//----------------------------------------------------------------------------
//PINS
pinMode(Analog_X_pin, INPUT);
pinMode(Analog_Y_pin, INPUT);
//----------------------------------------------------------------------------
InitialValues(); //averaging the values of the 3 analog pins (values from potmeters)
//----------------------------------------------------------------------------
//Stepper parameters
//setting up some default values for maximum speed and maximum acceleration
stepper.setMaxSpeed(5000); //SPEED = Steps / second
stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2
stepper.setSpeed(500);
delay(500);
//----------------------------------------------------------------------------
stepper2.setMaxSpeed(5000); //SPEED = Steps / second
stepper2.setAcceleration(1000); //ACCELERATION = Steps /(second)^2
stepper2.setSpeed(500);
delay(500);
}
void loop()
{
ReadAnalog();
stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
stepper2.runSpeed();
}
void ReadAnalog()
{
//Reading the 3 potentiometers in the joystick: x, y and r.
Analog_X = analogRead(Analog_X_pin);
Analog_Y = analogRead(Analog_Y_pin);
//if the value is 25 "value away" from the average (midpoint), we allow the update of the speed
//This is a sort of a filter for the inaccuracy of the reading
if(abs(Analog_X-Analog_X_AVG)>25)
{
stepper.setSpeed(5*(Analog_X-Analog_X_AVG));
}
else
{
stepper.setSpeed(0);
}
//----------------------------------------------------------------------------
if(abs(Analog_Y-Analog_Y_AVG)>25)
{
stepper2.setSpeed(5*(Analog_Y-Analog_Y_AVG));
}
else
{
stepper2.setSpeed(0);
}
}
void InitialValues()
{
//Set the values to zero before averaging
float tempX = 0;
float tempY = 0;
//----------------------------------------------------------------------------
//read the analog 50x, then calculate an average.
//they will be the reference values
for(int i = 0; i<50; i++)
{
tempX += analogRead(Analog_X_pin);
delay(10); //allowing a little time between two readings
tempY += analogRead(Analog_Y_pin);
delay(10);
}
//----------------------------------------------------------------------------
Analog_X_AVG = tempX/50;
Analog_Y_AVG = tempY/50;
//----------------------------------------------------------------------------
Serial.print("AVG_X: ");
Serial.println(Analog_X_AVG);
Serial.print("AVG_Y: ");
Serial.println(Analog_Y_AVG);
Serial.println("Calibration finished");
}
Make sure in the code you know which direction you are trying to move, then use that
to choose which of the two sensors to read in your loop.
If the sensor trips call stepper.stop(), and record the fact you are not trying to move in
either direction.
Before trying to move check the sensors to see if you are at one of the limits.
I'd strongly advise reading up on state-machines and use one - you have several
obvious states in such a system, such as idle, moving left, moving right, at left limit,
at right limit....
If I understand the runSpeed() function, it does not step unless you call it (i.e. it is polling/non-blocking). Just check the limit switch to see if it has changed states from open to closed and don't allow stepping in that direction (test the sign of the speed) while the switch is closed. When the switch is open then allow stepping in both directions.
It usually best to use run(), move/moveTo() and stop() only for position control. runSpeed etc are not position control. currentPosition() is of course useful for monitoring!
I don't want it to move to and stop, I only want it to stop when it hits the end of the track, and be able to go in the opposite direction, once the switch is open again then be able to go in either direction.
kayakbill:
I don't want it to move to and stop, I only want it to stop when it hits the end of the track, and be able to go in the opposite direction, once the switch is open again then be able to go in either direction.
That is impossible. Once a limit switch is engaged by an end-of-travel, it should and will remain engaged. If there are momentary limit switches, they must be extremely rare.
Surly there's a way to simply stop the motor from moving right when right switch is triggered, and stop moving left when left switch is triggered. That's all it needs
kayakbill:
Surly there's a way to simply stop the motor from moving right when right switch is triggered, and stop moving left when left switch is triggered. That's all it needs
Google, "limit switch". The answer to your question was given in reply #2.
"check the limit switch to see if it has changed states from open to closed and don't allow stepping in that direction"
aarg:
Google, "limit switch". The answer to your question was given in reply #2.
"check the limit switch to see if it has changed states from open to closed and don't allow stepping in that direction"
That logic makes it simple in that you ignore analog inputs that request stepping toward the limit switch. When an input is received that requests stepping away from the switch then as soon as the switch is open just start processing both directions.
kayakbill:
check the limit switch to see if it has changed states from open to closed and don't allow stepping in that direction
where does this go in the code
I would put it after ReadAnalog(). You will only call runSpeed() functions based on the corresponding limit switch state and step direction.
Also since you know that both limit switches on the same axis cannot be closed at the same time I would check for that so you can detect any sort of hardware error.
Thanks, I was just watching a video on hall effect end stops for a 3d printer. I think that's exactly what I need. I just don't work with code enough to know how to word it or where to put it.
kayakbill:
Thanks, I was just watching a video on hall effect end stops for a 3d printer. I think that's exactly what I need. I just don't work with code enough to know how to word it or where to put it.
Well, inline code is executed sequentially. So you put it after the first place where you can obtain the conditions you are testing for, and before the place where it's too late to use it.
There's no way to circumvent "design". If it was easy, nobody would be on this forum.