Similar project to some others in the forum, but just different enough. If you aren't familiar with the "Domination" game mode, two teams compete for holding a point (could be a fort, a stump, some moose poop, whatever) for the most amount of time.
This project is to count down the 60-minute game timer, while keeping track of how much time each team holds the point. In order to start their team's time, a player must press and release their team's button.
The code I have so far, for the most part, works as intended.
-
I press Orange button to start the game. This starts the 60-minute countdown and actuates Orange relay to blink an external orange light (which only blinks before either team captures the point.. it's basically only so the players can find the box).
-
I can press Blue button to start Blue timer counting up and the Blue relay to actuate an external blinking blue light. Orange relay gets set to LOW so the orange external light is turned off.
-
I can press Green button to pause Blue timer, start Green timer counting up and the Green relay to actuate an external blinking green light. Blue relay gets set to LOW so the blue external light is turned off.
Up to this this point, everything works exactly how it needs to work. However, the next time I press Blue button, it resets Blue timer to 0 and starts counting up again. Everything else works as intended. Same applies to subsequent Green button use.
Goal:
I would very much like it to not reset the teams' respective timers, as that defeats the purpose of the project.
Thanks in advance.
The project is on Wokwi: AI Domination Game - Wokwi ESP32, STM32, Arduino Simulator
Hardware:
- Arduino Uno
- I2C 16x2
- Three momentary arcade buttons
- Three relays
Code:
#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 greenButtonPin = 4; // Green team button pin
const int orangeRelayPin = 5; // Orange relay pin
const int blueRelayPin = 6; // Blue team relay pin
const int greenRelayPin = 7; // Green team relay pin
unsigned long gameStartTime = 0;
unsigned long blueStartTime = 0;
unsigned long greenStartTime = 0;
unsigned long blueElapsedTime = 0;
unsigned long greenElapsedTime = 0;
const unsigned long gameDuration = 3600000; // 60 minutes in milliseconds
bool gameTimerRunning = false;
bool blueTimerRunning = false;
bool greenTimerRunning = false;
bool blueButtonPressed = false;
bool greenButtonPressed = false;
bool blueButtonStatePrev = false;
bool greenButtonStatePrev = false;
void setup() {
lcd.init();
lcd.backlight();
pinMode(orangeButtonPin, INPUT_PULLUP);
pinMode(blueButtonPin, INPUT_PULLUP);
pinMode(greenButtonPin, INPUT_PULLUP);
pinMode(orangeRelayPin, OUTPUT);
pinMode(blueRelayPin, OUTPUT);
pinMode(greenRelayPin, OUTPUT);
lcd.setCursor(2, 0);
lcd.print("GAME 60:00");
lcd.setCursor(0, 1);
lcd.print("B 00:00 G 00:00");
}
void loop() {
bool orangeButtonState = digitalRead(orangeButtonPin) == LOW;
bool blueButtonState = digitalRead(blueButtonPin) == LOW;
bool greenButtonState = digitalRead(greenButtonPin) == LOW;
unsigned long currentTime = millis();
// Check if the game timer is running
if (gameTimerRunning) {
unsigned long elapsedTime = currentTime - gameStartTime;
unsigned long remainingTime = gameDuration - elapsedTime;
// Calculate remaining game time
int gameMinutes = remainingTime / 60000;
int gameSeconds = (remainingTime / 1000) % 60;
displayTime(gameMinutes, gameSeconds);
// Blink orange relay if blue or green timers are not running
if (!blueTimerRunning && !greenTimerRunning) {
// Blink the orange relay (1 second on, 1 second off)
unsigned long orangeRelayTime = currentTime % 2000;
digitalWrite(orangeRelayPin, (orangeRelayTime < 1000));
} else {
// Turn off the orange relay when blue or green timers are running
digitalWrite(orangeRelayPin, LOW);
}
} else {
// Turn off the orange relay when the game timer is not running
digitalWrite(orangeRelayPin, LOW);
}
// Blink blue relay if blue timer is running
if (blueTimerRunning) {
// Blink blue relay (1 second on, 1 second off)
unsigned long blueRelayTime = currentTime % 2000;
digitalWrite(blueRelayPin, (blueRelayTime < 1000));
} else {
// Turn off the blue relay when green timer is running
digitalWrite(blueRelayPin, LOW);
}
// Blink green relay if green timer is running
if (greenTimerRunning) {
// Blink green relay (1 second on, 1 second off)
unsigned long greenRelayTime = currentTime % 2000;
digitalWrite(greenRelayPin, (greenRelayTime < 1000));
} else {
// Turn off the green relay when blue timer is running
digitalWrite(greenRelayPin, LOW);
}
// Check for game start (orange button press)
if (orangeButtonState && !gameTimerRunning) {
startGameTimer(currentTime);
}
// Check blue team button
if (blueButtonState && !blueTimerRunning && !blueButtonPressed && gameTimerRunning) {
startBlueTimer(currentTime);
blueTimerRunning = true;
greenTimerRunning = false;
blueButtonPressed = true;
} else if (!blueButtonState && blueButtonPressed) {
blueElapsedTime += currentTime - blueStartTime;
blueButtonPressed = false;
}
// Check green team button
if (greenButtonState && !greenTimerRunning && !greenButtonPressed && gameTimerRunning) {
startGreenTimer(currentTime);
greenTimerRunning = true;
blueTimerRunning = false;
greenButtonPressed = true;
} else if (!greenButtonState && greenButtonPressed) {
greenElapsedTime += currentTime - greenStartTime;
greenButtonPressed = false;
}
// if (greenTimerRunning && !greenButtonState) {
// greenElapsedTime += currentTime - greenStartTime;
// }
// Check for game end
if (gameTimerRunning && currentTime - gameStartTime >= gameDuration) {
endGameTimer();
}
// Update blue timer if running
if (blueTimerRunning) {
unsigned long blueElapsedTime = currentTime - blueStartTime;
int blueMinutes = blueElapsedTime / 60000;
int blueSeconds = (blueElapsedTime / 1000) % 60;
lcd.setCursor(0, 1);
lcd.print("B ");
if (blueMinutes < 10) {
lcd.print("0");
}
lcd.print(blueMinutes);
lcd.print(":");
if (blueSeconds < 10) {
lcd.print("0");
}
lcd.print(blueSeconds);
}
// Update green timer if running
if (greenTimerRunning) {
unsigned long greenElapsedTime = currentTime - greenStartTime;
int greenMinutes = greenElapsedTime / 60000;
int greenSeconds = (greenElapsedTime / 1000) % 60;
lcd.setCursor(9, 1);
lcd.print("G ");
if (greenMinutes < 10) {
lcd.print("0");
}
lcd.print(greenMinutes);
lcd.print(":");
if (greenSeconds < 10) {
lcd.print("0");
}
lcd.print(greenSeconds);
}
}
void displayTime(int minutes, int seconds) {
lcd.setCursor(6, 0);
lcd.print(" ");
if (minutes < 10) {
lcd.print("0");
}
lcd.print(minutes);
lcd.print(":");
if (seconds < 10) {
lcd.print("0");
}
lcd.print(seconds);
}
void startGameTimer(unsigned long currentTime) {
gameTimerRunning = true;
gameStartTime = currentTime;
}
void endGameTimer() {
gameTimerRunning = false;
lcd.setCursor(6, 0);
lcd.print("GAME OVER");
}
void startBlueTimer(unsigned long startTime) {
blueTimerRunning = true;
blueStartTime = startTime;
}
void startGreenTimer(unsigned long startTime) {
greenTimerRunning = true;
greenStartTime = startTime;
}