Stepper Motor Push Button Help!

I am having difficulties programming what should be a simple sketch that gets my stepper motor to run at one step per second indefinitely at the press of a button and then stops at the press of another button. I am using the Bounce2.h and accelstepper.h libraries and have been unable to figure out how to do it. Any help would be greatly appreciated, and as for hardware I am using a NEMA 23 High Torque Stepper Motor connected through a M542T Motor Driver powered by a Switching Power Supply and running on an Arduino UNO.

Attatched find my code, and thank you so much for the help!

    #include <Bounce2.h>
    #include <LiquidCrystal.h>
    #include <SoftwareSerial.h>
    #include <AccelStepper.h>
    
    AccelStepper stepper(1, 9, 8); // initiate stepper motor
    
    //int buttonPresses = 0;
    const byte ButtonPin = 10;
    const byte LedPin = 13; // for debugging and visualization
    
    Bounce button;
    
    void setup() {
      Serial.begin(9600);
      button.attach(ButtonPin);
      pinMode(LedPin, OUTPUT);
      stepper.setSpeed(1);
    }
    
    void loop() {
      if (button.rose()) {
        stepper.runSpeed();
        digitalWrite(LedPin, HIGH);
        //    buttonPresses++; // count presses of button and print to monitor
        //    Serial.print("Number of Button ");
        //    Serial.print("Presses = ");
        //    Serial.println(buttonPresses);
      }
      else {
        button.update();
        digitalWrite(LedPin, LOW);
        if (button.fell()) {
          stepper.stop();
        }
      }
    }

As of now, a button press runs the motor at 1 step/second, but a second press or any subsequent presses thereafter do nothing to stop the motor. Thanks so much!

Have a look at how to deal with "state machines".
The pseudo sketch would be something like:

  • use a boolean variable "buttonState" and in the setup() set it "LOW"

  • void loop():

  • continuously read the button

  • if the button was pressed and the current "buttonState" is "LOW" -> set buttonState "HIGH" and run the motor

  • if the button was pressed and the current "buttonState" is "HIGH" -> set buttonState "LOW" and stop the motor

rpt007:

  • use a boolean variable "buttonState" and in the setup() set it "LOW"

  • void loop():

  • continuously read the button

  • if the button was pressed and the current "buttonState" is "LOW" -> set buttonState "HIGH" and run the motor

  • if the button was pressed and the current "buttonState" is "HIGH" -> set buttonState "LOW" and stop the motor

So I have edited my program and added a boolean buttonState = LOW above the void setup() so it declares globally and then edited my void loop() to look like this

void loop() {
  button.update();
  if (button.rose() == true && buttonState == LOW) {
    stepper.runSpeed();
    digitalWrite(LedPin, HIGH);
    buttonState = HIGH;
  }
  else {
    if (button.fell() == true && buttonState == HIGH) {
      stepper.stop();
      buttonState = LOW;
    }
  }
}

But now I get one step every button press and nothing else. Any ideas?

Move the line stepper.runSpeed() as the last thing in loop() - outside the various IF clauses

Something like this

if (buttonState == HIGH) {
   stepper.runSpeed();
}

...R

Look at the logic of your sketch.
The stepper only can move just one step, each time you press the button.

A program does what you tell it, not what you intend it to do :slight_smile: :slight_smile:
So follow Robin's advice and have the run command outside the IF clauses.

Just wanted to say thank you to RPT and Robin for the help. After using the advice, I notice how poor of a mistake I had made. I realize my fault in calling the runSpeed function within the if statement. I also needed to change button.fell() to button.rose() since button.fell() returns true when the button is released, so basically I was stopping the motor everytime I let go of the button. Here is the final, and working void loop() in case anyone runs into a similar problem in the future:

void loop() {
  button.update();
  if (button.rose() == true && buttonState == LOW) {
    digitalWrite(LedPin, HIGH);
    buttonState = HIGH;
  }
  else {
    if (button.rose() == true && buttonState == HIGH) {
      stepper.stop();
      buttonState = LOW;
    }
  }
  if (buttonState == HIGH) {
    stepper.setSpeed(1);
    stepper.runSpeed();
  }
}