// Need to fix the blue team position and make led flash for the team
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Initialize the LCD
const int orangeButtonPin = 2; // Orange button pin
const int blueButtonPin = 3; // Blue team button pin
const int redButtonPin = 4; // Red team button pin
const int orangeRelayPin = 5; // Orange relay pin
const int blueRelayPin = 6; // Blue team relay pin
const int redRelayPin = 7; // Red team relay pin
const int buzzer = 8; // Buzzer pin
const unsigned long buttonHoldTime = 3000; // 3 seconds in milliseconds
unsigned long blueButtonPressStartTime = 0; // Start time for blue button press
unsigned long redButtonPressStartTime = 0; // Start time for red button press
bool blueButtonPressedForLong = false; // Flag to check if blue button was pressed long enough
bool redButtonPressedForLong = false; // Flag to check if red button was pressed long enough
unsigned long gameStartTime = 0;
unsigned long blueStartTime = 0;
unsigned long redStartTime = 0;
unsigned long blueElapsedTime = 0;
unsigned long redElapsedTime = 0;
unsigned long blueTime = 0;
unsigned long redTime = 0;
unsigned long bluePausedTime = 0;
unsigned long redPausedTime = 0;
unsigned long gameDuration = 900000; // Default to 15 minutes in milliseconds
bool gameTimerRunning = false;
bool blueTimerRunning = false;
bool redTimerRunning = false;
bool blueButtonStatePrev = false;
bool redButtonStatePrev = false;
void setup() {
lcd.init();
lcd.backlight();
pinMode(orangeButtonPin, INPUT_PULLUP);
pinMode(blueButtonPin, INPUT_PULLUP);
pinMode(redButtonPin, INPUT_PULLUP);
pinMode(orangeRelayPin, OUTPUT);
pinMode(blueRelayPin, OUTPUT);
pinMode(redRelayPin, OUTPUT);
pinMode(buzzer, OUTPUT); // Set buzzer as output
lcd.setCursor(2, 0);
lcd.print("SURFERS PROP");
lcd.setCursor(3, 1);
lcd.print("DOMINATION");
// Wait for 5 seconds before continuing
delay(5000); // 5000 milliseconds = 5 seconds
// Now show the adjusted game time
lcd.setCursor(0, 1);
lcd.print("B 00:00 R 00:00");
displayAdjustedGameTime(); // Show the initial game time
}
void loop() {
bool blueButtonState = digitalRead(blueButtonPin) == LOW;
bool redButtonState = digitalRead(redButtonPin) == LOW;
unsigned long currentTime = millis();
// Adjust game time before the game starts
if (!gameTimerRunning) {
adjustGameTime(blueButtonState, redButtonState);
}
// Check for game start (orange button press)
if (digitalRead(orangeButtonPin) == LOW && !gameTimerRunning) {
startGameTimer(currentTime);
}
// If game timer is running, handle blue and red team actions
if (gameTimerRunning) {
updateGameTime(currentTime);
handleButtonPress(blueButtonPin, blueButtonPressStartTime, blueButtonPressedForLong, blueTimerRunning, blueStartTime, bluePausedTime, blueTime, currentTime, redRelayPin, redTimerRunning);
handleButtonPress(redButtonPin, redButtonPressStartTime, redButtonPressedForLong, redTimerRunning, redStartTime, redPausedTime, redTime, currentTime, blueRelayPin, blueTimerRunning);
}
// Handle simultaneous button presses for both teams
if (blueButtonState && redButtonState) {
tone(buzzer, 6000, 100); // Play sound when both buttons are pressed
}
// Update the display and button states
blueButtonStatePrev = blueButtonState;
redButtonStatePrev = redButtonState;
updateTeamTimers(currentTime);
}
void adjustGameTime(bool blueButtonState, bool redButtonState) {
if (blueButtonState && !blueButtonStatePrev) {
if (gameDuration > 60000) {
gameDuration -= 60000;
}
displayAdjustedGameTime();
delay(300); // Debounce delay
}
if (redButtonState && !redButtonStatePrev) {
gameDuration += 60000;
displayAdjustedGameTime();
delay(300); // Debounce delay
}
}
void updateGameTime(unsigned long currentTime) {
unsigned long elapsedTime = currentTime - gameStartTime;
unsigned long remainingTime = (elapsedTime <= gameDuration) ? (gameDuration - elapsedTime) : 0;
int gameMinutes = (remainingTime / 60000); // Calculate minutes
int gameSeconds = (remainingTime / 1000) % 60; // Calculate seconds
displayTime(gameMinutes, gameSeconds);
if (remainingTime == 0) {
blueTimerRunning = false;
redTimerRunning = false;
gameTimerRunning = false;
displayWinner();
}
// Blink orange relay if blue or red timers are not running
if (!blueTimerRunning && !redTimerRunning) {
unsigned long orangeRelayTime = currentTime % 2000;
digitalWrite(orangeRelayPin, (orangeRelayTime < 1000));
} else {
digitalWrite(orangeRelayPin, LOW);
}
}
void displayTime(int minutes, int seconds) {
lcd.setCursor(1, 0);
lcd.print("GAME ");
lcd.setCursor(8, 0);
lcd.print(minutes < 10 ? "0" : "");
lcd.print(minutes);
lcd.print(":");
lcd.print(seconds < 10 ? "0" : "");
lcd.print(seconds);
}
void displayAdjustedGameTime() {
int minutes = gameDuration / 60000;
int seconds = (gameDuration / 1000) % 60;
lcd.setCursor(0, 0);
lcd.print("Game Time: ");
lcd.print(minutes < 10 ? "0" : "");
lcd.print(minutes);
lcd.print(":");
lcd.print(seconds < 10 ? "0" : "");
lcd.print(seconds);
}
void startGameTimer(unsigned long currentTime) {
gameTimerRunning = true;
gameStartTime = currentTime;
// Clear top line, but do not overwrite bottom line repeatedly
lcd.setCursor(0, 0);
lcd.print(" "); // Clear top line
// Don't clear the bottom line every loop, update only when necessary
lcd.setCursor(0, 1);
lcd.print("B 00:00 R 00:00");
}
void handleButtonPress(int buttonPin, unsigned long &buttonPressStartTime, bool &buttonPressedForLong, bool &timerRunning, unsigned long &startTime, unsigned long &pausedTime, unsigned long &teamTime, unsigned long currentTime, int otherRelayPin, bool &otherTimerRunning) {
bool buttonState = digitalRead(buttonPin) == LOW;
if (buttonState && buttonPressStartTime == 0) {
buttonPressStartTime = currentTime; // Start tracking the button press time
}
if (buttonState) {
unsigned long pressDuration = currentTime - buttonPressStartTime;
if (pressDuration >= buttonHoldTime) {
buttonPressedForLong = true; // Mark the button as being pressed long enough
}
} else {
buttonPressStartTime = 0; // Reset if button is released
}
if (buttonPressedForLong && !timerRunning) {
startTime = currentTime - teamTime;
timerRunning = true;
// Stop the other team's timer if running
if (otherTimerRunning) {
pausedTime += currentTime - startTime;
otherTimerRunning = false;
digitalWrite(otherRelayPin, LOW);
}
// Activate the correct team's LED
if (buttonPin == blueButtonPin) {
digitalWrite(blueRelayPin, HIGH);
} else if (buttonPin == redButtonPin) {
digitalWrite(redRelayPin, HIGH);
}
buttonPressedForLong = false; // Reset the flag
tone(buzzer, 1000, 200); // Play confirmation sound
}
}
void updateTeamTimers(unsigned long currentTime) {
if (blueTimerRunning) {
unsigned long blueElapsed = currentTime - blueStartTime;
blueTime = blueElapsed / 1000; // Convert to seconds
}
if (redTimerRunning) {
unsigned long redElapsed = currentTime - redStartTime;
redTime = redElapsed / 1000; // Convert to seconds
}
// Only update the bottom line if the time has changed
static unsigned long lastBlueTime = 0;
static unsigned long lastRedTime = 0;
if (blueTime != lastBlueTime || redTime != lastRedTime) {
lastBlueTime = blueTime;
lastRedTime = redTime;
// Clear the bottom line before printing the updated times
lcd.setCursor(0, 1);
lcd.print(" "); // Clear the line
int blueMinutes = blueTime / 60;
int blueSeconds = blueTime % 60;
int redMinutes = redTime / 60;
int redSeconds = redTime % 60;
lcd.setCursor(1, 1);
lcd.print("B ");
lcd.print(blueMinutes < 10 ? "0" : "");
lcd.print(blueMinutes);
lcd.print(":");
lcd.print(blueSeconds < 10 ? "0" : "");
lcd.print(blueSeconds);
lcd.print(" R ");
lcd.print(redMinutes < 10 ? "0" : "");
lcd.print(redMinutes);
lcd.print(":");
lcd.print(redSeconds < 10 ? "0" : "");
lcd.print(redSeconds);
}
}
void displayWinner() {
if (blueTime > redTime) {
lcd.setCursor(0, 0);
lcd.print("BLUE WINS! ");
} else if (redTime > blueTime) {
lcd.setCursor(0, 0);
lcd.print("RED WINS! ");
} else {
lcd.setCursor(0, 0);
lcd.print("DRAW! ");
}
}