Start/Stop Button on Loop

I believe this topic has been covered, but I can’t apply what I’ve read to my application. I’m also starting a new thread as this is continuation from a previous, now finalized code.

I have an oscillation motion that bounces between two optical end-stops. Please see code below. I first used an ezButton library to have a start/stop button. The button works, but to get the loop going, I have to first trip an optical sensor. Which makes sense based on my code.

So I then tried to run the stepper forward when both switch states are Low. But that caused “bouncing” when an endstop was closed. Which also makes sense because I specified as such.

Any suggestions on what to try next? I was going to try a homing routine, but I wasn’t sure how to only initialize that upon startup – and not every time the loop runs.

Thanks!

#include <AccelStepper.h> //accelstepper library[color=#222222][/color]
#include <ezButton.h>[color=#222222][/color]
[color=#222222][/color]
#define LOOP_STATE_STOPPED 0[color=#222222][/color]
#define LOOP_STATE_STARTED 1[color=#222222][/color]
[color=#222222][/color]
// constants won't change. They're used here to set pin numbers:[color=#222222][/color]
const byte limitSwitch_1 = 2; //pin for the microswitch[color=#222222][/color]
const byte limitSwitch_2 = 3; //pin for the microswitch[color=#222222][/color]
int smDirectionPin = 9; //Direction pin[color=#222222][/color]
int smStepPin = 8; //Stepper pin[color=#222222][/color]
[color=#222222][/color]
// variables will change:[color=#222222][/color]
int switch1State = 0;         // variable for reading the Switch 1 status[color=#222222][/color]
int switch2State = 0;         // variable for reading the Switch 2 status[color=#222222][/color]
boolean ForwardState = 0;         // variable for reading the micro-switch status[color=#222222][/color]
boolean BackwardState = 0;   // variable for reading the microswitch status[color=#222222][/color]
//------------------------------------------------------------------------------------[color=#222222][/color]
[color=#222222][/color]
// create ezButton object that attach to pin 7;[color=#222222][/color]
ezButton button(7);[color=#222222][/color]
int loopState = LOOP_STATE_STOPPED;[color=#222222][/color]
[color=#222222][/color]
//direction Digital 9 (CCW), pulses Digital 8 (CLK)[color=#222222][/color]
AccelStepper stepper(1, 9, 8);[color=#222222][/color]
[color=#222222][/color]
void setup()[color=#222222][/color]
{[color=#222222][/color]
  //Limit Switches[color=#222222][/color]
  pinMode(limitSwitch_1, INPUT_PULLUP); // internal pullup resistor (debouncing)[color=#222222][/color]
  pinMode(limitSwitch_2, INPUT_PULLUP); // internal pullup resistor (debouncing)[color=#222222][/color]
  //---------------------------------------------------------------------------[color=#222222][/color]
[color=#222222][/color]
  //Stepper parameters[color=#222222][/color]
  //setting up some default values for maximum speed and maximum acceleration[color=#222222][/color]
  stepper.setMaxSpeed(5000); //SPEED = Steps / second[color=#222222][/color]
  stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2[color=#222222][/color]
[color=#222222][/color]
  pinMode(smDirectionPin, OUTPUT);[color=#222222][/color]
  pinMode(smStepPin, OUTPUT);[color=#222222][/color]
[color=#222222][/color]
  // set debounce time to 50 milliseconds[color=#222222][/color]
  button.setDebounceTime(50);[color=#222222][/color]
}[color=#222222][/color]
[color=#222222][/color]
void SlideForward()[color=#222222][/color]
{[color=#222222][/color]
  stepper.setSpeed(2000);[color=#222222][/color]
}[color=#222222][/color]
[color=#222222][/color]
void SlideBackward()[color=#222222][/color]
{[color=#222222][/color]
  stepper.setSpeed(-2000);[color=#222222][/color]
}[color=#222222][/color]
[color=#222222][/color]
void loop() {[color=#222222][/color]
  button.loop(); // MUST call the loop() function first[color=#222222][/color]
[color=#222222][/color]
  if (button.isPressed()) {[color=#222222][/color]
    if (loopState == LOOP_STATE_STOPPED)[color=#222222][/color]
      loopState = LOOP_STATE_STARTED;[color=#222222][/color]
    else // if(loopState == LOOP_STATE_STARTED)[color=#222222][/color]
      loopState = LOOP_STATE_STOPPED;[color=#222222][/color]
  }[color=#222222][/color]
[color=#222222][/color]
[color=#222222][/color]
  if (loopState == LOOP_STATE_STARTED) {[color=#222222][/color]
    // read the state of the switches value;[color=#222222][/color]
    ForwardState = digitalRead(limitSwitch_1);[color=#222222][/color]
    BackwardState = digitalRead(limitSwitch_2);[color=#222222][/color]
[color=#222222][/color]
    //step the motor (this will step the motor by 1 step at each loop indefinitely)[color=#222222][/color]
    stepper.runSpeed();[color=#222222][/color]
[color=#222222][/color]
    // check which pin 2 or 3 is HIGH:[color=#222222][/color]
    if (ForwardState == HIGH && BackwardState == LOW) {[color=#222222][/color]
      SlideForward();[color=#222222][/color]
    }[color=#222222][/color]
[color=#222222][/color]
    if (BackwardState == HIGH && ForwardState == LOW) {[color=#222222][/color]
      SlideBackward();[color=#222222][/color]
    }[color=#222222][/color]
  }[color=#222222][/color]
}

Ponder this - if the mechanism is traveling toward the ForwardState* switch do you really care about the BackwardState switch?

  • a small point but, standard form would be , forwardState

Hi dougp I need that clause because without checking the opposing switch, the stepper just “bounces” when the forwardState switch is blocked and then unblocked.

I’m also going to repost the code below. I don’t know why it added all that additional data.

When I upload the code, the motor doesn’t rotate, as expected. It’s when I trip a switch is when the circuit is initiated. Is there a initial homing sequence I can add that starts the motor upon upload? Would that homing sequence run every loop?

#include <AccelStepper.h> //accelstepper library
#include <ezButton.h>

#define LOOP_STATE_STOPPED 0
#define LOOP_STATE_STARTED 1

// constants won't change. They're used here to set pin numbers:
const byte limitSwitch_1 = 2; //pin for the microswitch
const byte limitSwitch_2 = 3; //pin for the microswitch
int smDirectionPin = 9; //Direction pin
int smStepPin = 8; //Stepper pin

// variables will change:
int switch1State = 0;         // variable for reading the Switch 1 status
int switch2State = 0;         // variable for reading the Switch 2 status
boolean ForwardState = 0;         // variable for reading the micro-switch status
boolean BackwardState = 0;   // variable for reading the microswitch status
//------------------------------------------------------------------------------------

// create ezButton object that attach to pin 7;
ezButton button(7);
int loopState = LOOP_STATE_STOPPED;

//direction Digital 9 (CCW), pulses Digital 8 (CLK)
AccelStepper stepper(1, 9, 8);

void setup()
{
  //Limit Switches
  pinMode(limitSwitch_1, INPUT_PULLUP); // internal pullup resistor (debouncing)
  pinMode(limitSwitch_2, INPUT_PULLUP); // internal pullup resistor (debouncing)
  //---------------------------------------------------------------------------

  //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

  pinMode(smDirectionPin, OUTPUT);
  pinMode(smStepPin, OUTPUT);

  // set debounce time to 50 milliseconds
  button.setDebounceTime(50);
}

void SlideForward()
{
  stepper.setSpeed(2000);
}

void SlideBackward()
{
  stepper.setSpeed(-2000);
}

void loop() {
  button.loop(); // MUST call the loop() function first

  if (button.isPressed()) {
    if (loopState == LOOP_STATE_STOPPED)
      loopState = LOOP_STATE_STARTED;
    else // if(loopState == LOOP_STATE_STARTED)
      loopState = LOOP_STATE_STOPPED;
  }


  if (loopState == LOOP_STATE_STARTED) {
    // read the state of the switches value;
    ForwardState = digitalRead(limitSwitch_1);
    BackwardState = digitalRead(limitSwitch_2);

    //step the motor (this will step the motor by 1 step at each loop indefinitely)
    stepper.runSpeed();

    // check which pin 2 or 3 is HIGH:
    if (ForwardState == HIGH && BackwardState == LOW) {
      SlideForward();
    }

    if (BackwardState == HIGH && ForwardState == LOW) {
      SlideBackward();
    }
  }
}

Please post a wiring diagram and describe your project and exactly how it is supposed to work.
Please edit your code and remove the color markups, they don't work in the code box, as you've seen.

hi @JCA34F. Thank you for your response!

Here is a sequence of operation of how I want my stepper to work after initially uploading the sketch and/or pressing reset button on Uno R3:

  1. Push Start Button

  2. Motor moves Forward to Limit Switch 1

  3. Motor reverses and changes direction.

  4. Motor moves to Limit Switch 2

  5. Motor reverses and changes direction.

  6. Motor oscillates back and forth until Push Stop Button

I have Steps 2-5 completed with the posted code. The start/stop button functionality however only works after I manually trip a switch. I'd like for the motor to start automatically when I press the start button.

I attached two images: how I wired my motor driver and stepper and how I wired the button per the ezButton functionality. What is not shown is that I have 1 optical endstop wired to Pin 2 and another wired to Pin 3. Ground and 5V wired accordingly.

I also just tried to put the following while statement in my void setup, but it didn't work:

{ while (digitalRead(limitSwitch_1) == LOW)
    stepper.runSpeed(); //step the motor (this will step the motor by 1 step
}

Thanks in advance for your time and help!!!

Your code doesn't set a speed for the stepper initially and it will only get set when you hit a limit switch, so if the thing that moves isn't touching either, there will not be movement.

I'd try calling SlideForward in setup.

@wildbill Your suggestion worked!!!!!!!! I set the speed in my setup and the start/stop button functionality works!

Thanks for the small, but very valuable line of code!

void setup()
{
  //Limit Switches
  pinMode(limitSwitch_1, INPUT_PULLUP); // internal pullup resistor (debouncing)
  pinMode(limitSwitch_2, INPUT_PULLUP); // internal pullup resistor (debouncing)
  //---------------------------------------------------------------------------

  //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(2000);
  delay(500);

  pinMode(smDirectionPin, OUTPUT);
  pinMode(smStepPin, OUTPUT);

  // set debounce time to 50 milliseconds
  button.setDebounceTime(50);
}