#include <TaskScheduler.h>
// Pin Definitions
const int LED_PIN = 13; // LED output pin
const int BUTTON_PIN = 2; // Button input pin
// Game State Variables
volatile bool gameStarted = false;
volatile bool ledOn = false;
volatile unsigned long ledOnTime = 0;
volatile unsigned long reactionTime = 0;
// Scheduler
Scheduler runner;
// Callback function prototypes
void randomLedOn();
void checkButton();
void resetGame();
// Task definitions
Task tRandomLed(0, TASK_ONCE, &randomLedOn);
Task tCheckButton(50, TASK_FOREVER, &checkButton);
Task tResetGame(3000, TASK_ONCE, &resetGame);
void setup() {
// Initialize serial communication
Serial.begin(115200);
// Pin mode setup
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
// Add tasks to the scheduler
runner.init();
runner.addTask(tRandomLed);
runner.addTask(tCheckButton);
runner.addTask(tResetGame);
// Welcome message
Serial.println("LED Reaction Time Game");
Serial.println("Press the button when the LED lights up!");
// Start the first game cycle
startNewRound();
}
void loop() {
// Run the scheduler
runner.execute();
}
void startNewRound() {
// Randomize delay before LED turns on
unsigned long randomDelay = random(1000, 5000);
tRandomLed.setDelay(randomDelay);
tRandomLed.enable();
}
void randomLedOn() {
// Turn on LED
digitalWrite(LED_PIN, HIGH);
ledOn = true;
ledOnTime = millis();
// Set a timeout for button press
tResetGame.enableDelayed(3000);
}
void checkButton() {
// Check if button is pressed and LED is on
if (ledOn && digitalRead(BUTTON_PIN) == LOW) {
// Calculate reaction time
reactionTime = millis() - ledOnTime;
// Turn off LED
digitalWrite(LED_PIN, LOW);
// Display reaction time
Serial.print("Reaction Time: ");
Serial.print(reactionTime);
Serial.println(" ms");
// Disable related tasks
tRandomLed.disable();
tResetGame.disable();
// Prepare for next round
gameStarted = false;
ledOn = false;
// Schedule next round
startNewRound();
}
}
void resetGame() {
// If no button press, reset the game
digitalWrite(LED_PIN, LOW);
Serial.println("Too slow! Try again.");
// Reset game state
gameStarted = false;
ledOn = false;
// Start a new round
startNewRound();
}