#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <SPI.h>
// Definicja pinów
#define TFT_CS 17
#define TFT_RST 5
#define TFT_DC 16
#define TFT_MOSI 23
#define TFT_SCK 18
#define TFT_MISO 19
#define START_BUTTON_PIN 34
#define CLUTCH_BUTTON_PIN 35
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST, TFT_MISO);
enum State { IDLE, PREPARE, READY, MEASURE, RESULT };
State currentState = IDLE;
unsigned long prepareStartTime;
unsigned long readyStartTime;
unsigned long reactionTime;
unsigned long randomDelay;
void setup() {
Serial.begin(115200);
pinMode(START_BUTTON_PIN, INPUT_PULLUP);
pinMode(CLUTCH_BUTTON_PIN, INPUT_PULLUP);
tft.begin();
tft.setRotation(3);
tft.fillScreen(ILI9341_BLACK);
drawIdleScreen();
}
void loop() {
switch(currentState) {
case IDLE:
if (digitalRead(START_BUTTON_PIN) == LOW) {
delay(200); // Debounce
currentState = PREPARE;
prepareStartTime = millis();
drawPrepareScreen();
}
break;
case PREPARE:
if (digitalRead(CLUTCH_BUTTON_PIN) == LOW) {
currentState = READY;
readyStartTime = millis();
randomDelay = random(1000, 7001); // Losowe opóźnienie 1-7 sekund
drawReadyScreen();
} else if (millis() - prepareStartTime > 3000) {
// Zawodnik nie wcisnął sprzęgła w czasie 3 sekund
currentState = IDLE;
drawErrorScreen("Nie wcisnieto sprzegla!");
delay(2000);
drawIdleScreen();
}
break;
case READY:
if (digitalRead(CLUTCH_BUTTON_PIN) == HIGH) {
// Zawodnik puścił sprzęgło przed czasem
currentState = IDLE;
drawErrorScreen("Za wczesnie!");
delay(2000);
drawIdleScreen();
} else if (millis() - readyStartTime > randomDelay) {
currentState = MEASURE;
drawMeasureScreen();
}
break;
case MEASURE:
if (digitalRead(CLUTCH_BUTTON_PIN) == HIGH) {
reactionTime = millis() - (readyStartTime + randomDelay);
currentState = RESULT;
drawResultScreen(reactionTime);
}
break;
case RESULT:
if (digitalRead(START_BUTTON_PIN) == LOW) {
delay(200); // Debounce
currentState = IDLE;
drawIdleScreen();
}
break;
}
}
void drawIdleScreen() {
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(50, 50);
tft.println("TEST CZASU REAKCJI");
tft.setCursor(80, 100);
tft.println("START/RESET");
tft.fillCircle(160, 180, 40, ILI9341_BLACK);
tft.fillCircle(160, 180, 40, ILI9341_BLACK);
}
void drawPrepareScreen() {
tft.fillScreen(ILI9341_BLACK);
tft.fillCircle(160, 120, 60, ILI9341_RED);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(80, 200);
tft.println("Wcisnij sprzeglo");
}
void drawReadyScreen() {
tft.fillScreen(ILI9341_BLACK);
tft.fillCircle(160, 120, 60, ILI9341_GREEN);
}
void drawMeasureScreen() {
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(100, 120);
tft.println("PUSC!");
}
void drawResultScreen(unsigned long time) {
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(3);
tft.setCursor(80, 80);
tft.println("Wynik:");
tft.setTextSize(4);
tft.setCursor(60, 140);
tft.print(time);
tft.println(" ms");
tft.setTextSize(2);
tft.setCursor(60, 200);
tft.println("START - reset");
}
void drawErrorScreen(const char* message) {
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_RED);
tft.setTextSize(2);
tft.setCursor(40, 120);
tft.println(message);
}