Menu
CoddyTech

Jeu de réflexes : faux départ

Fait partie de la section Projets du Journey Arduino de Coddy. Leçon 7 sur 24.

En ce moment, un joueur malin peut tricher : appuyer encore et encore pendant l’attente, et l’un des appuis tombe juste après l’allumage du voyant. Les courses ont une règle pour cela : bouger avant le signal est un faux départ, et le départ est annulé.

La machine à états sait déjà quand le joueur est trop tôt : tout appui dans l’état WAITING. Cherche-le à cet endroit, avant de vérifier l’horloge :

case WAITING:
  if (pressed) {
    Serial.println("Too soon!");
    state = READY;
  } else if (millis() - waitStart >= waitTime) {
    // allume la LED, comme avant
  }
  break;

Revenir à READY termine la manche : la LED ne s’allume jamais, et l’appui suivant lance une nouvelle partie avec une nouvelle attente aléatoire. Avec delay(waitTime), la carte ne pouvait pas détecter cet appui.

challenge icon

Défi

Moyen

Détecte les faux départs :

  • dans WAITING, un appui affiche Too soon! et revient à READY sans allumer la LED
  • tout le reste reste inchangé : l’appui suivant démarre un nouveau tour

Clique sur Exécuter, essaie d’appuyer deux fois rapidement, puis clique sur Vérifier.

Essayez vous-même

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

// Les trois états d'une manche
enum State { READY, WAITING, LIT };
State state = READY;

int lastButton = HIGH;       // la valeur lue du bouton la dernière fois
unsigned long waitStart = 0; // le moment où l'attente a commencé
unsigned long waitTime = 0;  // la durée de cette attente
unsigned long litAt = 0;     // le moment où la LED s'est allumée

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);  // vient d'être enfoncé
  lastButton = button;
  unsigned long now = millis();

  switch (state) {
    case READY:
      if (pressed) {
        randomSeed(micros());  // le moment de l'appui n'est jamais deux fois le même
        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 iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Projets

Entraînez-vous par vous-même : Playground Arduino