Menu
CoddyTech

Macchina a stati del semaforo

Fa parte della sezione Temporizzazione senza delay del percorso Arduino di Coddy. Lezione 10 di 18.

Un semaforo è una macchina a stati: si trova sempre in uno stato (verde, giallo o rosso), ogni stato dura un tempo prestabilito e ciascuno sa quale viene dopo:

  • GREEN: verde acceso; dopo 2 s, passa a YELLOW
  • YELLOW: giallo acceso; dopo 1 s, passa a RED
  • RED: rosso acceso; dopo 2 s, passa a GREEN

Ogni riga diventa un case:

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

Anche con delay(2000) il semaforo funzionerebbe, ma non potrebbe essere eseguito nient'altro. Con millis(), ogni passaggio attraverso loop() richiede microsecondi, così la scheda ha tempo per altre attività: in questo caso, un LED di stato che lampeggia per tutto il tempo per indicare che il controller è attivo.

challenge icon

Sfida

Medio

Il LED di stato sul pin 13 lampeggia già, e enum e lightStart sono pronti. Scrivi il semaforo usando uno switch (light) con un case per ogni luce:

  • verde per 2 s, giallo per 1 s, rosso per 2 s, poi di nuovo verde
  • un LED alla volta, con setLights()
  • nessun delay(), così il LED di stato continua a lampeggiare

Premi Run, poi Check.

Provalo tu

const int greenLed = 10;
const int yellowLed = 11;
const int redLed = 12;
const int statusLed = 13;   // il LED integrato della scheda

enum Light { GREEN, YELLOW, RED };
Light light = GREEN;
unsigned long lightStart = 0;   // quando si è accesa la luce corrente

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();

  // il LED di stato cambia ogni 250 ms, per mostrare che il controller è attivo
  if (now - statusPrevious >= 250) {
    statusPrevious = now;
    if (statusState == LOW) {
      statusState = HIGH;
    } else {
      statusState = LOW;
    }
    digitalWrite(statusLed, statusState);
  }

  // il semaforo: uno switch (light) con un case per ogni luce
  // verde 2 s, giallo 1 s, rosso 2 s, poi di nuovo verde
}
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 Temporizzazione senza delay

Esercitati da solo: Playground Arduino