Simple Score Keeper

I am very new to programming, and have spent all day trying to figure out how to do this. Any help would be appreciated!

I'm trying to get my LCD to display a score, and have that score increase in value when a Button is pushed. I cannot find a single clear tutorial or example of this anywhere on the internet...

added a pic of my LCD scoreboard so far,
Here's my code, and a lot of the stuff I'm missing is in comment caps:

#include <LiquidCrystal.h>

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

  int Score = 0;

void setup() {

  //input pins for scoring triggers
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  
  // set up the LCD:
  lcd.begin(16, 2);
  lcd.clear();


    // display player One
  lcd.print("PLAYER ONE:");
}

void loop() {

  //IF BUTTON IS PUSHED, (A0 goes high) ADD 10 POINTS
  //IF BUTTON IS PUSHED, (A1 goes high) ADD 30 POINTS

  lcd.setCursor(0, 1);
  // score sum total
  lcd.print(Score);
}

One of the things you have to consider is "debouncing" your buttons, to avoid getting multiple readings each time you press a button. A button "bounces" when it's pressed, generating multiple opens/closes.
This might help in that regard:-
Debounce

Then you could increment a counter each time the button receives a valid press and update the LCD.

I like using Nick Gammon's offering Switch Manager.
The library can be downloaded from here.
Discussed here:

See reply #2

Looks like you are on the right track, neat wiring.
.

Here's the image attached to the top post.

How to insert an uploaded image.

I don't see "INPUT_PULLUP" being used and based on the code, I'm guessing you're using a pull-down resistor. Is this right?

So the button is active high?

LarryD - I' check out the library, thanks. Is there not a simple way to do this without installing new libraries into the arduino? Because I'm a beginner and that seems like yet another process that can cause setbacks... Also in browsing the article, while it has a lot of explanation on switches and debouncing, but doesn't appear to have any info on adding values of triggers to a sum total, which is my current primary concern.

I don't see "INPUT_PULLUP" being used and based on the code, I'm guessing you're using a pull-down resistor. Is this right?

So the button is active high?

I currently don't have a PULLUP or pull-down anything set in place. I just connected a button to the A0 pin. I am still learning what those do. But sense I don't know how to program a point value to be added to a displayed total, the wiring really isn't my primary concern right now.

All I really want to know, is how to program a point value to be added to the sum total.

A simple debounce method is to just read a switch every 50ms or so, looking for a change in state.

The library does let you examine timed pushes.
For example, if a switch is pressed for say 3 seconds then reset your score board.
For less than 100ms increment a count.
Different timed pushes can do different functions.

yea, I got that. But I currently am asking how to have that successfully trigger a value to be added to my total score.

scarybeard:
a lot of the stuff I'm missing is in comment caps:

...

  //IF BUTTON IS PUSHED, (A0 goes high) ADD 10 POINTS

//IF BUTTON IS PUSHED, (A1 goes high) ADD 30 POINTS
}

Hi Scarybeard! Are you asking about how to increment the score values with your code?
As you mentioned that you are relatively new to coding, I have a couple of pointers that hopefully may help you.
First, may I suggest that you either use a variable to store your pin assignments in, or what I do is define a constant since those values don't change throughout your code's execution. This way, as your code grows, you have an easy way of keeping track of what pin goes to what and makes it much more human-readable not only to other people but yourself (you yourself will have a hard time remembering what the pin numbers are for a few weeks after writing the code, making it harder to revise). Also it means that should you need to change that pin for any reason as your project develops, you only need to change it in your code once as opposed to everywhere that that specific pin number appears in your code.
Here is an example of the method that I use, near the top of my sketch, I'll put something like

#define PIN_LED 13
#define PIN_SENSOR A1

and so on for all the pins I'm planning on using. You may find this to be a time saving practice and keep your code as organized as your wiring is (your wiring is very neat and easy to follow by the way, nice work)

Second,
to increment the value when a button is pressed, you'll need a couple things in your code where those comments are.
One thing you'll need is a conditional statement such as an
If statement (also, once you understand how to use a library, definitely look into the debounce solutions mentioned here by LarryD and OldSteve).
Another piece you'll need to have is an assignment statement like addition.

int a = 0;
int b = 0;

//addition example a
a = a + 5;

//addition example b
a += 5;

The example a takes the current value of a, adds 5, then stores the result in the variable a.
Example b in this case does the same thing, but uses a compound assignment operator += to accomplish the same task.

Well I hope this helps! Let us know how the project is going along, looks like you're well on your way to getting your scoreboard working! Keep going!

~Nichole

And you must add a pullup or pulldown resistor to your pushbutton to keep it in a known state when it isn't pressed, as mentioned, or the pin will "float" resulting in unpredictable false button presses. Getting the code right will only be useful if you also get the hardware right. :wink:

scarybeard:
yea, I got that. But I currently am asking how to have that successfully trigger a value to be added to my total score.

Here's a link to the button tutorial. It explains how to wire a button.

If x is your variable then to add one to x you'd use:

x++;

To add to x if pin A0 had been set as an a active low button using "INPUT_PULLUP" you'd use:

if (digitalRead(A0) == LOW)
  {
    x++;
  }

The "A" pins can be used for analog inputs. They're usually only used for buttons if you're running out of the normal digital pins.

scarybeard:
I am very new to programming, and have spent all day trying to figure out how to do this. Any help would be appreciated!

I'm trying to get my LCD to display a score, and have that score increase in value when a Button is pushed. I cannot find a single clear tutorial or example of this anywhere on the internet...

added a pic of my LCD scoreboard so far,
Here's my code, and a lot of the stuff I'm missing is in comment caps:

something like this is OK for now...

boolean lastReadButton1;
boolean lastReadButton2;

void loop() {

  //IF BUTTON IS PUSHED, (A0 goes high) ADD 10 POINTS
  // look for LOW to HIGH edge (button change)
  boolean readButton1 = digitalRead(pin_of_button_1);
  if (readButton1 == HIGH and lastReadButton1 == LOW)
  {  
      score = score + 10;
  }
  lastReadButton1 = readButton1;

  //IF BUTTON IS PUSHED, (A1 goes high) ADD 30 POINTS
  // look for LOW to HIGH edge (button change)
  boolean readButton2 = digitalRead(pin_of_button_2);
  if (readButton2 == HIGH and lastReadButton2 == LOW)
  {  
      score = score + 30;
  }
  lastReadButton2 = readButton2;


  lcd.setCursor(0, 1);
  // score sum total
  lcd.print(Score);
}

Thank you all! excellent info! I'll get to work on this and post my success or further problems! :slight_smile:

It works!

I'm sure this is not the most elegant solution to the sketch but it currently works.

Button A gives me 1 point when pressed,
Button B gives me 100 points when pressed.

Here's my code, and a pic of my wiring:

#include <LiquidCrystal.h>

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

  int Score = 0000;
  int a = 1;
  int b = 100;

void setup() {

  //input pins for scoring triggers
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
 
  // set up the LCD:
  lcd.begin(16, 2);
  lcd.clear();


    // display player One
  lcd.print("PLAYER ONE:");
}

void loop() {

  //IF BUTTON IS PUSHED, (A0 goes LOW) ADD 1 POINTS

if (digitalRead(A0) == LOW)
  {
    delay(500);
    Score = a + Score;
  }
  
  //IF BUTTON IS PUSHED, (A1 goes LOW) ADD 100 POINTS


if (digitalRead(A1) == LOW)
  {
    delay(500);
    Score = b + Score;
  }

  lcd.setCursor(0, 1);
  // score sum total
  lcd.print(Score);
}

Good start!

Now it's time to master some techniques:
Learn to use the best type to save RAM
unsigned int Score = 0; // scores don't usually go negative.
byte a = 1;
byte b = 100;

delay(500); // this freezes your sketch for 1/2 a second which is almost always not what you want.
Better look into blink without delay, an example comes with the IDE.

pinMode(A0, INPUT_PULLUP); // is usually done so you don't need a physical PULLUP resistor.

Also the sooner you learn about de-bouncing switches the better off you will be.
.

It looks like you are using delay(500) to give you time to release your finger, and count only once. Not a good permanent solution.

The next step for you is to remove the delay and instead either use edge triggering as above, or if necessary, use button debounce code.

ok I'm going to try and refine the code now and make it more usable. I'm still trying to digest the debounce and boolean info right now. Here's a quick question about byte though:

Now it's time to master some techniques:
Learn to use the best type to save RAM
unsigned int Score = 0; // scores don't usually go negative.
byte a = 1;
byte b = 100;

What is the benefit to using ( byte a = 1; ) over using ( int a = 1; )? also, in reading the reference on 'byte' it mentions that it will only work for values up to 255? Does that mean I could not have a ( byte c = 1000; )?

Ram is quite limited on the ARDUINO.
byte uses one byte (8 bits) of RAM. 0-255 range
int uses two bytes (16 bits) of RAM. -32,768 to 32,767 range
unsigned int two bytes (16 bits) of RAM 0-65535 range

you need
unsigned int c = 1000;

Data Types:
https://learn.sparkfun.com/tutorials/data-types-in-arduino

.

ok here's a weird behavior I cant figure out.

I want the game to start with 5 balls.
When a button is pushed you loose 1 ball
when (balls < 1) I want "GAME OVER' displayed

So this all works great, except when "GAME OVER" Appears there is still a 1 where the ball credits are displayed. I would like that to go away. I'm not sure why it's there.

Even weirder, if I hit (LOST BALL) again after game over appears, I get 6 credits. It remains at 6 no matter how many times I push it after that.

Here's the code and a pic of my "GAME OVER" state with the 1 unwanted credit:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

  boolean lastReadButton1;
  boolean lastReadButton2;


  unsigned int score = 0;
  unsigned int ballnumber = 5;
  int a = 100;


// SETUP===========================================
void setup() {

//input pins for scoring triggers
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);

// set up the LCD:
  lcd.begin(16, 2);
  lcd.clear();

}

//LOOP==============================================
void loop() {

//LCD TOP ROW: SCORE / GAME OVER

  lcd.setCursor(0, 0);

  if (ballnumber < 1)
  {  
    lcd.print("GAME OVER      ");
  }
  else
  {
  lcd.print("SCORE:    BALL:");
  lcd.print(ballnumber);
  }

//LCD BOTTOM ROW: NUMERIC SCORE
  
  lcd.setCursor(0, 1);
  lcd.print(score);

//SCORE a 100 PTS //////////////////////////////////////
   boolean readButton1 = digitalRead(A0);
  
  if (readButton1 == LOW and lastReadButton1 == HIGH)
  { 
      score = score + a;
  }
  lastReadButton1 = readButton1;

  
//LOST BALL///////////////////
   boolean readButton2 = digitalRead(A1);
  
  if (readButton2 == LOW and lastReadButton2 == HIGH)
  { 
      ballnumber = ballnumber - 1;
  }
  lastReadButton2 = readButton2;


}

When <1 clear the screen.
You better learn to handle bounce in your switches.

I don't recall how your switches are wired but you may need INPUT_PULLUP in pinMode.