Menu
CoddyTech

Máquina de estados del semáforo

Parte de la sección Temporización sin delay del Journey de Arduino de Coddy. Lección 10 de 18.

Un semáforo es una máquina de estados: siempre está en un estado (verde, amarillo o rojo), cada estado dura un tiempo determinado y cada estado sabe cuál viene después:

  • GREEN: verde encendido; después de 2 s, pasar a YELLOW
  • YELLOW: amarillo encendido; después de 1 s, pasar a RED
  • RED: rojo encendido; después de 2 s, pasar a GREEN

Cada línea se convierte en un case:

case GREEN:
  setLights(HIGH, LOW, LOW);
  if (now - lightStart >= 2000) {
    light = YELLOW;
    lightStart = now;
  }
  break;

Con delay(2000) la luz también funcionaría, pero no podría ejecutarse nada más. Con millis(), cada pasada por loop() dura microsegundos, así que la placa tiene tiempo para otras tareas: aquí, un LED de estado que parpadea todo el tiempo para mostrar que el controlador está activo.

challenge icon

Desafío

Intermedio

El LED de estado en el pin 13 ya parpadea, y enum y lightStart están listos. Escribe el semáforo como un switch (light) con un case por luz:

  • verde 2 s, amarillo 1 s, rojo 2 s, después verde otra vez
  • un LED a la vez, con setLights()
  • sin delay(), para que el LED de estado siga parpadeando

Pulsa Run y después Check.

Pruébalo tú mismo

const int greenLed = 10;
const int yellowLed = 11;
const int redLed = 12;
const int statusLed = 13;   // el LED de la propia placa

enum Light { GREEN, YELLOW, RED };
Light light = GREEN;
unsigned long lightStart = 0;   // cuándo se encendió la luz actual

unsigned long statusPrevious = 0;
int statusState = LOW;

void setup() {
  pinMode(greenLed, OUTPUT);
  pinMode(yellowLed, OUTPUT);
  pinMode(redLed, OUTPUT);
  pinMode(statusLed, OUTPUT);
}

void setLights(int green, int yellow, int red) {
  digitalWrite(greenLed, green);
  digitalWrite(yellowLed, yellow);
  digitalWrite(redLed, red);
}

void loop() {
  unsigned long now = millis();

  // el LED de estado cambia cada 250 ms para indicar que el controlador está funcionando
  if (now - statusPrevious >= 250) {
    statusPrevious = now;
    if (statusState == LOW) {
      statusState = HIGH;
    } else {
      statusState = LOW;
    }
    digitalWrite(statusLed, statusState);
  }

  // el semáforo: un switch (light) con un case para cada luz
  // verde 2 s, amarillo 1 s, rojo 2 s y luego verde otra vez
}
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 Temporización sin delay

Practica por tu cuenta: Playground de Arduino