Semaforo semplice

Descrizione

Questo progetto è un simulatore di semaforo Arduino costruito con un pulsante, un buzzer e tre LED: rosso, giallo e verde. Il sistema ripete continuamente una sequenza di semaforo, mantenendo la luce rossa accesa per 10 secondi, la luce verde accesa per 5 secondi e la luce gialla accesa per 2 secondi. Durante le fasi verde e gialla, il buzzer produce segnali acustici con ritmi diversi. Il pulsante viene controllato durante la fase rossa e può modificare il timing della sequenza. Questo progetto è utile per imparare gli input digitali, la logica INPUT_PULLUP, il controllo dei LED, i toni del buzzer, il timing con millis() e l’automazione di base del semaforo.

Componenti necessari:

Schema:

Circuit Scheme

Codice:

traffic_light.ino
// https://nemiatools.com
#define pinButton 2 // Pin pulsante
#define pinBuzzer 3 // Pin buzzer
#define pinRed 8  // Pin LED rosso
#define pinYellow 9 // Pin LED giallo
#define pinGreen 10 // Pin LED verde

unsigned long redDuration = 10000;  // Durata rosso
unsigned long yellowDuration = 2000;  // Durata giallo
unsigned long greenDuration = 5000;  // Durata verde

void red(){    // Funzione rosso
  bool buttonPressed = false;  // Stato pulsante iniziale (false)
  unsigned long start = millis();  // Salva tempo iniziale
  while(millis() < start + redDuration) {  // Attende durata rosso
    digitalWrite(pinRed, HIGH); // Accende rosso
    if(digitalRead(pinButton) == LOW && !buttonPressed && millis() < start + redDuration - 2000){  // Controlla pressione
      start -= 2000;  // Aumenta durata rosso
      buttonPressed = true;  // Segna pulsante usato
    }
  }
    digitalWrite(pinRed, LOW);  // Spegne rosso
}

void yellow(){  // Funzione giallo
  unsigned long start = millis(); // Salva tempo iniziale
  while(millis() < start + yellowDuration) {  // Attende durata giallo
    digitalWrite(pinYellow, HIGH); // Accende giallo
    tone(pinBuzzer, 1000);  // Attiva buzzer
    delay(100);  // Attesa breve
    noTone(pinBuzzer);  // Disattiva buzzer
    delay(200);  // Pausa beep
  }
    digitalWrite(pinYellow, LOW);  // Spegne giallo
}

void green(){  // Funzione verde
  unsigned long start = millis();  // Salva tempo iniziale
  while(millis() < start + greenDuration) { // Attende durata verde
    digitalWrite(pinGreen, HIGH); // Accende verde
    tone(pinBuzzer, 1000);   // Attiva buzzer
    delay(100);  // Attesa breve
    noTone(pinBuzzer);  // Disattiva buzzer
    delay(500);  // Pausa lunga
  }
    digitalWrite(pinGreen, LOW);  // Spegne verde
}

void setup() {
  pinMode(pinButton, INPUT_PULLUP);  // Pulsante ingresso
  pinMode(pinBuzzer, OUTPUT);  // Buzzer uscita
  pinMode(pinRed, OUTPUT);  // Rosso uscita
  pinMode(pinYellow, OUTPUT);  // Giallo uscita
  pinMode(pinGreen, OUTPUT);  // Verde uscita
}

void loop() {
  red();   // Esegue rosso
  green();  // Esegue verde
  yellow();  // Esegue giallo
}

Come funziona:

Questo progetto funziona come un semplice semaforo Arduino. I tre LED rappresentano le luci rossa, gialla e verde, mentre il buzzer aggiunge segnali sonori durante alcune fasi del ciclo.

Le righe #define pinButton 2, #define pinBuzzer 3, #define pinRed 8, #define pinYellow 9 e #define pinGreen 10 assegnano i pin Arduino usati dal pulsante, dal buzzer e dai LED.

Le variabili redDuration = 10000, yellowDuration = 2000 e greenDuration = 5000 definiscono quanto a lungo ogni luce resta attiva. Questi valori sono espressi in millisecondi, quindi 10000 significa 10 secondi, 2000 significa 2 secondi e 5000 significa 5 secondi.

Dentro setup(), la riga pinMode(pinButton, INPUT_PULLUP); configura il pulsante con la resistenza pull-up interna. Questo significa che il pulsante normalmente legge HIGH, e quando viene premuto legge LOW.

Le righe pinMode(pinBuzzer, OUTPUT);, pinMode(pinRed, OUTPUT);, pinMode(pinYellow, OUTPUT); e pinMode(pinGreen, OUTPUT); configurano il buzzer e i LED come output, così Arduino può accenderli e spegnerli.

Il ciclo principale è dentro loop(). Arduino esegue red();, poi green(); e infine yellow();. Dopo che il giallo finisce, il loop ricomincia dal rosso.

La funzione red() controlla la fase della luce rossa. La riga unsigned long start = millis(); salva il tempo esatto in cui la fase rossa inizia. La funzione millis() restituisce il numero di millisecondi passati da quando Arduino è stato alimentato o resettato.

La condizione while(millis() < start + redDuration) mantiene la fase rossa attiva finché il tempo selezionato è passato. Durante questo tempo, digitalWrite(pinRed, HIGH); mantiene il LED rosso acceso.

Il pulsante viene controllato con digitalRead(pinButton) == LOW. Poiché il pulsante usa INPUT_PULLUP, LOW significa che il pulsante è premuto.

La condizione if(digitalRead(pinButton) == LOW && !buttonPressed && millis() < start + redDuration - 2000) permette l’azione del pulsante solo una volta durante la fase rossa e solo se restano almeno 2 secondi.

La riga start -= 2000; cambia la temporizzazione della fase rossa. In questo codice esatto, sottrarre 2000 da start fa diventare start + redDuration precedente, quindi la fase rossa viene accorciata di circa 2 secondi. La variabile buttonPressed = true; impedisce che la stessa pressione del pulsante venga applicata ripetutamente durante lo stesso ciclo rosso.

Alla fine della fase rossa, digitalWrite(pinRed, LOW); spegne il LED rosso.

La funzione green() controlla la fase verde. Salva il tempo di inizio con millis() e mantiene il LED verde attivo mentre millis() < start + greenDuration è vero.

Durante la fase verde, la riga tone(pinBuzzer, 1000); accende il buzzer a 1000 Hz per 100 millisecondi. Poi noTone(pinBuzzer); lo spegne, seguito da una pausa più lunga di 500 millisecondi. Questo crea uno schema di beep lento.

La funzione yellow() funziona in modo simile, ma controlla il LED giallo e usa una pausa più corta tra i beep. Il buzzer resta acceso per 100 millisecondi e poi fa una pausa di 200 millisecondi, creando un ritmo di avviso più veloce.

Le funzioni red(), green() e yellow() sono fasi bloccanti: mentre una funzione è in esecuzione, il programma resta dentro quella fase finché il suo tempo è finito. Questo è semplice ed efficace per una simulazione di semaforo di base.

Nel complesso, il circuito ripete una sequenza rosso-verde-giallo. La fase rossa è silenziosa, la fase verde produce beep più lenti e la fase gialla produce beep più veloci. Il pulsante viene letto durante la fase rossa e, in questa versione del codice, può accorciare quella fase di circa 2 secondi.

Video dimostrazione:

In questo video dimostrazione ho utilizzato un modulo semaforo autocostruito tramite i 3 led e scheda PCB ed ho anche collegato il buzzer ad arduino tramite resistenza da 220Ω per abbassare il volume di esso, naturalmente il funzionamento del circuito non cambia.