Buttons counting their presses shown on LCD screen

Hi everybody. I am working with a project where I am using 4 buttons to count score for a air hockey game. The score is going to be shown on an lcd screen under P1 and P2. I have fixed that two of the buttons count P1, but it dosent work with the two next buttons for P2. Please help, below is my code:

Thanks!

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
// this constant won't change:
const int  Up_buttonPin   = 4;    // the pin that the pushbutton is attached to
const int  Down_buttonPin = 5;
const int  Down_buttonPin2 = 11;
const int Up_buttonPin2 = 12;
// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int up_buttonState = 0;         // current state of the up button
int up_lastButtonState = 0;     // previous state of the up button
int down_buttonState = 0;         // current state of the up button
int down_lastButtonState = 0;     // previous state of the up button
bool bPress = false;
int buttonPushCounter2 = 0;   // counter for the number of button presses
int up_buttonState2 = 0;         // current state of the up button
int up_lastButtonState2 = 0;     // previous state of the up button
int down_buttonState2 = 0;         // current state of the up button
int down_lastButtonState2 = 0;     // previous state of the up button
bool bPress2 = false;
void setup()
{
  Serial.begin(9600);
  pinMode( Up_buttonPin , INPUT_PULLUP);
  pinMode( Down_buttonPin , INPUT_PULLUP);
  pinMode ( Up_buttonPin2 , INPUT_PULLUP);
  pinMode ( Down_buttonPin2 , INPUT_PULLUP);
  lcd.init();                      // initialize the lcd
  lcd.clear();
  lcd.backlight();
  // Print a message to the LCD.
  lcd.setCursor(2,0); //Set cursor to character 2 on line 0
  lcd.print("   Air   ");
  lcd.setCursor(2,1); //Move cursor to character 2 on line 1
  lcd.print("   Hockey   ");
  delay(3000);
  lcd.clear();
  lcd.print(" P1          P2 ");
  lcd.setCursor(0, 1);
  lcd.print(" 0           0");
}
 // lcd.setCursor(2,1);
//  lcd.print(buttonPushCounter);
//}
void loop()
{
   checkUp();
   checkDown();
   if( bPress){
       bPress = false;
      lcd.clear();
      lcd.print(" P1          P2 ");
      lcd.setCursor(2,1);
      lcd.print("                ");
      lcd.setCursor(2,1);
      lcd.print(buttonPushCounter);
      lcd.setCursor(13,1);
      lcd.print(buttonPushCounter2);
   }
}
void checkUp()
{
  up_buttonState = digitalRead(Up_buttonPin);
  // compare the buttonState to its previous state
  if (up_buttonState != up_lastButtonState) {
    // if the state has changed, increment the counter
    if (up_buttonState == LOW) {
        bPress = true;
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  up_lastButtonState = up_buttonState;
    up_buttonState2 = digitalRead(Up_buttonPin2);
  // compare the buttonState to its previous state
  if (up_buttonState2 != up_lastButtonState2) {
    // if the state has changed, increment the counter
    if (up_buttonState2 == LOW) {
        bPress2 = true;
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter2++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter2);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  up_lastButtonState2 = up_buttonState2;
}
void checkDown()
{
  down_buttonState = digitalRead(Down_buttonPin);
  // compare the buttonState to its previous state
  if (down_buttonState != down_lastButtonState) {
    // if the state has changed, increment the counter
    if (down_buttonState == LOW) {
        bPress = true;
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter--;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  down_lastButtonState = down_buttonState;
  down_buttonState2 = digitalRead(Down_buttonPin2);
  // compare the buttonState to its previous state
  if (down_buttonState2 != down_lastButtonState2) {
    // if the state has changed, increment the counter
    if (down_buttonState2 == LOW) {
        bPress2 = true;
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter2--;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter2);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  down_lastButtonState2 = down_buttonState2;
}
1 Like

Welcome to the forum

You only print the values to the LCD if bPress is true which it won't be if the P2 buttons have been pressed

Change

  if ( bPress)

to

  if ( bPress || bPress2)

What happens now?

Thank you so much for helping me out. I tried running you program, but it is still not working since I get the error message 'buttonPushCounter' was not declared in this scope. Do you know what I need to change? Again thanks for helping me:)

The compiler is not wrong. In fact buttonPushCounter is not declared anywhere in the sketch and neither is buttonPushCounter2 for that matter

PushCounter1 and PushCounter2 are, however, declared and it looks like you should be printing them

Okay thanks, but i still dosent work://. I tried this code and got the error message "'PushCounter1'was not declared in this scope":

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

#define Up1_Pin 4 // the pin that the pushbutton is attached to
#define Up2_Pin 12
#define Down1_Pin 5
#define Down2_Pin 11

void setup()
{
Serial.begin(9600);
pinMode( Up1_Pin , INPUT_PULLUP);
pinMode( Up2_Pin , INPUT_PULLUP);
pinMode ( Down1_Pin , INPUT_PULLUP);
pinMode ( Down2_Pin , INPUT_PULLUP);
lcd.init(); // initialize the lcd
lcd.clear();
lcd.backlight();
// Print a message to the LCD.
lcd.setCursor(2, 0); //Set cursor to character 2 on line 0
lcd.print(" Air ");
lcd.setCursor(2, 1); //Move cursor to character 2 on line 1
lcd.print(" Hockey ");
delay(3000);
lcd.clear();
lcd.print(" P1 P2 ");
lcd.setCursor(0, 1);
lcd.print(" 0 0");
}

void loop() {
static uint16_t PushCounter1 = 0; // counter for the number of button presses
static uint16_t PushCounter2 = 0;
static uint8_t bS = 0; //buttons States binary
bS |= (!digitalRead(Up1_Pin)) << 0;
bS |= (!digitalRead(Up2_Pin)) << 1;
bS |= (!digitalRead(Down1_Pin)) << 2;
bS |= (!digitalRead(Down2_Pin)) << 3;
if (bS > 0) {
if (bS == 1 && PushCounter1 < 65000) {
showUp();
PushCounter1++;
Serial.print("number of button1 pushes: ");
Serial.println(PushCounter1);
}
if (bS == 2 && PushCounter1 < 65000) {
showUp();
PushCounter2++;
Serial.print("number of button2 pushes: ");
Serial.println(PushCounter2);
}
if (bS == 4 && PushCounter2 > 0) {
PushCounter2--;
showUp();
Serial.print("number of button2 pushes: ");
Serial.println(PushCounter2);
}
if (bS == 8 && PushCounter2 > 0) {
PushCounter2++;
showUp();
Serial.print("number of button2 pushes: ");
Serial.println(PushCounter2);
}
bS = 0;
delay(15);
}
}

void showUp() {
lcd.clear();
lcd.print(" P1 P2 ");
lcd.setCursor(2, 1);
lcd.print(PushCounter1);
lcd.setCursor(13, 1);
lcd.print(PushCounter2);
delay(15);
}

bPress2 = true;
// if the current state is HIGH then the button went from off to on:
PushCounter2++;
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(PushCounter2);
} else {
// if the current state is LOW then the button went from on to off:
Serial.println("off");
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state, for next time through the loop
up_lastbS2 = up_bS2;
}`

The problem is that these variables

static uint16_t PushCounter1 = 0; // counter for the number of button presses
static uint16_t PushCounter2 = 0;
static uint8_t bS = 0; //buttons States binary

are declared in loop(). Declare them as globals outside of any function instead

Please use code tags when posting code in future

Thanks, the solved that error message. Now it says "bPress2" does not name a type://

With this code I dont get any error messages, but only button 1 (pin 4) is working and it adds 4 points everytime I push it. Very strange... Again thanks for much needed help:)

I take a look

Perfect!

I see now that when I push button 1, it adds points after how long i hold/push the button. The other three buttons are still not working.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

#define  Up1_Pin    4    // the pin that the pushbutton is attached to
#define  Up2_Pin  12
#define  Down1_Pin  5
#define  Down2_Pin  11

uint16_t PushCounter1 = 0;   // counter for the number of button presses
uint16_t PushCounter2 = 0;
uint8_t bS = 0;        //buttons States binary

void setup() {
  Serial.begin(9600);
  pinMode( Up1_Pin , INPUT_PULLUP);
  pinMode( Up2_Pin , INPUT_PULLUP);
  pinMode ( Down1_Pin , INPUT_PULLUP);
  pinMode ( Down2_Pin , INPUT_PULLUP);
  lcd.init();                      // initialize the lcd
  lcd.clear();
  lcd.backlight();
  // Print a message to the LCD.
  lcd.setCursor(2, 0); //Set cursor to character 2 on line 0
  lcd.print("   Air   ");
  lcd.setCursor(2, 1); //Move cursor to character 2 on line 1
  lcd.print("   Hockey   ");
  delay(3000);
  lcd.clear();
  lcd.print(" P1          P2 ");
  lcd.setCursor(0, 1);
  lcd.print(" 0           0");
}

void loop() {
  bS = 0;
  bS |= (!digitalRead(Up1_Pin)) << 0;
  bS |= (!digitalRead(Up2_Pin)) << 1;
  bS |= (!digitalRead(Down1_Pin)) << 2;
  bS |= (!digitalRead(Down2_Pin)) << 3;
  if (bS > 0) {
    if ((bS & (1 << 0)) && PushCounter1 < 999) {
      PushCounter1++;
      showUp();
      Serial.print("number of button1 pushes: ");
      Serial.println(PushCounter1);
      delay(50);
      while (!digitalRead(Up1_Pin));
    }
    if ((bS & (1 << 1)) && PushCounter2 < 999) {
      PushCounter2++;
      showUp();
      Serial.print("number of button2 pushes: ");
      Serial.println(PushCounter2);
      delay(50);
      while (!digitalRead(Up2_Pin));
    }
    if ((bS & (1 << 2)) && PushCounter1 > 0) {
      PushCounter1--;
      showUp();
      Serial.print("number of button1 pushes: ");
      Serial.println(PushCounter1);
      delay(50);
      while (!digitalRead(Down1_Pin));
    }
    if ((bS & (1 << 3)) && PushCounter2 > 0) {
      PushCounter2--;
      showUp();
      Serial.print("number of button2 pushes: ");
      Serial.println(PushCounter2);
      delay(50);
      while (!digitalRead(Down2_Pin));
    }
  }
  //Serial.println(bS, BIN);
}

void showUp() {
  lcd.clear();
  lcd.print(" P1          P2 ");
  lcd.setCursor(1, 1);
  lcd.print(PushCounter1);
  lcd.setCursor(13, 1);
  lcd.print(PushCounter2);
  delay(30);
}
1 Like

Thanks, now button 1 and 2 work as they should. But when I push button 3 and 4 there is no respond. When I check the serial monitor it shows when I push button 1 and 2, but not anything when i push 3 and 4.

is this correct?

and you should make delay bigger. 50.

Yes, that is correct. I have changed the delay now:)

if i try this sketch it works, count up and down

1 Like

You are a hero! It works!!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.