I need to add some end stops to this stepper motor code. I'm using one axis of a joystick to control a carriage that goes back and forth on a long screw. I have hall switches for both ends, I just want it to stop going in that direction when it triggers the switch. I didn't wright this code but it works great if I could just add the end stops. If I have the switches connected to pins 2 and 3, how could I wright something like; if pin 2 high, stop motor in that direction, and then the same for pin 3 in the opposite direction?
#include <AccelStepper.h> //accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)
//Pins
const byte Analog_X_pin = A0; //x-axis readings
const byte enablePin = 7;
//Variables
int Analog_X = 0; //x-axis value
int Analog_X_AVG = 0; //x-axis value average
//----------------------------------------------------------------------------
void setup()
{
Serial.begin(9600);
//----------------------------------------------------------------------------
//PINS
pinMode(Analog_X_pin, INPUT);
pinMode(enablePin, OUTPUT);
//----------------------------------------------------------------------------
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(2000); //SPEED = Steps / second
stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2
stepper.setSpeed(1000);
delay(1000);
}
void loop()
{
ReadAnalog();
stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}
void ReadAnalog()
{
if(abs(Analog_X-Analog_X_AVG)>50)
{
digitalWrite(enablePin, HIGH); // enable the driver
stepper.setSpeed(5*(Analog_X-Analog_X_AVG));
}
else
{
digitalWrite(enablePin, LOW); // disable the driver
stepper.setSpeed(0);
}
//Reading the potentiometer in the joystick:
Analog_X = analogRead(Analog_X_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)>50)
{
stepper.setSpeed(5*(Analog_X-Analog_X_AVG));
}
else
{
stepper.setSpeed(0);
}
}
void InitialValues()
{
//Set the values to zero before averaging
float tempX = 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
}
//----------------------------------------------------------------------------
Analog_X_AVG = tempX/50;
//----------------------------------------------------------------------------
Serial.print("AVG_X: ");
Serial.println(Analog_X_AVG);
Serial.println("Calibration finished");
}
bob999:
I just want it to stop going in that direction when it triggers the switch.
You just need another function (a little like your readAnalog() function) that reads the state of the limit switches and also call that from loop() - something like this
void checkEndStops() {
static byte leftStopState = HIGH;
static byte rightStopState = HIGH;
byte previousLeftState = leftStopState;
byte previousRightState = rightStopState;
leftStopState = digitalRead(leftStoPin);
rightStopState = digitalRead(rightStopPin);
if (leftStopState == LOW and previousLeftState == HIGH) { // assumes LOW when triggered may be wrong
stepperMayMove = false; // stepperMayMove must be a global variable
}
if (rightStopState == LOW and previousRightState == HIGH) { // assumes LOW when triggered may be wrong
stepperMayMove = false;
}
}
You have not said how you want the motor to restart after a stop so I have not dealt with that. You could, for example, get the motor to change direction when a limit switch is triggered.
Thanks, simply put I only want the motor to stop going left when left switch is on and stop going right when right switch is on. So the carriage moves either direction unless it reaches one of the end switches which stops it from going any farther in that direction only. Also the code has been modified so that when the joystick is in center (off) position no power is going to the motor. This is because I'm using battery power and I don't need precision locking.
bob999:
Thanks, simply put I only want the motor to stop going left when left switch is on and stop going right when right switch is on.
Try the code I suggested and then try modifying it to the meet your requirement - it should provide a good starting point.
If you run into a problem please post the program that represents your best attempt and tell us in detail what it actually does and what you want it to do that is different. That way we can focus on the parts you need help with rather than wasting time on things that you can do.
I don't know how to add your code, I just get errors and it won't compile
#include <AccelStepper.h> //accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)
//Pins
const byte Analog_X_pin = A0; //x-axis readings
const byte enablePin = 7;
//Variables
int Analog_X = 0; //x-axis value
int Analog_X_AVG = 0; //x-axis value average
void setup()
{
//SERIAL
Serial.begin(9600);
//----------------------------------------------------------------------------
InitialValues(); //averaging the values of the 3 analog pins (values from potmeters)
//----------------------------------------------------------------------------
//PINS
pinMode(Analog_X_pin, INPUT);
pinMode(enablePin, OUTPUT);
//----------------------------------------------------------------------------
//Stepper parameters
//setting up some default values for maximum speed and maximum acceleration
stepper.setMaxSpeed(2000); //SPEED = Steps / second
stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2
stepper.setSpeed(1000);
delay(1000);
}
void loop()
{
ReadAnalog();
checkEndStops();
if (stepperMayMove == true) {
stepper.runSpeed();
}
{
ReadAnalog();
stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}
void ReadAnalog()
void checkEndStops() {
static byte leftStopState = HIGH;
static byte rightStopState = HIGH;
byte previousLeftState = leftStopState;
byte previousRightState = rightStopState;
leftStopState = digitalRead(leftStoPin);
rightStopState = digitalRead(rightStopPin);
if (leftStopState == LOW and previousLeftState == HIGH) { // assumes LOW when triggered may be wrong
stepperMayMove = false; // stepperMayMove must be a global variable
}
if (rightStopState == LOW and previousRightState == HIGH) { // assumes LOW when triggered may be wrong
stepperMayMove = false;
}
}
{
if(abs(Analog_X-Analog_X_AVG)>50)
{
digitalWrite(enablePin, HIGH); // enable the driver
stepper.setSpeed(5*(Analog_X-Analog_X_AVG));
}
else
{
digitalWrite(enablePin, LOW); // disable the driver
stepper.setSpeed(0);
}
//Reading the potentiometer in the joystick:
Analog_X = analogRead(Analog_X_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)>50)
{
stepper.setSpeed(5*(Analog_X-Analog_X_AVG));
}
else
{
stepper.setSpeed(0);
}
}
void InitialValues()
{
//Set the values to zero before averaging
float tempX = 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
}
//----------------------------------------------------------------------------
Analog_X_AVG = tempX/50;
//----------------------------------------------------------------------------
Serial.print("AVG_X: ");
Serial.println(Analog_X_AVG);
Serial.println("Calibration finished");
}
You have put the code for the function checkEndStops() inside the code for the function readAnalaog() - that is not allowed. Each function must be separate. Like this
readAnalog() {
// all the code for this function
} // end of the function
checkEndStops() {
// all the code for this function
}
There may be other errors and if so please post the updated program and the error message.
bob999:
Thanks but this could go on for days correcting errors. I'll find another way
I spent over an hour with a program problem the day before yesterday because I had incorrectly created a file with the name cyllinder.tpl and I had not thought to consider that the file name was wrong.