Button press results in wrong if statement being triggered.

Knyter

New member
Hi! I'm a novice programmer. I've butchered the Bounce2 > more > BounceTwo example to make it so that it only performs an action (count up or down and print result) with each button press.
It works okay if I alternate between pressing the buttons: count goes up, down, up down... But when I press either button a few times and then press the other one, the first press will result in the wrong action being performed once, after which it goes back to normal. So basically:

Press right: count = 1
Press left: count = 0
Press right: count = 1
Press left: count = 0
Press right: count = 1
Press right: count = 2
Press right: count = 3
Press right: count = 4
Press left: count = 5
Press left: count = 4
Press left: count = 3
Press left: count = 2
Press right: count = 1
Press right: count = 2
Press right: count = 3
Press right: count = 4
etc.

I also used a rotary encoder's A and B outputs in stead of the buttons (which are those tiny breadboard switches), but got the same result. I tried different pins (like 10 and 11), but no change.

I'm running the following code on a Teensy 4.1.

Code:
/* 
 DESCRIPTION
 ====================
 Simple example of the Bounce library that switches the debug LED when 
 either of 2 buttons are pressed.
 */
 
// Include the Bounce2 library found here :
// https://github.com/thomasfredericks/Bounce2
#include <Bounce2.h>

#define BUTTON_PIN_1 24
#define BUTTON_PIN_2 32


#define LED_PIN 13

// Instantiate a Bounce object
Bounce button1 = Bounce(); 

// Instantiate another Bounce object
Bounce button2 = Bounce(); 

bool statChange = false;
int count = 0;

void setup() {

  // Setup the first button with an internal pull-up :
  pinMode(BUTTON_PIN_1,INPUT_PULLUP);
  // After setting up the button, setup the Bounce instance :
  button1.attach(BUTTON_PIN_1);
  button1.interval(5); // interval in ms
  
   // Setup the second button with an internal pull-up :
  pinMode(BUTTON_PIN_2,INPUT_PULLUP);
  // After setting up the button, setup the Bounce instance :
  button2.attach(BUTTON_PIN_2);
  button2.interval(5); // interval in ms


  //Setup the LED :
  pinMode(LED_PIN,OUTPUT);

}

void loop() {
  // Update the Bounce instances :
  button1.update();
  button2.update();

  // Get the updated value :
  int value1 = button1.read();
  int value2 = button2.read();

  // Turn on the LED if either button is pressed :
  if ( value1 == LOW) {
    digitalWrite(LED_PIN, HIGH );
    if (statChange){
      Serial.print("Left button pushed, value: ");
      Serial.println(--count);
      statChange = false;
    }
  } 
  else if (value2 == LOW) {
    digitalWrite(LED_PIN, HIGH );
    if (statChange){
      Serial.print("Right button pushed, value: ");
      Serial.println(++count);
      statChange = false;
    }
  } 
  else {
    digitalWrite(LED_PIN, LOW );
    statChange = true;
  }
}

Unfortunately it's 00:30 AM here, so I gotta head off and won't be able to respond immediately. This problem has already occupied most of my night. Thanks in advance!
 
I have 'fixed' the issue. I took out the statChange checks (which made it so it only prints once per button press), which means the counter goes up or down by thousands per press. This new value will be compared to the old value after the buttons are released, and the corresponding message, "left" or "right" will be printed. It now works flawlessly, although I still do not understand what caused the problem.

Also, this solution doesn't work with the encoder, but don't plan on using it anyway. Too much hassle.

Code:
/* 
 DESCRIPTION
 ====================
 Simple example of the Bounce library that switches the debug LED when 
 either of 2 buttons are pressed.
 */
 
// Include the Bounce2 library found here :
// https://github.com/thomasfredericks/Bounce2
#include <Bounce2.h>

#define BUTTON_PIN_1 31
#define BUTTON_PIN_2 32


#define LED_PIN 13

// Instantiate a Bounce object
Bounce button1 = Bounce(); 

// Instantiate another Bounce object
Bounce button2 = Bounce(); 

bool statChange = false;
int count = 0;
int oldCount = 0;

void setup() {

  // Setup the first button with an internal pull-up :
  pinMode(BUTTON_PIN_1,INPUT_PULLUP);
  // After setting up the button, setup the Bounce instance :
  button1.attach(BUTTON_PIN_1);
  button1.interval(5); // interval in ms
  
   // Setup the second button with an internal pull-up :
  pinMode(BUTTON_PIN_2,INPUT_PULLUP);
  // After setting up the button, setup the Bounce instance :
  button2.attach(BUTTON_PIN_2);
  button2.interval(5); // interval in ms


  //Setup the LED :
  pinMode(LED_PIN,OUTPUT);

}

void loop() {
  // Update the Bounce instances :
  button1.update();
  button2.update();

// Get the updated value :
  int value1 = button1.read();
  int value2 = button2.read();

  // Turn on the LED if either button is pressed :
  if ( value1 == LOW) {
    digitalWrite(LED_PIN, HIGH );
    count--;
    // Serial.print("Left button pushed, value: ");
    // Serial.print(--count);
  } 
  else if (value2 == LOW) {
    digitalWrite(LED_PIN, HIGH );
    count++;
    // Serial.print("Right button pushed, value: ");
    // Serial.print(++count);
  } 
  else {
    digitalWrite(LED_PIN, LOW );
    if (oldCount < count){
      Serial.println("Left");
    }
    else if (oldCount > count){
      Serial.println("Right");
    }
    oldCount = count;
  }
}
 
Figured out the problem and it's embarrassing: the serial monitor's auto scroll hides the bottom line for some reason. To view that one, you'll have to scroll down.
So, no weird input shenanigans, just me being unobservant.
 
Back
Top