In questo tutorial vedremo come creare un semaforo con Arduino da poter usare nei diorami.
Il tutorial è stato pensato per gestire due semafori sincronizzati fra loro, quindi potrebbe essere usato sia per la gestione di un incrocio, che per la gestione del traffico pedonale e veicolare.
In un successivo tutorial, vedremo come creare un semaforo pedonale su chiamata, dove avremo sempre il segnale verde per le auto, ma alla pressione di un pulsante si attiverà il giallo ed il rosso per le auto ed il verde per i pedoni, per poi tornare allo stato iniziale.
Se siete interessati al file STL di un semaforo date un occhio qui
Materiale Necessario
Se siete interessati al materiale, cliccate su questo e sarete indirizzati alla pagina Amazon
Iniziamo a montare la nostra basetta di prova con i led, due per colore e le resistenze per evitare che si brucino.
Ogni led lo colleghiamo ad un pin di Arduino.
Una volta montata la basetta, iniziamo a lavorare sullo sketch, per semplicità creerò due loop, uno per semaforo, Arduino deciderà quale usare in base al valore di una variabile, questa cambierà alla fine del loop per permettere ad Arduino di switchare tra id ue loop secondari così da sincronizzare i semafori, ogni semaforo avrà tempi di funzionamento programmabili tramite delle variabili.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
/* HOBBYEIDEE.ALTERVISTA.ORG Simulazione semaforo stradale con if and else */ #define rosso1 1 #define giallo1 2 #define verde1 3 #define rosso2 5 #define giallo2 6 #define verde2 7 int stato = 0; int cambio_semaforo = 0; unsigned long verdeS1 = 0; unsigned long gialloS1 = 0; unsigned long rossoS1 = 0; unsigned long verdeS2 = 0; unsigned long gialloS2 = 0; unsigned long rossoS2 = 0; int verde_strada1 = 2000; int verde_strada2 = 4000; int rosso_totale = 1000; int durata_giallo = 2000; void setup() { pinMode(rosso1, OUTPUT); pinMode(giallo1, OUTPUT); pinMode(verde1, OUTPUT); pinMode(rosso2, OUTPUT); pinMode(giallo2, OUTPUT); pinMode(verde2, OUTPUT); } void loop(){ if( cambio_semaforo == 0){ loop_strada1(); } else{ loop_strada2(); } } void loop_strada1(){ unsigned long ultimo_verde1 = millis(); unsigned long ultimo_giallo1 = millis(); unsigned long ultimo_rosso1 = millis(); if(stato == 0){ digitalWrite (verde1, HIGH); digitalWrite (giallo1, LOW); digitalWrite (rosso1, LOW); digitalWrite (verde2, LOW); digitalWrite (giallo2, LOW); digitalWrite (rosso2, HIGH); stato = stato +1; } if(stato == 1){ if(ultimo_verde1 - rossoS1 > verde_strada1){ digitalWrite (verde1, LOW); digitalWrite (giallo1, HIGH); digitalWrite (rosso1, LOW); digitalWrite (verde2, LOW); digitalWrite (giallo2, LOW); digitalWrite (rosso2, HIGH); stato = stato +1; verdeS1 = ultimo_verde1; } } if( stato == 2){ if(ultimo_giallo1 - verdeS1 > durata_giallo ){ digitalWrite (verde1, LOW); digitalWrite (giallo1, LOW); digitalWrite (rosso1, HIGH); digitalWrite (verde2, LOW); digitalWrite (giallo2, LOW); digitalWrite (rosso2, HIGH); stato = stato +1; gialloS1 = ultimo_giallo1; } } if( stato == 3){ if(ultimo_rosso1 - gialloS1 > rosso_totale ){ digitalWrite (verde1, LOW); digitalWrite (giallo1, LOW); digitalWrite (rosso1, HIGH); digitalWrite (verde2, LOW); digitalWrite (giallo2, LOW); digitalWrite (rosso2, HIGH); stato = stato -3; rossoS1 = ultimo_rosso1; cambio_semaforo = 1; } } } void loop_strada2(){ unsigned long ultimo_verde1 = millis(); unsigned long ultimo_giallo1 = millis(); unsigned long ultimo_rosso1 = millis(); if(stato == 0){ digitalWrite (verde2, HIGH); digitalWrite (giallo2, LOW); digitalWrite (rosso2, LOW); digitalWrite (verde1, LOW); digitalWrite (giallo1, LOW); digitalWrite (rosso1, HIGH); stato = stato +1; } if(stato == 1){ if(ultimo_verde1 - rossoS1 > verde_strada1){ digitalWrite (verde2, LOW); digitalWrite (giallo2, HIGH); digitalWrite (rosso2, LOW); digitalWrite (verde1, LOW); digitalWrite (giallo1, LOW); digitalWrite (rosso1, HIGH); stato = stato +1; verdeS1 = ultimo_verde1; } } if( stato == 2){ if(ultimo_giallo1 - verdeS1 > durata_giallo ){ digitalWrite (verde2, LOW); digitalWrite (giallo2, LOW); digitalWrite (rosso2, HIGH); digitalWrite (verde1, LOW); digitalWrite (giallo1, LOW); digitalWrite (rosso1, HIGH); stato = stato +1; gialloS1 = ultimo_giallo1; } } if( stato == 3){ if(ultimo_rosso1 - gialloS1 > rosso_totale ){ digitalWrite (verde2, LOW); digitalWrite (giallo2, LOW); digitalWrite (rosso2, HIGH); digitalWrite (verde1, LOW); digitalWrite (giallo1, LOW); digitalWrite (rosso1, HIGH); stato = stato -3; rossoS1 = ultimo_rosso1; cambio_semaforo = 0; } } } |
Come sempre iniziamo ad analizzare lo sketch, sorvolo sulla prima parte, dove do solo dei nomi ai pin e passo alla descrizione delle variabili.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
int stato = 0; int cambio_semaforo = 0; unsigned long verdeS1 = 0; unsigned long gialloS1 = 0; unsigned long rossoS1 = 0; unsigned long verdeS2 = 0; unsigned long gialloS2 = 0; unsigned long rossoS2 = 0; int verde_strada1 = 2000; int verde_strada2 = 4000; int rosso_totale = 1000; int durata_giallo = 2000; |
La variabile “stato” è strettamente collegata ai led dei semafori, infatti ad ogni cambio del suo valore, ottengo un cambio luci dei semafori.
Con la variabile “cambio_semaforo”, gestisco il passaggio tra un semaforo all’altro, questa variabile cambierà il suo valore alla fine di ogni loop secondario.
Passo quindi ad aggiungere delle variabili per calcolare il tempo tra un passaggio e l’altro delle luci, su “verdeS1”, “gialloS1” …. fino a “rossoS2”, memorizzo il tempo trascorso dall’ultimo passaggio di quel colore e quel semaforo, questo valore verrà sarà il dato da millis(), vedremo più in fondo come, le variabili sono di tipo unsigned long, valore consigliato quando si usa millis, perché le variabili di tipo long hanno un range più ampio rispetto ad int e con la dicitura unsigned useremo solo valori positivi.
Le ultime quattro variabili di tipo int, hanno un valore di partenza che verrà usato nello sketch come valore di confronto con millis(), questi serviranno per stabilire la durata del verde, del giallo e del rosso.
La parte seutup, contiene solo la configurazione dei 6 pin usati, tutti impostati come uscite.
Passiamo alla parte loop, che in realtà contiene 3 loop, uno principale e due secondari che verrano eseguiti in base alla condizione del principale.
Analizziamo il loop principale, molto breve ma fondamentale per lo sketch:
1 2 3 4 5 6 7 8 9 10 11 |
void loop(){ if( cambio_semaforo == 0){ loop_strada1(); } else{ loop_strada2(); } } |
Il loop contiene semplicemente un if ed else, che legge la variabile “cambio_semaforo”, che potrà avere due valori, 0 ed 1, questi saranno dati dai due loop secondari, in base al valore di questa variabile, Arduino leggere il primo o il secondo loop secondario.
Passiamo alla spiegazione dei loop secondari, essendo identici ne analizzerò soltanto uno, spiegare anche il secondo sarebbe una ripetizione del primo, cambiando solo in nome delle variabili.
1 2 3 4 5 |
void loop_strada1(){ unsigned long ultimo_verde1 = millis(); unsigned long ultimo_giallo1 = millis(); unsigned long ultimo_rosso1 = millis(); |
Come prima cosa, inserisco all’interno del loop tre variabili di tipo unsigned loop, questi sono strettamente collegare al valore di millis().
1 2 3 4 5 6 7 8 9 10 11 |
if(stato == 0){ digitalWrite (verde1, HIGH); digitalWrite (giallo1, LOW); digitalWrite (rosso1, LOW); digitalWrite (verde2, LOW); digitalWrite (giallo2, LOW); digitalWrite (rosso2, HIGH); stato = stato +1; } |
Una volta inserite le variabili iniziano le serie di “if”, queste sono collegate alla variabile “stato”.
Se questa avrà valore 0, otterremo il segnale di verde sulla strada 1 ed il rosso sulla strada 2, alla fine dell’if la variabile passa dal valore 0 a valore 1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
if(stato == 1){ if(ultimo_verde1 - rossoS1 > verde_strada1){ digitalWrite (verde1, LOW); digitalWrite (giallo1, HIGH); digitalWrite (rosso1, LOW); digitalWrite (verde2, LOW); digitalWrite (giallo2, LOW); digitalWrite (rosso2, HIGH); stato = stato +1; verdeS1 = ultimo_verde1; } } |
Con “stato” uguale ad 1, si passa dal verde al giallo sulla strada 1.
Da questo if, avremo anche la memorizzazione del tempo di durata del colore, in questo caso “verdeS1”, assumerà un valore pari a “ultimo_verde1” , così da memorizzare i millis, in cui il pin era in stato HIGH.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
if( stato == 2){ if(ultimo_giallo1 - verdeS1 > durata_giallo ){ digitalWrite (verde1, LOW); digitalWrite (giallo1, LOW); digitalWrite (rosso1, HIGH); digitalWrite (verde2, LOW); digitalWrite (giallo2, LOW); digitalWrite (rosso2, HIGH); stato = stato +1; gialloS1 = ultimo_giallo1; } } |
Il successivo if, che si attiva quando “stato” ha valore 2, fa accedere il segnale di rosso, anche qui memorizziamo il valore di millis(), in cui il giallo era acceso ed aumentiamo il valore di stato.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
if( stato == 3){ if(ultimo_rosso1 - gialloS1 > rosso_totale ){ digitalWrite (verde1, LOW); digitalWrite (giallo1, LOW); digitalWrite (rosso1, HIGH); digitalWrite (verde2, LOW); digitalWrite (giallo2, LOW); digitalWrite (rosso2, HIGH); stato = stato -3; rossoS1 = ultimo_rosso1; cambio_semaforo = 1; } } } |
Con “stato” uguale a 3 avremo un momento di pausa, in cui entrambi i semafori sono con segnale rosso.
La variabile “stato” passa da 3 a 0, così da riprendere il loop dal primo if.
Mentre la variabile “cambio_semaforo” passa da 0 a 1 così da permettere ad Arduino di passare al secondo loop secondario che gestisce il secondo semaforo.
Una volta arrivati alla fine del secondo loop, questo cambierà la variabile “cambio semaforo” da 1 a 0 così da tornare al primo loop.
Il tutorial è finito, come sempre se avete domande o consigli vi invito a scrivere qui sotto.
LINK FILE STL DI UN MODELLO SI SEMAFORO
Nella pagina sono presenti link di affiliazione su cui si ottiene una piccola quota dei ricavi, senza variazioni dei prezzi.