Basic LCD Counter help

I want to start this post by saying that I am completely new to Arduino and C/C++.

I'm trying to code a simple counter using pushbuttons and a 16x2 LCD. However, when the code is run, the counter just alternates between 1 and 0. Can anyone help me diagnose and fix the problem?

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  lcd.begin(16, 2);
  pinMode(8, INPUT);
  pinMode(13, INPUT);
}

int counter = 0;
int up = 0;
int down = 0;
int upLast = 0;
int downLast = 0;

void loop() {
  if(digitalRead(8) == LOW) {
    counter = counter + 1;
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print(life);
    lcd.setCursor(0,0);
    lcd.print("Counter");
    delay(200);
  }
  if(digitalRead(13) == LOW) {
    counter = counter - 1;
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print(life);
    lcd.setCursor(0,0);
    lcd.print("Counter");
    delay(200);
  }
}

How are your buttons connected? Do you external pull-ups?
If not...

 pinMode(8, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);
}

Nope. Even if I do replace it with INPUT_PULLUP, the problem persists.

Hmmm...

In your loop function you seem to be printing out a variable called "life" where I would expect you to be printing the value of counter

void loop() {
  if(digitalRead(8) == LOW) {
    counter = counter + 1;
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print(life);                        //<-- Would have expected you would output counter here
    lcd.setCursor(0,0);
    lcd.print("Counter");
    delay(200);
  }
  if(digitalRead(13) == LOW) {
    counter = counter - 1;
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print(life);                        //<-- Would have expected you would output counter here
    lcd.setCursor(0,0);
    lcd.print("Counter");
    delay(200);
  }
}

I'm not sure what "life" is but it is obviously defined somewhere or your sketch would not compile.

Ian

zenith5720:
Nope. Even if I do replace it with INPUT_PULLUP, the problem persists.

That might mean that both of your input pins are shorted to Ground. Try disconnecting one of the pins to see if that stops the number from going 0 1 0 1 0 1 0 1

I'm not sure what "life" is but it is obviously defined somewhere or your sketch would not compile.

I put "Life" because it was for a life counter for Magic The Gathering. I edited it out for "counter" to make you better understand it. In the original code every "counter" was replaced with "life" so it's not that that's the issue.

That might mean that both of your input pins are shorted to Ground. Try disconnecting one of the pins to see if that stops the number from going 0 1 0 1 0 1 0 1

The issue still persists. If it helps, im using an Arduino simulator (Tinkercad, to be exact).

Detect button state change instead of checking state

IoT_hobbyist:
Detect button state change instead of checking state

Here are the changes I did:

void loop() {
  if(digitalRead(8) == LOW && upLast == HIGH) {
    counter = counter + 1;
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print(life);
    lcd.setCursor(0,0);
    lcd.print("Counter");
    delay(200);
  }
  if(digitalRead(9) == LOW && downLast == HIGH) {
    counter = counter - 1;
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print(life);
    lcd.setCursor(0,0);
    lcd.print("Counter");
    delay(200);
  }
  upLast = digitalRead(8);
  downLast = digitalRead(9);
}

The counter now just stays at 0 despite button changes, but its still an improvement.

Now, @pcbbc, you know noobs always connect their buttons to Vcc, so INPUT_PULLUP is usless, unless the button is connected to GND. :slight_smile:

zenith5720:
I put "Life" because it was for a life counter for Magic The Gathering. I edited it out for "counter" to make you better understand it. In the original code every "counter" was replaced with "life" so it's not that that's the issue.

Make me better understand it....Really? It reads like incomprehensible nonsense.

zenith5720:
I put "Life" because it was for a life counter for Magic The Gathering. I edited it out for "counter" to make you better understand it. In the original code every "counter" was replaced with "life" so it's not that that's the issue.

The issue still persists. If it helps, im using an Arduino simulator (Tinkercad, to be exact).

Ok...

However in both occasions where you have listed code (your original post and reply #7) you do not print out the content of the variable "counter" but you do print out the content of the variable "life" (note lower case l). You are printing the word Counter.
loop function from original post:-

void loop() {
  if(digitalRead(8) == LOW) {
    counter = counter + 1;
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print(life);                                     // <-- prints the value of life (lower case l)
    lcd.setCursor(0,0);
    lcd.print("Counter");
    delay(200);
  }
  if(digitalRead(13) == LOW) {
    counter = counter - 1;
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print(life);                                     // <-- prints the value of life (lower case l)
    lcd.setCursor(0,0);
    lcd.print("Counter");
    delay(200);
  }
}

loop function from reply #7:-

void loop() {
  if(digitalRead(8) == LOW && upLast == HIGH) {
    counter = counter + 1;
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print(life);                                     // <-- still printing life (lower case l)
    lcd.setCursor(0,0);
    lcd.print("Counter");
    delay(200);
  }
  if(digitalRead(9) == LOW && downLast == HIGH) {
    counter = counter - 1;
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print(life);                                     // <-- still printing life (lower case l)
    lcd.setCursor(0,0);
    lcd.print("Counter");
    delay(200);
  }
  upLast = digitalRead(8);
  downLast = digitalRead(9);
}

Is this the code you are actually running on Tinkercad?

Ian

  1. post actual complete sketch code copied and paste red direct fromIDE, not snippets or incorrect retypes.
  2. post a circuit diagram of how you have the buttons connected.

JCA34F:
Now, @pcbbc, you know noobs always connect their buttons to Vcc, so INPUT_PULLUP is usless, unless the button is connected to GND. :slight_smile:

Yes, but the code is expecting LOW for button pressed.
And as input PULL-UP didn’t fix it we must assume the button is actually pulled low somehow.
Perhaps the OP has buttons to Vcc and strong external pull downs, but that seems a bit much to expect...

Although as we’ve actually to see the actual code being run (just snippets and re-typings so far) it really is impossible to help.

Just wondering...
Did you want to count negative numbers?
Did you want the built in LED to show when you count down?
On a real UNO, a stripped down version of your code works.
(using serial printer, print counter, INPUT_PULLUP, jumper wire for switch to GND)

The code works now. I've also added serial and comments for better readability and feedback from the Arduino itself.

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//begin lcd, designate pins 8 and 9 to input
void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(8, INPUT);
  pinMode(9, INPUT);
  lcd.print("Counter");
  lcd.setCursor(0,1);
  lcd.print("0");
}

//declare variables for counter, upLast, and downLast
int counter = 0;
int upLast = 0;
int downLast = 0;

void loop() {  
  //detect if the "up" button state has changed
  if(digitalRead(8) == LOW && upLast == HIGH) {
    //update lcd counter
    Serial.println("up button triggered");
    counter = counter + 1;
    lcd.clear();
    delay(50);
    lcd.setCursor(0,1);
    lcd.print(counter);
    lcd.setCursor(0,0);
    lcd.print("Counter");
    delay(200);
  }
  //detect if the "down" button state has changed
  if(digitalRead(9) == LOW && downLast == HIGH) {
    //update lcd counter
    Serial.println("down button triggered");
    counter = counter - 1;
    lcd.clear();
    delay(50);
    lcd.setCursor(0,1);
    lcd.print(counter);
    lcd.setCursor(0,0);
    lcd.print("Counter");
    delay(200);
  }
  //update upLast and downLast
  upLast = digitalRead(8);
  downLast = digitalRead(9);
}