I am making a game timer that has two stages.
Stage 1 a countdown until the game begins, this can be 1-3 minutes for example so people can get ready.
Then a long and loud from a buzzer (people will be up to 100 feet away) and then the game timer begins.
At the end the buzzer sounds again for 5 seconds or so loudly and then stops.
This is the code I have made but I am having trouble with making it presentable as it sometimes displays elements like the prep time after the time has finished.
In addition, in the future I want to link a single channel relay to attach a siren, but not sure how the code the relay into it as I never really used one before.
Thank you for your time.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define BUTTON_START_PIN 2
#define BUTTON_SET_UP_PIN 3
#define BUTTON_SET_DOWN_PIN 4
#define BUZZER_PIN 7
LiquidCrystal_I2C lcd(0x27, 16, 2);
unsigned long previousMillis = 0;
const long interval = 1000; // 1 second interval
bool lastTenSeconds = false;
int prepCountdownTimer = 0;
int settingPrepTime = 0; // initial setting time in seconds for prep timer
int gameCountdownTimer = 0;
int settingGameTime = 0; // initial setting time in seconds for game timer
bool settingPrep = false;
bool settingGame = false;
bool prepTimeFinished = false;
bool gameStarted = false;
void setup() {
pinMode(BUTTON_START_PIN, INPUT_PULLUP);
pinMode(BUTTON_SET_UP_PIN, INPUT_PULLUP);
pinMode(BUTTON_SET_DOWN_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Prep Time: 0:00");
}
void loop() {
unsigned long currentMillis = millis();
if (!settingPrep && !settingGame) {
handleSettingTime(settingPrepTime, prepCountdownTimer, "Prep Time: ");
} else if (settingPrep && !settingGame) {
handleSettingTime(settingGameTime, gameCountdownTimer, "Game Time: ");
} else if (settingPrep && settingGame) {
if (!prepTimeFinished) {
handlePrepCountdown();
} else {
handleGameCountdown();
}
}
}
void handleSettingTime(int &settingTime, int &countdown, String title) {
if (digitalRead(BUTTON_SET_UP_PIN) == LOW) {
settingTime += 60; // Increase the time by one minute
if (!settingGame) {
displaySettingTime(settingTime, 0, title);
} else {
displaySettingTime(settingTime, 1, title);
}
delay(200); // Debounce delay
}
if (digitalRead(BUTTON_SET_DOWN_PIN) == LOW && settingTime >= 60) {
settingTime -= 60; // Decrease the time by one minute
if (!settingGame) {
displaySettingTime(settingTime, 0, title);
} else {
displaySettingTime(settingTime, 1, title);
}
delay(200); // Debounce delay
}
if (digitalRead(BUTTON_START_PIN) == LOW && settingTime > 0) {
if (!settingPrep) {
settingPrep = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Prep Time: ");
displaySettingTime(settingPrepTime, 0, "Game Time: ");
} else {
settingGame = true;
lcd.clear();
lcd.print("Starting");
delay(2000);
lcd.clear();
prepCountdownTimer = settingPrepTime;
}
}
}
void handlePrepCountdown() {
handleCountdownHelper(prepCountdownTimer, "Prep Time: ");
if (prepCountdownTimer == 0) {
prepTimeFinished = true;
longBuzzer();
lcd.clear();
lcd.print("Game Started!");
delay(2000);
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Game Time: ");
displaySettingTime(settingGameTime, 1, "Game Time: ");
gameCountdownTimer = settingGameTime;
}
}
void handleGameCountdown() {
handleCountdownHelper(gameCountdownTimer, "Game Time: ");
if (gameCountdownTimer == 0) {
longBuzzer();
lcd.clear();
lcd.print("GAME OVER");
while (true) {
// Game over, do nothing
}
}
}
void handleCountdownHelper(int &countdown, String title) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (countdown > 0) {
if (countdown <= 10) {
lastTenSeconds = true;
digitalWrite(BUZZER_PIN, HIGH);
delay(1000);
digitalWrite(BUZZER_PIN, LOW);
} else {
lastTenSeconds = false;
}
countdown--;
}
if (!settingGame) {
displaySettingTime(countdown, 0, title);
} else {
displaySettingTime(countdown, 1, title);
}
}
}
void displaySettingTime(int time, int row, String title) {
lcd.setCursor(0, row);
lcd.print(title);
lcd.print(time / 60);
lcd.print(":");
if ((time % 60) < 10) {
lcd.print("0");
}
lcd.print(time % 60);
}
void longBuzzer() {
digitalWrite(BUZZER_PIN, HIGH);
delay(5000);
digitalWrite(BUZZER_PIN, LOW);
}