Menu
CoddyTech

Reaktionsspiel: Fehlstart

Teil des Abschnitts Projekte der Arduino-Journey von Coddy. Lektion 7 von 24.

Im Moment kann ein cleverer Spieler schummeln: Während der Wartezeit immer wieder drücken, und einer der Tastendrücke erfolgt direkt nach dem Aufleuchten. Bei Rennen gibt es dafür eine Regel: Wer sich vor dem Signal bewegt, begeht einen Fehlstart, und der Start wird abgebrochen.

Die Zustandsmaschine weiß bereits, wann der Spieler zu früh dran ist: bei jedem Tastendruck im Zustand WAITING. Prüfe das dort, bevor du die Uhr abfragst:

case WAITING:
  if (pressed) {
    Serial.println("Too soon!");
    state = READY;
  } else if (millis() - waitStart >= waitTime) {
    // die LED wie zuvor einschalten
  }
  break;

Die Rückkehr zu READY beendet die Runde: Die LED leuchtet nie auf, und der nächste Tastendruck startet ein neues Spiel mit einer neuen zufälligen Wartezeit. Mit delay(waitTime) hätte das Board diesen Tastendruck überhaupt nicht erkennen können.

challenge icon

Aufgabe

Mittel

Fehlstarts erkennen:

  • in WAITING gibt ein Tastendruck Too soon! aus und kehrt zu READY zurück, ohne die LED einzuschalten
  • alles andere bleibt wie bisher: Der nächste Tastendruck startet eine neue Runde

Klicke auf Ausführen, versuche, zweimal schnell zu drücken, und klicke dann auf Prüfen.

Probier es selbst

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

// Die drei Zustände eines Durchgangs
enum State { READY, WAITING, LIT };
State state = READY;

int lastButton = HIGH;       // der zuletzt gemessene Tasterzustand
unsigned long waitStart = 0; // wann die Wartezeit begann
unsigned long waitTime = 0;  // wie lange diese Wartezeit dauert
unsigned long litAt = 0;     // wann die LED aufleuchtete

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);  // gerade gedrückt
  lastButton = button;
  unsigned long now = millis();

  switch (state) {
    case READY:
      if (pressed) {
        randomSeed(micros());  // der Zeitpunkt des Tastendrucks ist nie zweimal gleich
        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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Projekte

Übe selbstständig: Arduino-Playground