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:
- 1x Arduino UNO
- 1x Modulo semaforo (o 3x LED dei differenti colori)
- 1x Pulsante
- 1x buzzer passivo
- Cavi jumper (breadboard opzionale)
Schema:
Codice:
// 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.