#include <TM1637Display.h>
// ======== ADJUSTABLE PARAMETERS ========
const uint8_t RELAY1_PIN = 8; // Player 1 LED (via relay)
const uint8_t RELAY2_PIN = 9; // Player 2 LED (via relay)
const uint8_t VIBE1_PIN = 2; // Player 1 vibration sensor
const uint8_t VIBE2_PIN = 3; // Player 2 vibration sensor
const uint8_t DISPLAY_CLK1 = 4; // TM1637 CLK pin
const uint8_t DISPLAY_DIO1 = 5; // TM1637 DIO pin
const uint8_t DISPLAY_CLK2 = 6; // TM1637 CLK pin
const uint8_t DISPLAY_DIO2 = 7; // TM1637 DIO pin
const bool logicFlagRelay = HIGH; // Relay/LED active logic (HIGH or LOW)
const bool logicFlagVibe = LOW; // Vibe sensor active logic (HIGH or LOW)
const uint16_t FLASH_COUNT = 3; // “Get ready” flash count
const uint16_t FLASH_ON_MS = 1000; // Flash ON duration (ms)
const uint16_t FLASH_OFF_MS = 1000; // Flash OFF duration (ms)
const uint16_t RANDOM_MIN_MS = 5000; // Min random “wait” (ms)
const uint16_t RANDOM_MAX_MS = 10000; // Max random “wait” (ms)
const uint16_t REACT_TIMEOUT = 5000; // Timeout for each hit (ms)
const uint16_t DISPLAY_TIME = 10000; // How long to show times (ms)
// ======== GLOBAL OBJECTS ========
TM1637Display display1(DISPLAY_CLK1, DISPLAY_DIO1);
TM1637Display display2(DISPLAY_CLK2, DISPLAY_DIO2);
void setup() {
Serial.begin(9600);
// LEDs/relays
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
// Ensure both off at start
digitalWrite(RELAY1_PIN, !logicFlagRelay);
digitalWrite(RELAY2_PIN, !logicFlagRelay);
// Vibe sensors
pinMode(VIBE1_PIN, INPUT_PULLUP);
pinMode(VIBE2_PIN, INPUT_PULLUP);
display1.setBrightness(0x0f); // Max brightness
display1.showNumberDec(0, true); // Clear display
display2.setBrightness(0x0f); // Max brightness
display2.showNumberDec(0, true); // Clear display
randomSeed(analogRead(A0)); // Seed RNG
Serial.println("Start the Game");
}
void loop() {
// 1) “Get ready” both LEDs
flashReady();
// 2) Random pre-start delay
uint32_t randDelay = random(RANDOM_MIN_MS, RANDOM_MAX_MS);
Serial.print("Current Random Time:");
Serial.println(randDelay);
delay(randDelay);
// 3) Turn both LEDs on, start timer
digitalWrite(RELAY1_PIN, logicFlagRelay);
digitalWrite(RELAY2_PIN, logicFlagRelay);
uint32_t tStart = millis();
// 4) Detect first hit
uint32_t hitTime = 0;
uint8_t firstPlayer = 0;
bool player1Hit = false, player2Hit = false; // Flag to get set when a player hits
bool fastFlashLed1 = false, fastFlashLed2 = false; // Flag to be set to flash respective led
int led1FlashCount = 0, led2FlashCount = 0; // Varible to hold the flash count of each led
uint32_t lastLed1FlashTime = 0, lastLed2FlashTime = 0; // Note Last time of led 1 and led 2 flash
while ((millis() - tStart < REACT_TIMEOUT) && firstPlayer == 0) {
if (digitalRead(VIBE1_PIN) == logicFlagVibe && player1Hit == false) {
player1Hit = true;
fastFlashLed1 = true; // Fast Flash LED 1
hitTime = millis() - tStart;
// display1.displayInt(hitTime);
display1.showNumberDec(hitTime, true);
}
if (digitalRead(VIBE2_PIN) == logicFlagVibe && player2Hit == false) {
player2Hit = true;
fastFlashLed2 = true; // Fast Flash LED 1
hitTime = millis() - tStart;
// display2.displayInt(hitTime);
display2.showNumberDec(hitTime, true);
}
if (led1FlashCount < 6 && (millis() - lastLed1FlashTime) > 300 && player1Hit) {
digitalWrite(RELAY1_PIN, !digitalRead(RELAY1_PIN)); // Read current state and reverse it
lastLed1FlashTime = millis(); // Note current time
led1FlashCount++; // Increase flash count
}
if (led2FlashCount < 6 && (millis() - lastLed2FlashTime) > 300 && player2Hit) {
digitalWrite(RELAY2_PIN, !digitalRead(RELAY2_PIN)); // Read current state and reverse it
lastLed2FlashTime = millis(); // Note current time
led2FlashCount++; // Increase flash count
}
}
// 5) Turn both LEDs off immediately
digitalWrite(RELAY1_PIN, !logicFlagRelay);
digitalWrite(RELAY2_PIN, !logicFlagRelay);
Serial.println("TimeOut");
// 7) Hold both times visible
delay(DISPLAY_TIME);
// Clear displays
// display1.displayClear();
// display2.displayClear();
display1.showNumberDec(0, true); // Clear
display2.showNumberDec(0, true); // Clear
}
// ======== HELPERS ========
// “Get ready” flash on both LEDs
void flashReady() {
Serial.println("Start Flashing to make Both user ready");
for (uint8_t i = 0; i < FLASH_COUNT; i++) {
digitalWrite(RELAY1_PIN, logicFlagRelay);
digitalWrite(RELAY2_PIN, logicFlagRelay);
delay(FLASH_ON_MS);
digitalWrite(RELAY1_PIN, !logicFlagRelay);
digitalWrite(RELAY2_PIN, !logicFlagRelay);
delay(FLASH_OFF_MS);
}
}