/*
Project: Padel Scoreboard
Description: Use to keep score in a padel match
In a real circuit add 330 ohm resistors on each segment
and transistors on each digit! (Wokwi doesn't care...)
The gray wires are digits, colored are the segments.
Creation date: 5/October/25
Author: Ariel Dupar
*/
#include <LiquidCrystal_I2C.h>
const char PLAYER_1_NAME[] = {"Padel "};
const char PLAYER_2_NAME[] = {"Scoreboard "};
//Definition of Push Buttons
const int SET_PIN = 23;
const int GAME_PIN = 25;
const int POINT_PIN = 27;
const int PLAYER1_PIN = 31;
const int PLAYER2_PIN = 29;
const int RESET_PIN = 33;
// point scores
const uint8_t POINT_SCORES[4] = {15, 30, 40, 41};
// digit pins, 0 - 9
const uint8_t DIGIT_PINS[10] = {8, 9, 10, 11, 12, 3, 4, 5, 6, 7};
// segment pins, A - G
const uint8_t SEG_PINS[7] = {51, 49, 47, 45, 43, 53, 41};
// lookup table, which segments are on for each number,
// 10 numbers, 7 segments
const uint8_t NUM_SEGS[10][7] = {
{1, 1, 1, 1, 1, 1, 0}, /* 0 */
{0, 1, 1, 0, 0, 0, 0}, /* 1 */
{1, 1, 0, 1, 1, 0, 1}, /* 2 */
{1, 1, 1, 1, 0, 0, 1}, /* 3 */
{0, 1, 1, 0, 0, 1, 1}, /* 4 */
{1, 0, 1, 1, 0, 1, 1}, /* 5 */
{1, 0, 1, 1, 1, 1, 1}, /* 6 */
{1, 1, 1, 0, 0, 0, 0}, /* 7 */
{1, 1, 1, 1, 1, 1, 1}, /* 8 */
{1, 1, 1, 1, 0, 1, 1} /* 9 */
};
int currentPlayer = 0;
int sets[2] = {0, 0};
int games[2] = {0, 0};
int points[2] = {0, 0};
int resetcounter=0;
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Function for Write Segmets (Sets/Games/Points)
void writeDigit(int digit, int number) {
// set up the segments
for (int segment = 0; segment < 7; segment++) {
digitalWrite(SEG_PINS[segment], NUM_SEGS[number][segment]);
}
// turn digit on
digitalWrite(DIGIT_PINS[digit], LOW);
// turn digit off
digitalWrite(DIGIT_PINS[digit], HIGH);
}
void checkSet() {
static int oldSetState = HIGH;
int setState = digitalRead(SET_PIN);
if (setState != oldSetState) {
if (setState == LOW) {
if (currentPlayer == 0) {
sets[0] = sets[0] + 1;
if (sets[0] > 9) sets[0] = 0;
} else {
sets[1] = sets[1] + 1;
if (sets[1] > 9) sets[1] = 0;
}
}
oldSetState = setState;
}
delay(20); // debounce
}
void checkGame() {
static int oldGameState = HIGH;
int gameState = digitalRead(GAME_PIN);
if (gameState != oldGameState) {
if (gameState == LOW) {
if (currentPlayer == 0) {
games[0] = games[0] + 1;
if (games[0] > 6) {games[0] = 0;sets[0] = sets[0] + 1;}// Games A > 6, toDo Add +1 Set
} else {
games[1] = games[1] + 1;
if (games[1] > 6) {games[1] = 0;sets[1] = sets[1] + 1;}// Games B > 6, toDo Add +1 Set
}
}
oldGameState = gameState;
}
delay(20); // debounce
}
// To check Add Point + Add New Game + Add New one Set
void AddGame() {
if (currentPlayer == 0) {
games[0] = games[0] + 1;
if (games[0] > 5 ) {games[0] = 0;sets[0] = sets[0] + 1;}// Games A > 6, toDo Add +1 Set
} else {
games[1] = games[1] + 1;
if (games[1] > 5) {games[1] = 0;sets[1] = sets[1] + 1;}// Games B > 6, toDo Add +1 Set
}
}
void checkPoint() {
static int oldPointState = HIGH;
static int pointsTotalOne = 0;
static int pointsTotalTwo = 0;
int pointState = digitalRead(POINT_PIN);
if (pointState != oldPointState) {
if (pointState == LOW) {
if (currentPlayer == 0) {
points[0] = POINT_SCORES[pointsTotalOne];
pointsTotalOne++;
if (pointsTotalOne > 4) {points[0] = 0; pointsTotalOne=0; points[1] = 0; pointsTotalTwo=0; AddGame(); }//Add +1 Game cuando Supera los 4 puntos
} else {
points[1] = POINT_SCORES[pointsTotalTwo];
pointsTotalTwo++;
if (pointsTotalTwo > 4) {points[1] = 0; pointsTotalTwo=0; points[0] = 0; pointsTotalOne=0; AddGame(); }//Add +1 Game cuando Supera los 4 puntos
}
}
oldPointState = pointState;
}
delay(20); // debounce
}
void checkPlayer() {
if (digitalRead(PLAYER1_PIN) == LOW) {currentPlayer = 0;resetcounter=0;}
if (digitalRead(PLAYER2_PIN) == LOW) {currentPlayer = 1;resetcounter=0;}
}
void updateSet() {
writeDigit(0, sets[0]);
writeDigit(5, sets[1]);
}
void updateGame() {
int gameHi[2] = {0, 0};
int gameLo[2] = {0, 0};
gameHi[0] = (games[0] % 100) / 10; // tens
gameHi[1] = (games[1] % 100) / 10; // tens
gameLo[0] = games[0] % 10; // ones
gameLo[1] = games[1] % 10; // ones
writeDigit(1, gameHi[0]);
writeDigit(2, gameLo[0]);
writeDigit(6, gameHi[1]);
writeDigit(7, gameLo[1]);
}
void updatePoint() {
int pointHi[2] = {0, 0};
int pointLo[2] = {0, 0};
pointHi[0] = (points[0] % 100) / 10; // tens
pointHi[1] = (points[1] % 100) / 10; // tens
pointLo[0] = points[0] % 10; // ones
pointLo[1] = points[1] % 10; // ones
writeDigit(3, pointHi[0]);
writeDigit(4, pointLo[0]);
writeDigit(8, pointHi[1]);
writeDigit(9, pointLo[1]);
}
void updatePlayer() {
static int lastPlayer = -1;
if (currentPlayer != lastPlayer) {
lastPlayer = currentPlayer;
lcd.clear(); //LCD Clear
if (currentPlayer == 0) {
lcd.setCursor(0, 0);
lcd.print("Player 1");
lcd.setCursor(13, 0);
} else {
lcd.setCursor(0, 1);
lcd.print("Player 2");
lcd.setCursor(13, 1);
}
lcd.print("(*)");
}
}
void ResetScore(){
//Clean all Variables
lcd.clear();
//Points on 0 values
points[0] = 0;
points[1] = 0;
//Games on 0 values
games[0] = 0;
games[1] = 0;
//Sets on 0 values
sets[0] = 0;
sets[1] = 0;
}
//Check Reset Score Button
void CheckResetScore() {
static int oldResetState = HIGH;
int ResetState = digitalRead(RESET_PIN);
if (ResetState != oldResetState ){
resetcounter++;
//Serial.println(" ");Serial.print("Resetcounter: ");Serial.println(resetcounter);
lcd.clear();
lcd.setCursor(currentPlayer,0);
lcd.print ("2 times-> RESET");
if (resetcounter ==2){//Two times on RESET... clean Scoreboard
//Serial.println(" ");Serial.print("Resetcounter: ");Serial.println(resetcounter);
lcd.clear();
lcd.setCursor(currentPlayer,0);
lcd.print ("RESETING...");
delay(5000);
resetcounter = 0; ResetScore();
}
}
}
void testDisplay() {
writeDigit(0, 0);
writeDigit(1, 1);
writeDigit(2, 2);
writeDigit(3, 3);
writeDigit(4, 4);
writeDigit(5, 5);
writeDigit(6, 6);
writeDigit(7, 7);
writeDigit(8, 8);
writeDigit(9, 9);
}
void setup() {
lcd.init();
pinMode(SET_PIN, INPUT_PULLUP);
pinMode(GAME_PIN, INPUT_PULLUP);
pinMode(POINT_PIN, INPUT_PULLUP);
pinMode(PLAYER1_PIN, INPUT_PULLUP);
pinMode(PLAYER2_PIN, INPUT_PULLUP);
pinMode(RESET_PIN, INPUT_PULLUP);
for (int i = 0; i < 10; i++) {
pinMode(DIGIT_PINS[i], OUTPUT);
digitalWrite(DIGIT_PINS[i], HIGH);
}
for (int i = 0; i < 7; i++) {
pinMode(SEG_PINS[i], OUTPUT);
digitalWrite(SEG_PINS[i], LOW);
}
lcd.backlight();
lcd.setCursor(0, 0);
//StartUp
lcd.print(PLAYER_1_NAME);
lcd.setCursor(0, 1);
lcd.print(PLAYER_2_NAME);
delay(5000);
lcd.clear(); //LCD Clear
lcd.setCursor(0, 0);
lcd.print("Start in 5 secs");
delay(5000);
lcd.clear(); //LCD Clear
Serial.begin(9600); // Serial for debuggin, should be off on final to avoid delays
}
void loop() {
//testDisplay();
CheckResetScore(); //Reset function of Scoreboard
checkPlayer();
checkSet();
checkGame();
checkPoint();
updatePlayer();
updateSet();
updateGame();
updatePoint();
}
Player 1/ Player 2
Sets
Games
Points