Semaforo: etimologia
Dal greco Sema->significato e Foro->portatore
"portatore di significato"
Ma se sta fermo? cosa potrebbe portare un coso che sta fermo cementato a terra?
chiaramente non è giusto, qualcuno ha preso un abbaglio...
Invertiamo il concetto:
"il significato di portare"
peggio che peggio, un palo cementato a terra non può esemplificare il concetto di trasporto, al massimo quello di gancio
decisamente semaforo non viene dal greco
qualcuno dice dal francese, dicono sia un calco dal francese "sémaphore"
peccato che in francese semaforo si dica "feu" (plurale "feux")
decisamente semaforo non viene dal francese, e comunque nemmeno in francese viene dal greco...
rimane solo il latino
Seme: da seme ovvero seme
Foro: da forum, nota trasmissione di persone litigiose
ecco quindi il vero significato di semaforo:
"seme della discordia"
infatti spesso ci si litiga, ai semafori....
ma tutto questo per dire cosa?
nulla di importante: ne ho fatto uno
mi sono documentato in rete, ho letto un fracco di discussioni qui sul forum (noto luogo di discussione, appunto)
e unendo tutto quello che ho trovato in qualche giorno di studio di discussioni antiche (altrui) e idee moderne (mie)
ho tirato fuori questo:
vedete se vi piace
/* di Nelson-StandardOil
IDE 1.8.19 -
Progetto:
Scopo: prova per un semaforo usando la matrice di tasti e led
Data inizio lavori: 03/06/22
*/
// matrice 3 per 3
// 3 anodi e tre catodi
// un po' di dichiarazioni
byte anodi[] = {2, 3, 4};
byte catodi[] = {5, 6, 7};
#include "matriled.h"
// la libreria matriled gestisce una matrice di anodi x catodi LED e Pulsanti con LED ausiliario di pulsante premuto
/*
il ciclo delle lanterne sarà
rosso 1 rosso 2 (solo qui può cambiare il servizio normale<->notturno oppure normale<->pedonale
verde 1 rosso 2
verde giallo 1 rosso2
rosso 1 rosso 2
rosso 1 verde 2
rosso 1 verde giallo 2
ricomincia
ciclo ausiliare
doppio rosso pedonale rosso
doppio rosso pedonale verde
doppio rosso pedonale verde giallo
doppio rosso pedonale rosso
rosso1 rosso 2 (ritorno) è quello di prima, il termine del ciclo principale, ricomincia
lampeggio notturno
doppio giallo con giallo pedonale spento - solo qui può cambiare servizio
giallo pedonale con lanterne principale spente
*/
// la durata di un secondo
#define TEMPO 100
// il tempo di cambio ultimo stato
unsigned long int tempo;
enum Stati {DOPPIOROSSO, LANTERNA1VERDE, LANTERNA1GIALLO, ROSSODOPPIO, LANTERNA2VERDE, LANTERNA2GIALLO, PEDONEVERDE, PEDONEGIALLO, LAMPEGGIO1, LAMPEGGIO2};
// solo da doppiorosso può commutare in pedoneverde o lampeggio1
// solo da lampeggio2 può commutare in doppiorosso
// dopo pedonegiallo può commutare solo in doppiorosso
// ciclo principale 6 passi
// la definizione delle lanterne dei varii stati
typedef struct
{
char lanterne[9];// le nove lanterne, '1' acceso non uno spento scritto come carattere
byte tempo; // il tempo "base" di attesa prima di cambiare, in tempi elementari definiti come TEMPO
byte prossimo; //prossimo stato nella sequenza
} Stato;
Stato stati[] = {{"001001001", 3, LANTERNA1VERDE}, {"100001001", 30, LANTERNA1GIALLO}, {"110001001", 9, ROSSODOPPIO}, {"001001001", 3, LANTERNA2VERDE}, {"001100001", 30, LANTERNA2GIALLO}, {"001110001", 30, DOPPIOROSSO}, {"001001100", 30, PEDONEGIALLO}, {"001001110", 9, DOPPIOROSSO}, {"010010000", 1, LAMPEGGIO2}, {"000000010", 1, LAMPEGGIO1}};
byte stato; // lo stato attuale della macchina a stati
byte prenotato; // la prenotazione del predonale
// magheggio, uso una macro per leggere l'interruttore notturno, mappato su una matrice di LED e pulsanti, attraverso la sua funzione di lettura
#define notturno pulsante(1)
#define pedonale pulsante(0)
void setup(void)
{
Serial.begin(9600);
pinMode(13, OUTPUT);
Serial.println("inizio programma");
Serial.flush();
}
void loop(void)
{
// aggiorno i LED e i pulsanti
scorre();
// controllo se abbiamo una richiesta di pedone
if (pedonale)
{
prenotato = 1;
}
// il evolvere della macchina a stati
if (millis() - tempo > stati[stato].tempo * TEMPO)
{
tempo = millis();
// passo allo step successivo
// prima devo controllare che non si sia in una situazione di cambio modo notturno o pedonale
if (stato == DOPPIOROSSO)
{
if (prenotato)
{
stato = PEDONEVERDE;
prenotato = 0;
// deprenoto il pedone
}
else if (notturno)
{
stato = LAMPEGGIO1;
}
else
{
// situazione normale
stato = stati[stato].prossimo;
}
}
else
{
// non siamo in doppiorosso,
// pero' potremmo essere in LAMPEGGIO2
// che se l'iterrottore di notturno è stato escluso ripassiamo a doppio rosso
if (!notturno && stato == LAMPEGGIO2)
{
stato = LANTERNA2GIALLO;
}
stato = stati[stato].prossimo;
}
// adesso aggiorno i led
for (byte i = 0; i < 9; i++)
{
setta(i, (stati[stato].lanterne[i] == '1'));
}
Serial.print("stato: ");
Serial.println(stato);
}
}
notare l'uso del costrutto enum per creare una serie di costanti consecutive, invece di usare, come fanno tutti, delle #define, o peggio delle const int
notare anche l'uso di macro per mappare su "parole facili" la lettura di array di pulsanti multiplati