Menu
CoddyTech

Gra reakcji: falstart

Część sekcji Projekty ścieżki Arduino w Coddy. Lekcja 7 z 24.

W tej chwili sprytny gracz może oszukiwać: naciskać przycisk wielokrotnie podczas oczekiwania, aż jedno z naciśnięć przypadnie tuż po zapaleniu się światła. W wyścigach obowiązuje zasada: ruszenie przed sygnałem to falstart, a start zostaje anulowany.

Maszyna stanów już wie, kiedy gracz naciska przycisk za wcześnie: każde naciśnięcie w stanie WAITING. Sprawdź to właśnie tam, przed sprawdzeniem zegara:

case WAITING:
  if (pressed) {
    Serial.println("Too soon!");
    state = READY;
  } else if (millis() - waitStart >= waitTime) {
    // zaświeć diodę LED, tak jak wcześniej
  }
  break;

Powrót do READY kończy rundę: dioda LED nigdy się nie zapala, a następne naciśnięcie rozpoczyna nową grę z nowym losowym czasem oczekiwania. Przy użyciu delay(waitTime) płytka w ogóle nie mogłaby wykryć tego naciśnięcia.

challenge icon

Wyzwanie

Średni

Wykrywaj falstarty:

  • w stanie WAITING naciśnięcie wyświetla Too soon! i powoduje powrót do READY bez zapalenia diody LED
  • cała reszta pozostaje bez zmian: kolejne naciśnięcie rozpoczyna nową rundę

Naciśnij Run, spróbuj szybko nacisnąć dwa razy, a następnie naciśnij Check.

Spróbuj swoich sił

const int ledPin = 12;
const int buttonPin = 2;

// Trzy stany jednej rundy
enum State { READY, WAITING, LIT };
State state = READY;

int lastButton = HIGH;       // poprzedni odczyt stanu przycisku
unsigned long waitStart = 0; // kiedy rozpoczęło się oczekiwanie
unsigned long waitTime = 0;  // jak długo trwa to oczekiwanie
unsigned long litAt = 0;     // kiedy zapaliła się dioda LED

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Press the button to start");
}

void loop() {
  int button = digitalRead(buttonPin);
  bool pressed = (button == LOW && lastButton == HIGH);  // przycisk został właśnie naciśnięty
  lastButton = button;
  unsigned long now = millis();

  switch (state) {
    case READY:
      if (pressed) {
        randomSeed(micros());  // czas naciśnięcia nigdy nie jest dwa razy taki sam
        waitTime = random(1000, 3001);
        waitStart = now;
        state = WAITING;
      }
      break;
    case WAITING:
      if (now - waitStart >= waitTime) {
        digitalWrite(ledPin, HIGH);
        litAt = now;
        state = LIT;
      }
      break;
    case LIT:
      if (pressed) {
        digitalWrite(ledPin, LOW);
        unsigned long reaction = now - litAt;
        Serial.print("Reaction: ");
        Serial.print(reaction);
        Serial.println(" ms");
        state = READY;
      }
      break;
  }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Projekty

Poćwicz samodzielnie: Edytor online Arduino