From 606219b8bd2b94c8a7f1022e4da9576c920b6b57 Mon Sep 17 00:00:00 2001 From: Robin Cerny Date: Sat, 19 Apr 2025 08:48:59 +0200 Subject: [PATCH] implemented 'end screen' to be displayed when the fight timer ends. Cleaned up some comments --- .../ROFLS_Arena_Controller.ino | 104 +++++++++++++++--- .../ROFLS_Arena_Pit_Controller.ino | 2 +- 2 files changed, 87 insertions(+), 19 deletions(-) diff --git a/ROFLS_Arena_Controller/ROFLS_Arena_Controller.ino b/ROFLS_Arena_Controller/ROFLS_Arena_Controller.ino index 460dab9..02fd850 100644 --- a/ROFLS_Arena_Controller/ROFLS_Arena_Controller.ino +++ b/ROFLS_Arena_Controller/ROFLS_Arena_Controller.ino @@ -3,7 +3,6 @@ #include #include // automatically installed for ESP32 boards, I think? #include // automatically installed for ESP32 boards -#include // https://fastled.io/ #include // https://github.com/avdwebLibraries/avdweb_Switch #include // https://github.com/RobTillaart/CountDown #include // https://github.com/RobTillaart/StopWatch_RT @@ -59,9 +58,9 @@ unsigned long PITopenTimestamp = 0; bool PITreleased = false; const long PITopenTime = 500; // default: 500 activate solenoid for 500ms -const int countdownTIME = 30; // default: 180 countdown timer length in seconds, actual countdown for the fight +const int countdownTIME = 180; // default: 180 countdown timer length in seconds, actual countdown for the fight const int countdownToFightTIME = 3; // default: 3 countdown timer length in seconds, "ready" countdown -const int PITreleaseTime = 15; // default: 90 automatic pit release time in seconds until end of countdown +const int PITreleaseTime = 90; // default: 90 automatic pit release time in seconds until end of countdown bool countdownPAUSED = false; CountDown FightCountDown(CountDown::SECONDS); CountDown ReadyCountDown(CountDown::SECONDS); @@ -164,13 +163,19 @@ void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) { break; case 1: // RED team button - buttonREDTEAMvar = receiveDATA.buttonREDTEAM; - buttonREDTEAMtapout = receiveDATA.buttonREDTEAMtapout; + // ignore button input if in rumble mode + if (!switchRUMBLE.on()) { + buttonREDTEAMvar = receiveDATA.buttonREDTEAM; + buttonREDTEAMtapout = receiveDATA.buttonREDTEAMtapout; + } break; case 2: // BLUE team button - buttonBLUETEAMvar = receiveDATA.buttonBLUETEAM; - buttonBLUETEAMtapout = receiveDATA.buttonBLUETEAMtapout; + // ignore button input if in rumble mode + if (!switchRUMBLE.on()) { + buttonBLUETEAMvar = receiveDATA.buttonBLUETEAM; + buttonBLUETEAMtapout = receiveDATA.buttonBLUETEAMtapout; + } break; } } @@ -199,6 +204,15 @@ bool blueTapOutActive = false; unsigned long blueTapOutStartTime = 0; int blueTapOutStage = 0; +// Global Vars for Fight end +bool fightStarted = false; +bool fightEnded = false; +const int END_BLINK_COUNT = 3; +const unsigned long END_BLINK_INTERVAL = 500; // in milliseconds +int endBlinkTransitions = 0; +bool endBlinkState = false; +unsigned long lastEndBlinkTime = 0; + //------------------------------------------------------------------------------------ void setup() { @@ -301,12 +315,16 @@ void handleStartButton() { buttonREDTEAMvar = false; buttonBLUETEAMvar = false; ARENA_READY = true; + REDTEAM_LED(true); + BLUETEAM_LED(true); ReadyCountDown.start(countdownToFightTIME); } else if (buttonREDTEAMvar && buttonBLUETEAMvar && !switchRUMBLE.on()) { buttonREDTEAMvar = false; buttonBLUETEAMvar = false; ARENA_READY = true; + REDTEAM_LED(true); + BLUETEAM_LED(true); ReadyCountDown.start(countdownToFightTIME); } } @@ -319,6 +337,8 @@ void handleStartButton() { resumeFight = true; // Mark that we want to resume later. countdownPAUSED = false; ARENA_READY = true; + REDTEAM_LED(true); + BLUETEAM_LED(true); ReadyCountDown.start(countdownToFightTIME); } else if (switchRUMBLE.on()) { @@ -327,6 +347,8 @@ void handleStartButton() { resumeFight = true; countdownPAUSED = false; ARENA_READY = true; + REDTEAM_LED(true); + BLUETEAM_LED(true); ReadyCountDown.start(countdownToFightTIME); } } @@ -410,6 +432,7 @@ void handleCountdownTransition() { } else { FightCountDown.start(countdownTIME); // Fresh start. + fightStarted = true; } } else if (switchRUMBLE.on()) { @@ -447,7 +470,7 @@ void updateDisplay() { } } -// Redesigned endless cycling for Red Team tap-out. +// endless cycling for Red Team tap-out. void handleRedTapOut() { // When the red tap-out is first triggered. if (!redTapOutActive && buttonREDTEAMtapout && !switchRUMBLE.on() && !blueTapOutActive) { @@ -461,8 +484,8 @@ void handleRedTapOut() { // If tap-out is active, continuously update the display in a cycle. if (redTapOutActive) { - // Define a full cycle period of 10'000 ms. - const unsigned long cycleDuration = 10000; + // Define a full cycle period of 8'000 ms. + const unsigned long cycleDuration = 8000; // Compute how far into the current cycle we are. unsigned long cycleTime = (millis() - redTapOutStartTime) % cycleDuration; @@ -481,7 +504,7 @@ void handleRedTapOut() { } } -// Redesigned endless cycling for Blue Team tap-out. +// endless cycling for Blue Team tap-out. void handleBlueTapOut() { // When the blue tap-out is first triggered. if (!blueTapOutActive && buttonBLUETEAMtapout && !switchRUMBLE.on() && !redTapOutActive) { @@ -495,8 +518,8 @@ void handleBlueTapOut() { // If tap-out is active, continuously update the display in a cycle. if (blueTapOutActive) { - // Define a full cycle period of 10'000 ms. - const unsigned long cycleDuration = 10000; + // Define a full cycle period of 8'000 ms. + const unsigned long cycleDuration = 8000; // Compute the cycle progress. unsigned long cycleTime = (millis() - blueTapOutStartTime) % cycleDuration; @@ -515,6 +538,44 @@ void handleBlueTapOut() { } } +void handleFightEnd() { + // When the countdown hits 0 and the fight had started, mark it as ended. + if ((FightCountDown.remaining() == 0) && fightStarted) { + fightEnded = true; + } + + // Only do blinking if the fight has ended. + if (!fightEnded) { + return; // Skip the rest until fightEnded becomes true. + } + + // Each full blink cycle includes an "on" and "off" state. + // Therefore, we count transitions: total transitions = END_BLINK_COUNT * 2. + const int totalTransitions = END_BLINK_COUNT * 2 + 1; + + // If we haven't completed our full blink sequence, manage timing: + if (endBlinkTransitions < totalTransitions) { + unsigned long currentMillis = millis(); + if (currentMillis - lastEndBlinkTime >= END_BLINK_INTERVAL) { + endBlinkState = !endBlinkState; // Toggle between on and off states. + endBlinkTransitions++; // Count this toggle. + lastEndBlinkTime = currentMillis; // Reset the timer. + } + + // Depending on the blink state, update the display. + // When endBlinkState is true, use the normal brightness. + // When false, replace CLOCK_LED_BRIGHTNESS with 0 to blank the display. + if (endBlinkState) { + sendTimeDisplay(0, 0, 255, 165, 0, CLOCK_LED_BRIGHTNESS); + } else { + sendTimeDisplay(0, 0, 255, 165, 0, 0); + } + } else { + // After completing the blink sequence, ensure that the display remains on. + sendTimeDisplay(0, 0, 255, 165, 0, CLOCK_LED_BRIGHTNESS); + } +} + //---------------------------------------------------------------------------------------- @@ -526,6 +587,7 @@ void loop() { statusLEDs(); updateTEAMLEDs(); + // Process button events. handleStartButton(); handleForcedStartButton(); @@ -533,9 +595,12 @@ void loop() { handlePitButton(); handleAutoPitRelease(); - // Process non-blocking tap-out sequences. - handleRedTapOut(); - handleBlueTapOut(); + + // Process tap-out sequences. + if (!switchRUMBLE.on()) { + handleRedTapOut(); + handleBlueTapOut(); + } // Handle reset if (buttonRESETvar) { @@ -547,8 +612,11 @@ void loop() { // Transition from ReadyCountDown to the appropriate fight countdown. handleCountdownTransition(); - // When no team is in a tap‐out sequence, update the display. - if (!redTapOutActive && !blueTapOutActive) { + // End display + handleFightEnd(); + + // When no team is in a tap‐out sequence and fight hasn't ended, update the display. + if (!redTapOutActive && !blueTapOutActive && !fightEnded) { updateDisplay(); } } diff --git a/ROFLS_Arena_Pit_Controller/ROFLS_Arena_Pit_Controller.ino b/ROFLS_Arena_Pit_Controller/ROFLS_Arena_Pit_Controller.ino index 941273a..3db02cb 100644 --- a/ROFLS_Arena_Pit_Controller/ROFLS_Arena_Pit_Controller.ino +++ b/ROFLS_Arena_Pit_Controller/ROFLS_Arena_Pit_Controller.ino @@ -13,7 +13,7 @@ #define ACTUATED_PULSE 1000 // Actuated position // Define the reset time in milliseconds -#define RESET_TIME_MS 500 +#define RESET_TIME_MS 1000 // Create two Servo objects for the two servos Servo servo1;