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.
Desafío
IntermedioDetecta las salidas en falso:
- en
WAITING, una pulsación imprimeToo soon!y vuelve aREADYsin 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;
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Proyectos
2Juego de reacción
Juego de reacción: espera aleatoriaJuego de reacción: temporizadorJuego de reacción: salida en falsoJuego de reacción: mejor tiempoPractica por tu cuenta: Playground de Arduino