Trouble With Bounce Library inside a While Loop.

I have a project that has 2 buttons, one of which is a multifunction button. Button one is using the Bounce Library .fallingEdge to send usbMIDI note and works just as it should. Button two is the multifunction button and when pressed will send a Midi note and when held will send a different midi note. My problem lies in the While Loop for the second button. I could not get .fallingEdge to work inside of the While Loop for the second button. I tried using digitalRead for it instead and was able to get both notes to send but I did not have control over which one was sent or whether or not it sent when the button was pressed or held. In the code button9 is the first button and button10 is the multifunction button. I have it coded with digitalRead as of right now.I would prefer to use .fallingEdge instead of digitalRead because It seems to respond better with the buttons than the digitalRead does. any advice would be greatly appreciated. Thanks in advance.

#include <Bounce.h>

const int channel = 1;

int press_milliSeconds = 0;

int press = 100;
int hold = 2000;

Bounce button9 = Bounce(9, 10); 
int button10 = (10);

void setup() {
  // put your setup code here, to run once:
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:
button9.update();


while (digitalRead(button10)==LOW) {
  press_milliSeconds = press_milliSeconds + 100;
}  

if (digitalRead(button10)==LOW){
      (press_milliSeconds >= hold);
    usbMIDI.sendNoteOn(3, 99, channel);
}
else if(digitalRead(button10)==LOW){
      (press_milliSeconds >= press); 
  usbMIDI.sendNoteOn(2, 99, channel);
}

if (button9.fallingEdge()) {
  usbMIDI.sendNoteOn(1, 99, channel);
}
}


/code]

I suspect the Bounce object only checks the button when you call .update() so if you want to detect change in the button state inside a loop you should call .update() in your loop.

I suggest that you use the Bounce2 version of the library. It is available through the library manager, and documentation is here https://github.com/thomasfredericks/Bounce2/wiki

Determining the duration of a button press with a while loop is not correct. You need to detect when the button is pressed and when it is released(or exceeds a time out), and determine the time between those events. Here’s an example using the syntax of Bounce2.

#include <Bounce2.h>

#define buttonPin 5
#define shortTime 500
#define longTime 1500

#define noEvent    0
#define shortPress 1
#define longPress  2

// Instantiate a Bounce object called button :
Bounce button = Bounce();

unsigned long buttonPressStartTimeStamp;
unsigned long buttonPressDuration;
boolean startTimeout = false;
boolean endTimeout = false;
byte event;

void setup()
{
  Serial.begin(115200);
  Serial.println("Long/Short Button Press");

  // Setup the button with an internal pull-up
  pinMode(buttonPin, INPUT_PULLUP);
  button.attach(buttonPin);
  button.interval(20);//set debounce interval
}
void loop()
{
  event = checkButton();

  switch (event)
  {
    case shortPress:
      Serial.println("short press");
      //do short press code
      break;

    case longPress:
      Serial.println("long press");
      //do long press code
      break;
  }
}

byte checkButton()
{
  byte event = noEvent;
  // Update the Bounce instance, does digitalRead of button
  button.update();

  // Button press transition from HIGH to LOW)
  if (button.fell())
  {
    buttonPressStartTimeStamp = millis();
    startTimeout = true;
  }

  // Button release transition from LOW to HIGH) :
  if (button.rose())
  {
    buttonPressDuration = (millis() - buttonPressStartTimeStamp);
    startTimeout = false;
  }

  if (buttonPressDuration > 0 && buttonPressDuration <= shortTime)
  {
    event = shortPress;
    buttonPressDuration = 0;
  }

  if (startTimeout == true && (millis() - buttonPressStartTimeStamp) > longTime)
  {
    event = longPress;
    startTimeout = false;
    buttonPressDuration = 0;
  }
  return event;
}

Ok so I got the multifunction working on one button but now I can’t figure out how to get the a Single function on the second button… I tried tying the 1st Bounce.h library back in with the fallingEdge method but the 2 Bounce libraries don’t play very well together. I really appreciate y’all’s help and patients.

const int channel = 1;
#include <Bounce2.h>

#define buttonPin (10)
#define shortTime 500
#define longTime 1500

#define noEvent    0
#define shortPress 1
#define longPress  2

// Instantiate a Bounce object called button :
Bounce button = Bounce(10, 10);

unsigned long buttonPressStartTimeStamp;
unsigned long buttonPressDuration;
boolean startTimeout = false;
boolean endTimeout = false;
byte event;

void setup()
{
  Serial.begin(115200);
  Serial.println("Long/Short Button Press");

  // Setup the button with an internal pull-up
  
  pinMode(buttonPin, INPUT_PULLUP);
  button.attach(buttonPin);
  button.interval(20);//set debounce interval
}
void loop()
{ 
  event = checkButton();

  switch (event)
  {
    case shortPress:
      Serial.println("short press");
     
      {usbMIDI.sendNoteOn(1, 99, channel); }
      break;

    case longPress:
      Serial.println("long press");
      {
        usbMIDI.sendNoteOn(2, 99, channel);
      }
      break;
  }
}

byte checkButton()
{
  byte event = noEvent;
  // Update the Bounce instance, does digitalRead of button
  button.update();
  // Button press transition from HIGH to LOW)
  if (button.fell())
  {
    buttonPressStartTimeStamp = millis();
    startTimeout = true;
  }

  // Button release transition from LOW to HIGH) :
  if (button.rose())
  {
    buttonPressDuration = (millis() - buttonPressStartTimeStamp);
    startTimeout = false;
  }

  if (buttonPressDuration > 0 && buttonPressDuration <= shortTime)
  {
    event = shortPress;
    buttonPressDuration = 0;
  }

  if (startTimeout == true && (millis() - buttonPressStartTimeStamp) > longTime)
  {
    event = longPress;
    startTimeout = false;
    buttonPressDuration = 0;
  }
  return event;

  
  
  
  }
/code]

Take a look at the Bounce2 library example titled "bounce2buttons".

It shows you how to create and attach two Bounce instances. Make sure you call .update() for both buttons, and use the conditional with the .fell() for the second button. .fell() replaces .fallingEdge().

You can then use a conditional statement to execute the third send note.

if(secondSingleFunctionButton.fell())
{
  usbMIDI.sendNoteOn(3, 99, channel);
}

I checked out the Bounce2buttons example and tried doing a test code to make sure I was understanding what I was looking at and I keep getting a “request member for .fell in 9 which is non class type int”. I tried looking up with error code and finding a fix. Any ideas?

#include <Bounce2.h>
const int channel = 1;

#define BUTTON_PIN_1 (9)

Bounce debouncer1 = Bounce();

void setup() {
  // put your setup code here, to run once:
 pinMode (BUTTON_PIN_1, INPUT_PULLUP);
 debouncer1.attach(BUTTON_PIN_1);
 debouncer1.interval(10);
}

void loop() {
  // put your main code here, to run repeatedly:
debouncer1.update();
 

if (BUTTON_PIN_1.fell()) {
  usbMIDI.sendNoteOn( 1, 99, channel);
}
}/code]

You are close. You have named your Bounce instance debouncer1.

Bounce debouncer1 = Bounce();

You then use debouncer1.xxx as the way to call all the functions for that instance.

debouncer1.attach(BUTTON_PIN_1);
debouncer1.interval(10);
debouncer1.update();

But then you missed the last one.

if (BUTTON_PIN_1.fell())

You have alread attached BUTTON_PIN_1 , so the correct syntax for the change state is
if(debouncer1.fell())
{
usbMIDI.sendNoteOn( 1, 99, channel);
}

sorry I have been away from my laptop for a couple days but yes that has fixed it. Everything is working perfectly! Thank you for all the help.

BTW, if your project become bigger with more switch and you want to save MCU power, I found a CMOS Switch Debouncers chip, cheap and easy to implement.