Limit switches not changing the direction of stepper motors

Hi everyone,

Im currently working on a project that involves a cart in a rail using an Arduino Mega, external battery, 2 28BYJ stepper motors with ULN2003 drivers. On the ends it has 2 micro limit switches on NC and COM. The code "works"if the limit switch is pressed by hand the motors change direction, BUT in the cart, the cart moves so slow that when the limit switch is pressed, it keeps on pressing and it doesn't trigger changing the direction, so it keeps moving forward.

This is a video of the problem:

Any ideas on how to fix this?

This is my code:

// Include the AccelStepper Library
#include <AccelStepper.h>

// Define step constants
#define FULLSTEP 4

// Creates two instances
// Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence
AccelStepper stepper1(FULLSTEP, 8, 10, 9, 11);
AccelStepper stepper2(FULLSTEP, 4, 6, 5, 7);

//Limit switches
#define LIMIT_SWITCH_PIN_L 2
#define LIMIT_SWITCH_PIN_R 3

void setup() {

  Serial.begin(9600);

  pinMode(LIMIT_SWITCH_PIN_L, INPUT_PULLUP);
  pinMode(LIMIT_SWITCH_PIN_R, INPUT_PULLUP);

	// set the maximum speed, acceleration factor,
	// initial speed and the target position for motor 1
	stepper1.setMaxSpeed(100.0);
	stepper1.setAcceleration(100.0);
	stepper1.setSpeed(100);
  stepper1.moveTo(2560);

	// set the same for motor 2
	stepper2.setMaxSpeed(100.0);
	stepper2.setAcceleration(100.0);
	stepper2.setSpeed(100);
  stepper2.moveTo(-2560);

  delay(100);
}

void loop() {

  if (stepper1.distanceToGo() == 0 || stepper2.distanceToGo() == 0){
		stepper1.moveTo(stepper1.currentPosition());
    stepper2.moveTo(-stepper2.currentPosition());
  }

	if (stepper1.distanceToGo() == 0 || stepper2.distanceToGo() == 0){
    stepper1.moveTo(-stepper1.currentPosition());
		stepper2.moveTo(stepper2.currentPosition());
  }

  if (digitalRead(LIMIT_SWITCH_PIN_R) == 1){
      stepper1.stop();
      stepper2.stop();
      Serial.println("Right limit switch pressed");
		  stepper1.moveTo(2560);
		  stepper2.moveTo(-2560);
    
    delay(100);
  }

  if (digitalRead(LIMIT_SWITCH_PIN_L) == 1){
      stepper1.stop();
      stepper2.stop();
      Serial.println("Left limit switch pressed");
		  stepper1.moveTo(-2560);
		  stepper2.moveTo(2560);

    delay(100);
  }

  stepper1.run();
	stepper2.run();
}

You can try reading a state change of the limit switches by comparing the current reading to a previous one. When the switch goes from closed to open, make the reversal.

Tapping the board for motor current is generally No, No. Use a separate power supply for motors.

1 Like

@Yarelix

  1. Verify you wired the correct side of the left limit switch. You are looking for OPEN when pressed so the INPUT_PULLUP can create the "1" to change directions.
  2. See if the motors are pulling against each other when it stalls

Stalling its not the issue nor the motors are pulling each other, its that the motors doesn't stop when the switch is triggered on time, the motors keeps pushing the switch. If the switch is released by hand then the motors reverse their direction, so it basically defeats the purpose of having a switch in the sides.

I interpreted motors not moving as stalling.

I agree with @cattledog to examine the code for reading (and debouncing) the limit switches. A bouncing button might put the "state" into "keep pushing."

You are looking for HIGH or LOW for your switch. A bouncing button will cause hundreds of transitions. Read about "arduino button debounce" to ensure you change the state only when you want to change it.

bounce

This does NOT stop your steppers immediately. It only sets a new target, that can be reached using the actual acceleration/deceleration. So your motor will still go in the same direction, ramping it's speed down ... but this:

delay(100);
reduces the speed very much to reach the turnaround point.

[EDIT]: Even worse - as long as the limit switch is pressed, with every loop cycle .stop is executed again, and a new target further away is set, which will never be reached.
Delete all .stop statements and the delay statements.

Also this:

    stepper1.moveTo(-2560);
    stepper2.moveTo(2560);

will not help much, because the direction will only be changed after the turnaround point has been reached.

Another question:

What do you want to achive with this? It's fairly useless, because
stepperx.moveTo(stepperx.currentPosition());
does nothing, and so
stepperx.distanceToGo() == 0
will always stay true once thae target position is reached ( and not changed at another place )

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.