#include <LiquidCrystal_I2C.h>
// Konfiguracja LCD
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adres I2C 0x27, 16 znaków, 2 linie
// Piny
const int clutchPin = 4; // Pin sprzęgła (przycisk)
const int startResetPin = 2; // Pin START/RESET
const int redLedPin = 5; // Czerwona dioda LED
const int greenLedPin = 18; // Zielona dioda LED
// Zmienne stanu
bool clutchPressed = false;
bool startButtonPressed = false;
bool testInProgress = false;
bool waitingForRelease = false;
unsigned long greenLedOnTime = 0;
unsigned long greenLedOffTime = 0;
unsigned long reactionTime = 0;
unsigned long randomDelay = 0;
void setup() {
// Inicjalizacja pinów
pinMode(clutchPin, INPUT_PULLUP);
pinMode(startResetPin, INPUT_PULLUP);
pinMode(redLedPin, OUTPUT);
pinMode(greenLedPin, OUTPUT);
// Inicjalizacja LCD
lcd.init();
lcd.backlight();
lcd.clear();
// Wyświetl powitanie
showWelcomeMessage();
// Wyłącz diody na starcie
digitalWrite(redLedPin, LOW);
digitalWrite(greenLedPin, LOW);
// Inicjalizacja generatora liczb losowych
randomSeed(analogRead(0));
}
void loop() {
// Sprawdź stan sprzęgła
bool currentClutchState = digitalRead(clutchPin) == LOW;
// Sprawdź stan przycisku START/RESET
bool currentStartState = digitalRead(startResetPin) == LOW;
// Obsługa przycisku START/RESET
if (currentStartState && !startButtonPressed) {
startButtonPressed = true;
if (testInProgress) {
resetTest();
} else {
startTestSequence();
}
delay(200); // Debounce
}
if (!currentStartState) {
startButtonPressed = false;
}
if (testInProgress) {
if (waitingForRelease) {
// Test w trakcie - czekamy na zgaśnięcie zielonej diody
if (millis() >= greenLedOffTime) {
digitalWrite(greenLedPin, LOW);
waitingForRelease = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pusc sprzeglo!");
}
// Sprawdź czy zawodnik nie puścił za wcześnie
if (!currentClutchState && clutchPressed) {
clutchPressed = false;
earlyRelease();
}
} else {
// Czekamy na zwolnienie sprzęgła po zgaśnięciu zielonej diody
if (!currentClutchState && clutchPressed) {
clutchPressed = false;
calculateReactionTime();
endTest();
}
}
}
// Aktualizuj stan sprzęgła
if (!currentClutchState) {
clutchPressed = false;
}
}
void startTestSequence() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Przygotuj sie");
lcd.setCursor(0, 1);
lcd.print("Wcisnij sprzeglo");
// Czekaj na wciśnięcie sprzęgła
while(digitalRead(clutchPin) {
delay(10);
// Sprawdź czy nie wciśnięto RESET
if (digitalRead(startResetPin) == LOW) {
resetTest();
return;
}
}
clutchPressed = true;
startTest();
}
void startTest() {
testInProgress = true;
digitalWrite(redLedPin, HIGH);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Czekaj...");
// Losowe opóźnienie przed zapaleniem zielonej diody (1-3 sekundy)
unsigned long waitStart = millis();
while(millis() - waitStart < random(1000, 3000)) {
// Sprawdź czy nie wciśnięto RESET
if (digitalRead(startResetPin) == LOW) {
resetTest();
return;
}
delay(10);
}
digitalWrite(redLedPin, LOW);
digitalWrite(greenLedPin, HIGH);
greenLedOnTime = millis();
// Losowy czas świecenia zielonej diody (1-7 sekund)
randomDelay = random(1000, 7000);
greenLedOffTime = greenLedOnTime + randomDelay;
waitingForRelease = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Trzymaj!");
lcd.setCursor(0, 1);
lcd.print("Czekaj na sygnal");
}
void earlyRelease() {
digitalWrite(greenLedPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Za wczesnie!");
lcd.setCursor(0, 1);
lcd.print("Wcisnij START");
testInProgress = false;
}
void calculateReactionTime() {
reactionTime = millis() - greenLedOffTime;
}
void endTest() {
digitalWrite(greenLedPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Czas reakcji:");
lcd.setCursor(0, 1);
lcd.print(reactionTime);
lcd.print(" ms");
unsigned long displayStart = millis();
while(millis() - displayStart < 5000) {
// Jeśli wciśnięto RESET, przerwij wyświetlanie
if (digitalRead(startResetPin) == LOW) {
resetTest();
return;
}
delay(10);
}
resetTest();
}
void resetTest() {
testInProgress = false;
waitingForRelease = false;
clutchPressed = false;
digitalWrite(redLedPin, LOW);
digitalWrite(greenLedPin, LOW);
showWelcomeMessage();
}
void showWelcomeMessage() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Test refleksu");
lcd.setCursor(0, 1);
lcd.print("START - zaczynaj");
}