Stepper direction control using one button

Hi,
Ive been working on a code that when a button on a remote is pressed, my stepper will run forward, when the same button is pressed again, it reverses to where it started.
I have a code that works exactly how I need it too and uses a two buttons, so i started to alter that code to work with only one button.
Im on the right track I believe, but I'm a little confused on the counting of button presses and what part of the code is actually changing the direction of the stepper....

Here is the working 2 button code...

#include <AccelStepper.h>
#define DISTANCE 900

// Define a stepper and the pins it will use
AccelStepper stepper(1, 4, 3);

int pos = 3600;
int StepCounter = 0;
int Stepping = false;

void setup() {
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);

  pinMode(1, INPUT);
  pinMode(2, INPUT);
  stepper.setMaxSpeed(500);
  stepper.setAcceleration(500);




  
}

void loop() {
  if (digitalRead(2) == HIGH && Stepping == false)
  {
    digitalWrite(3, LOW);
    Stepping = true;
  }
  if (digitalRead(1) == HIGH && Stepping == false)
  {
    digitalWrite(3, HIGH);
    Stepping = true;
  }

  if (Stepping == true)
  {
    digitalWrite(4, HIGH);
    delay(1);
    digitalWrite(4, LOW);
    delay(1);

    StepCounter = StepCounter + 1;

    if (StepCounter == DISTANCE)
    {
      StepCounter = 0;
      Stepping = false;
    }
    stepper.run();
  }
}
/code]

And here is my one button code thats being worked on.....
[code]#include <AccelStepper.h>
#define DISTANCE 200

// Define a stepper and the pins it will use
AccelStepper stepper(1, 3, 4);

int pos = 2000;
int StepCounter = 0;
int Stepping = false;
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;
const int buttonPin = 1;

void setup() {
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(buttonPin, INPUT);

  digitalWrite(4, LOW);
  digitalWrite(3, LOW);

  stepper.setMaxSpeed(500);
  stepper.setAcceleration(500);
}

void loop()
{
  buttonState = digitalRead(buttonPin);
  if (buttonState != lastButtonState)
  {
    if (buttonState == HIGH)
    {
      buttonPushCounter++;//button pressed once
      digitalWrite(4, LOW);
      Stepping = true;
    }
  }
  lastButtonState == buttonState;
  if (buttonPushCounter % 2 == 0)
  {
    digitalWrite(4, HIGH);
    Stepping = true;
  }
  if (Stepping == true)
  {
    digitalWrite(3, HIGH);
    delay(1);
    digitalWrite(3, LOW);
    delay(1);
  }

  StepCounter = StepCounter + 1;

  if (StepCounter == DISTANCE)
  {
    StepCounter = 0;
    Stepping = false;
  }
  stepper.run();
}

/code]

Any advise/guidance would be greatly appreciated

Thank You 8)

Any advise/guidance would be greatly appreciated

  • give names to your pins
  • you will need to handle your button bouncing

Wouldn't it be a lot easier if you create a variable called motorDirection and set it to 'F' with one button press and set it to 'R' with the next button press etc.

...R

J-M-L,
Will do.

Robin2,
Ill read up on "variable".....

Are you referring to the Boolean Variable or does it matter either way?

Thanks for the replies, Ill read up on those subjects...

Jeff

Merlin5150:
Are you referring to the Boolean Variable or does it matter either way?

I was thinking of a char variable so it could have values such as 'F' and 'R'. I think that makes the program logic easier for me (and you?) to understand. But you could certainly use a boolean variable such as forwardDirection = true (or false, for reverse).

...R

But you could certainly use a boolean variable such as forwardDirection = true (or false, for reverse).

Perhaps named movingForward, so that true makes sense. If I were to see forwardDirection as a variable name, I'd expect the type to be a vector with i, j, and k components.

Small item...
Make sure to keep track of where your EXACT motor/step count is - accommodating the first & last steps when button is pressed.
You may find that without clean button state sensing and clearly controlled step pulsing, that your motor position could 'stumble' an extra step.
It could help if you have an optical/switch limit at the 'home'position to recalibrate on each cycle.
One step lost in thousands doesn't seem much, but it can accumulate if missed steps are not accounted for.

PaulS:
Perhaps named movingForward, so that true makes sense. If I were to see forwardDirection as a variable name, I'd expect the type to be a vector with i, j, and k components.

Fair point. Which is why I prefer to use a char variable with 'F' and 'R'

...R

Robin2:
Fair point. Which is why I prefer to use a char variable with 'F' and 'R'

...R

That would allow for 'S' (stopped), too.

Awesome and Thanks again!!

so,
I don't really need "buttonPushCounter" at all....as long as the code keeps track of the "lastButtonState"

both F and R are set to ( int f = false;) for example

Then, "if" statements change the direction when compared to...

I mean in a general sense, not exactly like that. Im looking at the first 2 button code also as reference to understand why the code works as it does.

Merlin5150:
both F and R are set to ( int f = false;) for example

That sounds like the worst of all possible worlds - meaningless single character variable names, still needing to get your head around that what true and false represent AND the risk (because they are now separate) of both being true at the same time. And wasting memory by using an int rather than a boolean (or a char for 'F').

...R

Maybe I need to wrap my head around everything it sounds like before I even start asking questions......

I'll be busy and thanks everyone for the continuing guidance.