Menu
CoddyTech

Gioco di reazione: falsa partenza

Fa parte della sezione Progetti del percorso Arduino di Coddy. Lezione 7 di 24.

In questo momento un giocatore furbo può barare: premi ripetutamente durante l'attesa e una delle pressioni avviene subito dopo l'accensione della luce. Le gare hanno una regola per questo: muoversi prima del segnale è una partenza falsa e la partenza viene annullata.

La macchina a stati sa già quando il giocatore è troppo in anticipo: qualsiasi pressione nello stato WAITING. Controlla lì, prima di verificare l'orologio:

case WAITING:
  if (pressed) {
    Serial.println("Too soon!");
    state = READY;
  } else if (millis() - waitStart >= waitTime) {
    // accendi il LED, come prima
  }
  break;

Tornare a READY termina il round: il LED non si accende mai e la pressione successiva avvia una nuova partita con una nuova attesa casuale. Con delay(waitTime), la scheda non avrebbe potuto rilevare affatto questa pressione.

challenge icon

Sfida

Medio

Rileva le false partenze:

  • in WAITING, una pressione stampa Too soon! e torna a READY senza accendere il LED
  • tutto il resto rimane invariato: la pressione successiva avvia un nuovo round

Premi Esegui, prova a premere due volte rapidamente, poi premi Verifica.

Provalo tu

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

// I tre stati di un turno
enum State { READY, WAITING, LIT };
State state = READY;

int lastButton = HIGH;       // la lettura precedente del pulsante
unsigned long waitStart = 0; // quando è iniziata l'attesa
unsigned long waitTime = 0;  // quanto dura questa attesa
unsigned long litAt = 0;     // quando si è acceso il 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);  // premuto proprio ora
  lastButton = button;
  unsigned long now = millis();

  switch (state) {
    case READY:
      if (pressed) {
        randomSeed(micros());  // l'istante della pressione non è mai uguale due volte
        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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Progetti

Esercitati da solo: Playground Arduino