Menu
CoddyTech

Juego de reacción: salida en falso

Parte de la sección Proyectos del Journey de Arduino de Coddy. Lección 7 de 24.

Ahora mismo, un jugador astuto puede hacer trampa: pulsar una y otra vez mientras espera, hasta que una de las pulsaciones se produzca justo después de que se encienda la luz. Las carreras tienen una regla para esto: moverse antes de la señal es una salida falsa y se cancela la salida.

La máquina de estados ya sabe cuándo el jugador se adelanta: cualquier pulsación en el estado WAITING. Busca ahí, antes de comprobar el reloj:

case WAITING:
  if (pressed) {
    Serial.println("Too soon!");
    state = READY;
  } else if (millis() - waitStart >= waitTime) {
    // enciende el LED, como antes
  }
  break;

Volver a READY termina la ronda: el LED nunca se enciende, y la siguiente pulsación inicia un nuevo juego con una nueva espera aleatoria. Con delay(waitTime), la placa no podría detectar esta pulsación.

challenge icon

Desafío

Intermedio

Detecta las salidas en falso:

  • en WAITING, una pulsación imprime Too soon! y vuelve a READY sin encender el LED
  • todo lo demás sigue igual: la siguiente pulsación inicia una nueva ronda

Pulsa Ejecutar, intenta pulsar dos veces rápidamente y después pulsa Comprobar.

Pruébalo tú mismo

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

// Los tres estados de una ronda
enum State { READY, WAITING, LIT };
State state = READY;

int lastButton = HIGH;       // la lectura anterior del botón
unsigned long waitStart = 0; // cuándo comenzó la espera
unsigned long waitTime = 0;  // cuánto dura esta espera
unsigned long litAt = 0;     // cuándo se encendió el 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);  // pulsado en este instante
  lastButton = button;
  unsigned long now = millis();

  switch (state) {
    case READY:
      if (pressed) {
        randomSeed(micros());  // el momento de la pulsación nunca es el mismo dos veces
        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 iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Proyectos

Practica por tu cuenta: Playground de Arduino