#include <Wire.h>
#include <LiquidCrystal_I2C.h> // muss installiert werden
#include <EEPROM.h>
// I2C Adresse meist 0x27 oder 0x3F
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Verbindung:
// GND -> GND
// VCC -> 5V
// SDA -> A4
// SCL -> A5
// Buttons Pin 7 and Pin 8
// Buttons GND
const int buttonPin1 = 7; // Button input pin P1
const int buttonPin2 = 8; // Button input pin P2
// ===== HIGH SCORE SYSTEM =====
const int MAX_SCORES = 3;
long highScores[MAX_SCORES] = {0,0,0};
int storedCount = 0;
unsigned long bothPressedStart = 0;
bool bothPressed = false;
void loadScoresFromEEPROM() {
EEPROM.get(0, highScores);
storedCount = 0;
for (int i = 0; i < MAX_SCORES; i++) {
if (highScores[i] != 0) storedCount++;
}
}
void saveScoresToEEPROM() {
EEPROM.put(0, highScores);
}
void tryStoreScore(long newScore) {
// First score always accepted
if (storedCount == 0) {
highScores[0] = newScore;
storedCount = 1;
lcd.clear();
lcd.print("1st Stored!");
delay(1000);
return;
}
// Find current best (minimum value)
long minVal = highScores[0];
for (int i = 1; i < storedCount; i++) {
if (highScores[i] < minVal) {
minVal = highScores[i];
}
}
// Only accept if better (smaller)
if (newScore < minVal) {
if (storedCount < MAX_SCORES) {
highScores[storedCount] = newScore;
storedCount++;
lcd.clear();
lcd.print("Better Score!");
delay(1000);
} else {
lcd.clear();
lcd.print("Top 3 full");
lcd.setCursor(0,1);
lcd.print("No change");
delay(1500);
}
} else {
lcd.clear();
lcd.print("Not better");
delay(1000);
}
}
void checkBothButtons() {
bool b1 = digitalRead(buttonPin1) == LOW;
bool b2 = digitalRead(buttonPin2) == LOW;
if (b1 && b2) {
if (!bothPressed) {
bothPressed = true;
bothPressedStart = millis();
}
if (millis() - bothPressedStart >= 5000) {
saveScoresToEEPROM();
lcd.clear();
lcd.print("Saved EEPROM");
delay(1500);
bothPressed = false;
}
} else {
bothPressed = false;
}
}
// ===== END HIGH SCORE SYSTEM =====
void setup() {
pinMode(buttonPin1, INPUT_PULLUP); // internal pull-up resistor
pinMode(buttonPin2, INPUT_PULLUP); // internal pull-up resistor
lcd.init(); // initialize I2C display
lcd.backlight(); // turn on backlight
loadScoresFromEEPROM(); // <-- added
lcd.setCursor(0,0);
lcd.print("Reaction Timer!");
delay(2000);
lcd.clear();
}
void loop() {
checkBothButtons(); // <-- added
while (digitalRead(buttonPin1) == LOW || digitalRead(buttonPin2) == LOW) { }
lcd.setCursor(0,0);
lcd.print("Get Ready...");
delay(random(3000,6000)); // random wait 3-6 s
lcd.clear();
lcd.setCursor(0,0);
while (digitalRead(buttonPin1) == LOW || digitalRead(buttonPin2) == LOW) {
// wait for button release
}
lcd.print("NOW!");
long startTime = millis();
long reactionTime= 100000;
int winner = 0;
while ((digitalRead(buttonPin1) == HIGH)&&(digitalRead(buttonPin2) == HIGH)) {
// Wait for first valid press
while (true) {
if (digitalRead(buttonPin1) == LOW) {
winner = 1;
break;
}
if (digitalRead(buttonPin2) == LOW) {
winner = 2;
break;
}
}
reactionTime = millis() - startTime;
}
lcd.clear();
lcd.print("P");
lcd.print(winner);
lcd.print(" wins!");
lcd.setCursor(0, 1);
lcd.print("Time:");
lcd.print(reactionTime);
lcd.print(" ms");
delay(2000);
// ===== STORE SCORE HERE =====
tryStoreScore(reactionTime);
// ===== END STORE =====
lcd.clear();
}