1

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 write this code but it would work great if I could just add the end stops. If I have the switches connected to pins 2 and 3.

How could I write something like: if pin 2 goes 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");  
}
1

This is what I came up with. Note that the ReadLimits function is called after ReadAnalog and before runSpeed. In that order the stepper will not move in the direction of the limit switch, if it is pressed.

PS since you used setAcceleration, don't you need to call run instead of runSpeed?

void loop()
{
  ReadAnalog();
  ReadLimits();  
  stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}

void ReadLimits()
{
  if( digitalRead(2)==LOW && stepper.speed()>0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }

  if( digitalRead(3)==LOW && stepper.speed()<0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }
}

edit to avoid some confusion; here is the entire code with my suggestion embedded:

#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();
  ReadLimits();  
  stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}

void ReadLimits()
{
  if( digitalRead(2)==LOW && stepper.speed()>0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }

  if( digitalRead(3)==LOW && stepper.speed()<0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }
}

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");  
}
7
  • Thanks for responding, I tried what you sent, if I touch either pin 2 or 3 to gnd. or 5V still nothing happens the motor doesn't stop in either direction. I don't know much about coding, I tried to hire someone to do it and after 2 days of trouble shooting and revising the code it still doesn't work. The code works perfectly except I can't seam to add the end stops. Any help would be greatly appreciated. – edrummer Jan 26 at 18:24
  • Have you added pull-up resistors, or used pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP);? – Gerben Jan 26 at 21:40
  • Why did you add ReadAnalog(); stepper.runSpeed(); at the end of the ReadLimits function I provided? – Gerben Jan 26 at 21:45
  • See my edit above. – Gerben Jan 26 at 21:50
  • I think that's it, if I have pins 2 and 4 connected to 5v it runs normally, when I connect the jumper wire to gnd instead or + it stops the motor in that direction. Forgive me I really don't know what I'm doing when it comes to this stuff. So I have hall switches for the stops do I include pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); or do I need pullup resistors? if so what value please? I am very grateful for your help maybe now I can finish this. – edrummer Jan 26 at 22:28
-1

This is what I tried:

#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;
 const byte leftSwitch = 2;
 const byte rightSwitch = 3; 
//Variables
 int Analog_X = 0; //x-axis value
 int Analog_X_AVG = 0; //x-axis value average

void setup()
{
 
  //SERIAL
  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();
  ReadLimits();  
  stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}

void ReadLimits()
{
  if( digitalRead(2)==LOW && stepper.speed()>0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }

  if( digitalRead(3)==LOW && stepper.speed()<0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }
  
  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");  
}
2
  • Are you saying this is an answer to your question somehow? If so, it would be good to make that clear. Or is this additional information that should be edited into your question? – timemage Jan 26 at 18:35
  • Looks like the ReadAnalog() at the end of the ReadLimits() code would undo any setSpeed(0) done by the limit tests. – Dave X Feb 25 at 22:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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