momentary button switch control for stepper using Arduino/Button

I have been looking at this library because it supports different lengths of button presses. I don’t have any experience with this and could use some help by way of explanations…I do know how to press a button. The below example is from the library readme.

#include "Button.h"

Button button(2);  // the button will be on pin 2

// functions that will be called whenever one of the XB(s)P's event occurs

void on_release() {
  Serial.print(String("button released immediately: ") + button.gap() + String(" milliseconds\n"));
}
void on_press() {
  Serial.print(String("button pressed immediately: ") + button.gap() + String(" milliseconds\n"));
}
void on_long_release() {
  Serial.print(String("button released after long time: ") + button.gap() + String(" milliseconds\n"));
}
void on_long_press() {
  Serial.print(String("button pressed after long time: ") + button.gap() + String(" milliseconds\n"));
}
void on_bounced_release() {
  Serial.print(String("button released after a bounce: ") + button.gap() + String(" milliseconds\n"));
}
void on_bounced_press() {
  Serial.print(String("button pressed after a bounce: ") + button.gap() + String(" milliseconds\n"));
}

void setup() {
  Serial.begin(9600);
  button.on_release(on_release);            // on NBP (if not set nothing will be done)
  button.on_press(on_press);              // on NBsP (if not set nothing will be done)
  button.on_long_press(on_long_press);        // on LBsP (if not set, on_press will be used for on_long_press events)
  button.on_long_release(on_long_release);      // on LBP (if not set, on_release will be used for on_long_release events)
  button.on_bounced_release(on_bounced_release);    // on BBP (junk, if not set nothing will be done)
  button.on_bounced_press(on_bounced_press);      // on BBsP (junk, if not set nothing will be done)
}

void loop() {
  button.init();
}

Options

You can change the default time for wich a press is considered as bounced as well as that for which a press is considered long with the methods:

button.set_minimum_gap(<time in milliseconds>);
button.set_maximum_gap(<time in milliseconds>);

You can also get these values with:

button.get_minimum_gap(<time in milliseconds>);
button.get_maximum_gap(<time in milliseconds>);

The gap between a release and a press (or vice versa) can be accessed with:

button.gap(<time in milliseconds>);

Finally debug mode can be enable or disabled with (it is disabled by default):

button.enable_debug();
button.disable_debug();

What’s the question?

//Thanks, more than one, actually -

//Do I need to put all of this in my sketch or can I put in just what I want to use,ie normal button press //and long button press?

//What do I do with these parentheses?:

button.on_press(on_press);

//and these:

void on_press() {
Serial.print(String("button pressed immediately: ") + button.gap() + String(" milliseconds\n"));
}

You don't have to have them all.

void on_press() {
  Serial.print(String("button pressed immediately: ") + button.gap() + String(" milliseconds\n"));
}

That's a function. Just a regular old function.

button.on_press(on_press);

That's telling the library to call the on_press function when it detects a press.

You could have it call any function you want when it detects a button press as long as the function in question takes no arguments and returns void. Just put the name of your function in those parens.

Thanks very much, sometimes I vaguely know what I know; so I look it up, if I can't find anything after a day, I ask -

Here is what I have - I keep thinking something is missing because after a few rounds seems to get lost, or I’m inconsistent with my button presses:

#include <Adafruit_MotorShield.h>
#include <Adafruit_MS_PWMServoDriver.h>
#include <Button.h>

Adafruit_MotorShield AFMS = Adafruit_MotorShield();

const int BLACK_BUTTON_PIN = A0;
const int RED_BUTTON_PIN = A2;

int blackButtonState = LOW;
int redButtonState = LOW;
int myMotor1Position = 0;
int myMotor2Position = 0;

Button redButton(A2);

Adafruit_StepperMotor *myMotor1 = AFMS.getStepper(512, 1);
Adafruit_StepperMotor *myMotor2 = AFMS.getStepper(512, 2);

void on_release() {
  Serial.print(String("redButton released immediately: ") + redButton.gap() + String(" milliseconds\n"));
}
void on_long_release() {
  Serial.print(String("redButton released after long time: ") + redButton.gap() + String(" milliseconds\n"));
}

void setup() {
  AFMS.begin();

  pinMode(BLACK_BUTTON_PIN, INPUT);
  pinMode(RED_BUTTON_PIN, INPUT);

  myMotor1->setSpeed(15);
  myMotor2->setSpeed(30);

  Serial.begin(9600);
  redButton.on_release(on_release);
  redButton.on_long_release(on_long_release);
}

void loop() {

  blackButtonState = digitalRead(BLACK_BUTTON_PIN);
  if (blackButtonState == HIGH)
  {
    myMotor1->step(32, FORWARD, SINGLE);
    delay(2);

    myMotor2->step(256, FORWARD, SINGLE);
    delay(2);
  }

  on_release;
  redButtonState = digitalRead(RED_BUTTON_PIN);
  if (redButtonState == HIGH)
  {
    myMotor2->step(256, BACKWARD, SINGLE);
    delay(2);
  }

  on_long_release;
  redButtonState = digitalRead(RED_BUTTON_PIN);
  if (redButtonState == HIGH)
  { myMotor2->step(256, FORWARD, SINGLE);
    delay(2);
  }

}

Do you see anything wrong or missing?

debounce

bbishop:
because after a few rounds seems to get lost

Can you describe that in some slightly more detail. What do you mean by "get lost". What actually happens and how does that compare with what you expected to see?

You have that button class to handle your red button. Why are you also trying to handle it in the loop?

Can you describe that in some slightly more detail. What do you mean by "get lost". What actually happens and how does that compare with what you expected to see?

What happens is the button starts by toggling the motor back and forth as desired; after a few rounds it will go the wrong direction.

You have that button class to handle your red button. Why are you also trying to handle it in the loop?

What in the loop are you referring to?

on_release; ??

how would it know if normal release or long release?

[/quote]

bbishop:
What in the loop are you referring to?

on_release; ??

how would it know if normal release or long release?

Yeah that line. See, you should put whatever you want to have happen on a long release in that function that you attached. Not in the loop. All that stuff needs to be in the on_long_release() method.

This line:

on_release;

doesn't do anything. A function name without the parenthesis is just a pointer to a function. That doesn't make a statement. It's just a number. It doesn't do anything. You could call the function if you put parenthesis there, but you don't want to do that unconditionally in loop. You want to let that Button object handle all of that.