/*
Arduino | hardware-help
reaction time game
jubilant_quokka_50345 Saturday, October 25, 2025 11:34 AM
can someone verify?
https://www.tinkercad.com/things/lfNQY2mWsLY-ingenious-densor-snaget?sharecode=HJ7A-mKtT0La3KH2qbXO1Fd5YlKFHwHzeK_G8P0NIt0
*/
#include <LiquidCrystal.h>
// Pin definitions
const int buttonPins[] = {6, 4, A3, A1}; // Button pins corresponding to LEDs
const int ledPins[] = {5, 3, A2, A0}; // LED pins (3 red, 1 yellow)
// LCD pins: RS, EN, D4, D5, D6, D7
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
// Game states
enum GameState { WAIT_LED, WAIT_PRESS, SHOW_RESULT, SHOW_WRONG };
GameState state = WAIT_LED;
unsigned long stateStartTime = 0;
unsigned long ledOnTime = 0;
unsigned long randomDelay = 0;
int targetIndex = 0; // Index of the correct LED/button
unsigned long reactionTime = 0;
void setup() {
// Initialize LED pins as outputs and set LOW
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
digitalWrite(ledPins[i], LOW);
}
// Initialize button pins as inputs with pull-up resistors
for (int i = 0; i < 4; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
// Initialize LCD with 16 columns and 2 rows
lcd.begin(16, 2);
// Seed random using an unconnected analog pin
randomSeed(analogRead(A5));
// Display initial message
lcd.print("Get Ready...");
// Set initial random delay between 1 and 5 seconds (1000-5000 ms)
randomDelay = random(1000, 5001);
stateStartTime = millis();
}
void loop() {
unsigned long currentTime = millis();
switch (state) {
case WAIT_LED:
// After random delay, light up a random LED
if (currentTime - stateStartTime >= randomDelay) {
targetIndex = random(0, 4); // 0 to 3
digitalWrite(ledPins[targetIndex], HIGH);
ledOnTime = currentTime;
// Prompt user to react
lcd.clear();
lcd.print("Go!");
state = WAIT_PRESS;
}
break;
case WAIT_PRESS:
// Check for button press (active LOW)
for (int i = 0; i < 4; i++) {
if (digitalRead(buttonPins[i]) == LOW) {
// Turn off the LED immediately
digitalWrite(ledPins[targetIndex], LOW);
// Check if correct button
if (i == targetIndex) {
reactionTime = currentTime - ledOnTime;
lcd.clear();
lcd.print("Time: ");
lcd.print(reactionTime);
lcd.print(" ms");
state = SHOW_RESULT;
} else {
lcd.clear();
lcd.print("Wrong Button!");
state = SHOW_WRONG;
}
stateStartTime = currentTime;
break;
}
}
break;
case SHOW_RESULT:
// Display result for 2 seconds, then start new round
if (currentTime - stateStartTime >= 2000) {
lcd.clear();
lcd.print("Get Ready...");
randomDelay = random(1000, 5001);
stateStartTime = currentTime;
state = WAIT_LED;
}
break;
case SHOW_WRONG:
// Display wrong message for 2 seconds, then start new round
if (currentTime - stateStartTime >= 2000) {
lcd.clear();
lcd.print("Get Ready...");
randomDelay = random(1000, 5001);
stateStartTime = currentTime;
state = WAIT_LED;
}
break;
}
}