Dart Scoreboard

Hi, I need help changing this keypad calculator code so that it subtracts like a dart scoreboard. I'm testing it out in the serial monitor. I want to be able to display 501 and count down automatically when the score is inputted, and be able to reset. i plan to test on seven segments later but I'm not worried about that right now. Any advice would be helpful ! thank you .

#include <Keypad.h>

const byte numRows = 4; //number of rows on the keypad
const byte numCols = 4; //number of columns on the keypad

//keymap defines the key pressed according to the row and columns just as appears on        the keypad
char keymap[numRows][numCols] =
{
    {'1', '2', '3', '+'},
    {'4', '5', '6', '-'},
    {'7', '8', '9', 'C'},
    {'0', ' ', '=', 'D'}
};

//Code that shows the the keypad connections to the arduino terminals
byte rowPins[numRows] = {5, 4, 3, 2}; //connect to the row pinouts of the kpd
byte colPins[numCols] = {9, 8, 7, 6}; //connect to the column pinouts of the kpd

//initializes an instance of the Keypad class
Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

long num1, num2, answer;
boolean mySwitch = false;
boolean do_subtraction_flag = false;  // when true we will apply subtraction
int x = 501;

void setup()
{
    Serial.begin(9600);
    num1 = 0;
    num2 = 0;
}

//If key is pressed, this key is stored in 'keypressed' variable
//If key is not equal to 'NO_KEY', then this key is printed out
//if count=17, then count is reset back to 0 (this means no key is pressed during the   whole keypad scan process


void loop()
{
    char keypressed = myKeypad.getKey();

    if(keypressed != NO_KEY)
    {

        //Serial.print(keypressed - 48);
        Serial.print(keypressed);

        if(keypressed > 47 && keypressed < 58)  // is between '0' and '9'
        {
            if(!mySwitch)
            {
                num1 = (num1 * 10) + (keypressed - 48);
            }
            else
            {
                num2 = (num2 * 10) + (keypressed - 48);
            }
        }

        if(keypressed == '=')
        {
            if(do_subtraction_flag)  // we want to subtract the numbers
            {
                answer = num1 - num2;
            }
            else  // we want to add the numbers
            {
                answer = num1 + num2;
           }

            Serial.println(answer);
            num1 = 0;
            num2 = 0;
            mySwitch = false;
            do_subtraction_flag = false;
        }
        else if(keypressed == '+')
        {
            mySwitch = true;
        }
        else if(keypressed == '-')
        {
            mySwitch = true;
            do_subtraction_flag = true;
        }
    }
}

keypad_calculator.ino (2.27 KB)

Please post the code here to avoid the need to download it.

UKHeliBob:
Please post the code here to avoid the need to download it.

edited

            {
                num1 = (num1 * 10) + (keypressed - 48);
            }

This section of code adds the latest digit to the previously entered number which is how you would enter the score

       if(keypressed == '=')
        {
            if(do_subtraction_flag)  // we want to subtract the numbers
            {
                answer = num1 - num2;
            }

This section subtracts one number from another when the = key is pressed. For your purposes the first number would be the current total and the other one would be the latest score. In practice you would use num1 instead of answer in the calculation because you need a running total.

You also need to switch between 2 separate scores, one for each player. You can do this most easily by using an array for the running total and changing the array index to the other player after each calculation.

UKHeliBob:

            {

num1 = (num1 * 10) + (keypressed - 48);
            }



This section of code adds the latest digit to the previously entered number which is how you would enter the score



if(keypressed == '=')
        {
            if(do_subtraction_flag)  // we want to subtract the numbers
            {
                answer = num1 - num2;
            }



This section subtracts one number from another when the = key is pressed. For your purposes the first number would be the current total and the other one would be the latest score. In practice you would use num1 instead of answer in the calculation because you need a running total.

You also need to switch between 2 separate scores, one for each player. You can do this most easily by using an array for the running total and changing the array index to the other player after each calculation.

how would i start at 501 and count down from there?

how would i start at 501 and count down from there?

Using the variable names from the program that you uploaded, set num1 to 501, perhaps when * is entered to start the scoring, input num2 from the keypad then when = is pressed

num1 = num1 - num2;

will give you the remainder in num1 ready for the next score to be deducted for that player.

UKHeliBob:
Using the variable names from the program that you uploaded, set num1 to 501, perhaps when * is entered to start the scoring, input num2 from the keypad then when = is pressed

num1 = num1 - num2;

will give you the remainder in num1 ready for the next score to be deducted for that player.

i dont fully understand what you are saying and not sure what to change, could you please explain more?

If I were you I would tackle the project in stages.

First write a program to read the keypad, create the score and print it when the = key is pressed.
Build the number using

            {
                score = (score * 10) + (keypressed - 48);
            }

Next a program that subtracts the score from the running total (which you initialise to 501 in the program) and print it. Each time you enter = set num1 to num1 minus the score.

Then a program that initialises num1 to 501 when you press * on the keypad ready to start a new game.

UKHeliBob:
If I were you I would tackle the project in stages.

First write a program to read the keypad, create the score and print it when the = key is pressed.
Build the number using

            {

score = (score * 10) + (keypressed - 48);
            }




Next a program that subtracts the score from the running total (which you initialise to 501 in the program) and print it. Each time you enter = set num1 to num1 minus the score.

Then a program that initialises num1 to 501 when you press * on the keypad ready to start a new game.

Okay Thank you for your help, I do sort of understand what you are getting at, i found a youtube video that may help also, thanks again.

UKHeliBob:
If I were you I would tackle the project in stages.

First write a program to read the keypad, create the score and print it when the = key is pressed.
Build the number using

            {

score = (score * 10) + (keypressed - 48);
            }




Next a program that subtracts the score from the running total (which you initialise to 501 in the program) and print it. Each time you enter = set num1 to num1 minus the score.

Then a program that initialises num1 to 501 when you press * on the keypad ready to start a new game.

I've got this far, i can display 501 at the start then enter a value with up to 3 digits, and it will output 501 - whatever, but without displaying the entered score. Im stuck on trying to continue on from the last score entered, please help.

#include <Keypad.h>

int firstnumber = 99;
int secondnumber = 99;
int thirdnumber = 99;
int keyfullnumber = 0;
const byte numRows = 4; //number of rows on the keypad
const byte numCols = 4; //number of columns on the keypad

//keymap defines the key pressed according to the row and columns just as appears on        the keypad
char keymap[numRows][numCols] =
{
    {'1', '2', '3', '+'},
    {'4', '5', '6', '-'},
    {'7', '8', '9', 'C'},
    {'0', ' ', '=', 'D'}
};

//Code that shows the the keypad connections to the arduino terminals
byte rowPins[numRows] = {5, 4, 3, 2}; //connect to the row pinouts of the kpd
byte colPins[numCols] = {9, 8, 7, 6}; //connect to the column pinouts of the kpd

//initializes an instance of the Keypad class
Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

volatile int GAMESTARTVALUE = 501;
volatile int PLAYERScore = 0;
//volatile int Score1 = 0;
void setup(){
  Serial.begin(9600);
  Serial.println(501);
}
  
void loop(){
  char key = myKeypad.getKey();
  if (key != NO_KEY){
    switch (key){

      case '1':
        checknumber(1);
      break;
      
      case '2':
        checknumber(2);
      break;
      
      case '3':
        checknumber(3);
      break;
      
      case '4':
        checknumber(4);
      break;
      
      case '5':
        checknumber(5);
      break;

      case '6':
        checknumber(6);
      break;
      
      case '7':
        checknumber(7);
      break;
      
      case '8':
        checknumber(8);
      break;
      
      case '9':
        checknumber(9);
      break;
      
      case '0':
        checknumber(0);
      break;

      case '=':
       subtractnumber();
      break;
      
//      case ' ':
//        deletenumber();
//      break;
        
    }
  }
}

  void checknumber(int x){
    if (firstnumber == 99) {
      firstnumber = x;
    } else {
      if (secondnumber == 99) {
        secondnumber = x;
      } else {
        thirdnumber = x;
      }
    }
    
  }

  void subtractnumber() {
    if (thirdnumber == 99 && secondnumber == 99 && firstnumber != 99) {
      keyfullnumber = firstnumber;
      if (PLAYERScore - keyfullnumber >= 0) {
        PLAYERScore = PLAYERScore - keyfullnumber;
        }
      }
    if (secondnumber != 99 && thirdnumber == 99) {
      keyfullnumber = (firstnumber*10) + secondnumber;
      if (PLAYERScore - keyfullnumber >= 0) {
        PLAYERScore = PLAYERScore - keyfullnumber;
      }
    }
    if (thirdnumber != 99) {
     keyfullnumber = (firstnumber*100) + (secondnumber*10) + thirdnumber;
      if (PLAYERScore - keyfullnumber >= 0) {
        PLAYERScore = PLAYERScore - keyfullnumber;
      }
    }
    PLAYERScore = GAMESTARTVALUE - keyfullnumber;
    Serial.println(PLAYERScore);
  }

Here is some code that should do what you want using the serial monitor.

Enter an integer in the serial monitor and it will be subtracted from a player's score. Enter 'D' to switch players. When a score gets to zero the player is crowned the winner and scoring begins again at 501.

Maybe this can be a starting point for integrating the keypad library.

/*

 Dart Scores
 
 In serial monitor:
 
 D -> switch players
 
 integer -> score for currnet player
 
 Scores start at 501, first to zero wins.  
 
 */


// number of players
const int NUM_PLAYERS = 4;

// scores for each player
int scores[NUM_PLAYERS];

// index into scores array
int playerIdx = 0;

// scoreBpard
//
// Show scores for each player
//
void scoreBpard()
{
  Serial.println();

  // while more players
  for(int i = 0; i < NUM_PLAYERS; i++)
  {
    // show score
    Serial.print("Player :");
    Serial.print(i+1);
    Serial.print("  ");
    Serial.println(scores[i]);

  } // for 

}

// initScores
//
// Set all scores to 501
//
void initScores()
{
  // while more players
  for(int i = 0; i < NUM_PLAYERS; i++)
  {
    scores[i] = 501;  // initial score

  } // for 

}

void setup()
{
  Serial.begin(9600);


  initScores();    // set initial scores
  scoreBpard();    // show score board

  // prompt for score
  Serial.println("Enter score for player  1");
}



void loop()
{
  byte inChar;
  int score;

  if( Serial.available() )
  {
    // if first char is switch player char 
    if( Serial.peek() == 'D' ) {

      // read it
      inChar = Serial.read();

      // switch player 
      playerIdx = ++playerIdx%NUM_PLAYERS;

      // prompt for score
      Serial.print("Enter score for player  ");
      Serial.println(playerIdx+1);

    } 
    else {

      // read score 
      score = Serial.parseInt();

      // record score read
      scores[playerIdx] -= score;

      // show scores on serial monitor
      scoreBpard();

      // if we have a winner
      if( scores[playerIdx] <= 0 )
      {
        Serial.print(playerIdx+1);
        Serial.println(":  wins!");
        Serial.println();

        // reset scores
        initScores();

        // prompt for score
        playerIdx = 0;
        Serial.print("Enter score for player  ");
        Serial.println(playerIdx+1);

      } // if

    } // else

  } // if


}

I think that an RPN calculator would do what the OP wants.