/* FUNZIONAMENTO DEI DUE SEMAFORI */
// Semaforo dello scambio (tracciato deviato)
int rosso_tracciatoDeviato = 8;
int verde_tracciatoDeviato = 11;
// Semaforo sul tratto dritto (tracciato retto)
int rosso_tracciatoRetto = 3;
int verde_tracciatoRetto = 5;
int statoSemaforo_trattoDritto = HIGH;/* verifica se il semaforo sul tratto dritto è abilitato o disabilitato. Se è alto(HIGH),
si può procedere diritto,se è basso(LOW), allora si devia il percorso */
long millisNOW50, millisOLD50 = millis();//millisNOW sono i millisecondi attuali, mentre millisOLD quelli passati
long int50 = 50000;// è il tempo di attesa di 50 sec che deve passare per fare lo switch (riferito al tempo di attesa tra i due semafori)
/* DATI RIFERITI AL FUNZIONAMENTO DEL SEMAFORO A LUCE UNICA, TRAMITE PULSANTE NELLA STAZIONE */
int pulsante_semaforoStazione = 12;// il pulsante che controlla il semaforo a luce unica sulla banchina della stazione
int pinRosso_rgb = 7, pinVerde_rgb = 6;// ledBlu = 5;il led rgb rappresenta il semaforo sulla banchina che emette due colori (rosso o verde)
long millisNOW2, millisOLD2 = millis();/* millisNOW sono i millisecondi attuali, mentre millisOLD quelli passati. Quest'ultimi
rappresentano i millisecondi che arduino deve aspettare per poi leggere il pulsante, in modo da attivare o disattivare il
semaforo della stazione */
long int2 = 2000;/* è il tempo di attesa di 2 sec, che impiega per verif. se il tasto è stato premuto o non è stato premuto, evitandone
i rimbalzi (il debounce) */
/* IN CASO DI ALLARME */
int pulsanteAllarme = 9;// è il pulsante che ferma il programma in caso di pericolo
int stato_pulsanteAllarme = LOW;/* controlla se il pulsante che interrompe il programma è stato
premuto così da attivare l'allarme ed interromperne l'esecuzione (ovviamente se HIGH l'allarme è attivo) */
long millisNOW02, millisOLD02 = millis();/* i millisecondi di rif. rappresentano i millisecondi che arduino deve aspettare per verificare se
il tasto è premuto, in modo da attivare l'allarme */
long int02 = 200;/* il tempo di attesa di 200msec che arduino deve attendere per verificare se il tasto è premuto ed attivare così l'allarme,
evitandone i rimbalzi */
int Timer = LOW;/* con Timer LOW e stato_pulsanteAllarme LOW restano le istruzioni di partenza, in cui il semaforo nel tratto dritto
è abilitato */
void setup() {
/* 1) Attiviamo il monitor seriale per vedere ciò che accade su arduino, e verificarne così
il comportamento dei tre semafori */
Serial.begin(9600);
/* 2) Configuriamo i due pulsanti come pin di ingresso, utilizzando la resistenza interna
di arduino. E quindi di conseguenza il funzionamento del pulsante è inverso. Li abilitiamo col comando INPUT_PULLUP */
pinMode(pulsante_semaforoStazione, INPUT_PULLUP);
pinMode(pulsanteAllarme, INPUT_PULLUP);
/* 3) Configuro i 4 led per l'accensione dei due semafori, come pin di uscita inquanto, ricevono
il segnale tramite arduino */
pinMode(rosso_tracciatoDeviato, OUTPUT);
pinMode(verde_tracciatoDeviato, OUTPUT);
pinMode(rosso_tracciatoRetto, OUTPUT);
pinMode(verde_tracciatoRetto, OUTPUT);
/* 4) Configuriamo i due pin del led rgb come pin di uscita. Quest'ultimo rappresenta il semaforo
a luce unica, della stazione */
pinMode(pinRosso_rgb, OUTPUT);
pinMode(pinVerde_rgb, OUTPUT);
//pinMode(pinBlu, OUTPUT);
// PARTENZA PROGRAMMA (PROCEDURA)
// parto accendendo il verde nel tratto diritto ed il rosso nel tratto deviato
digitalWrite(rosso_tracciatoRetto, LOW);
digitalWrite(verde_tracciatoRetto, HIGH);
digitalWrite(rosso_tracciatoDeviato, HIGH);
digitalWrite(verde_tracciatoDeviato, LOW);
/* Inizialmente è verde la luce nel tratto dritto(quindi statoSemaf_trattoDritto = HIGH) e la luce del semaforo a luce unica della stazione,
quindi il treno può andare */
Serial.println("Luce verde Stazione ON");
Serial.print("Tratto dritto: ");
Serial.println("via libera");
Serial.println("Aspetta 50 sec");
}
void Funzionamento_Pulsante_allarme() {
/* In questa funzione verifico se sono passati 200msec per poi attivare il pulsante di allarme; a) Quindi memorizzo il n. di millisecondi
attuali nella variabile millisNOW02; b) Verifico se sono passati; c) Dopodichè modifico lo stato del pulsante se è disattivato lo attiva
o viceversa; d) Poi registro che sono passati 200msec nella variabile millisOLD02. Metto Timer HIGH per verificare la condizione di
attività */
millisNOW02 = millis();
if ((millisNOW02 - millisOLD02) >= int02) {
stato_pulsanteAllarme = !stato_pulsanteAllarme;
millisOLD02 = millis();
Timer = HIGH;/* con Timer HIGH, abilitiamo il semaforo nel tratto dritto, attraverso la funzione Riprendi_esecuzione() o
abilitiamo il pulsante di interruzione */
}
}
void Spegniled_2_semafori() {
// In questa funzione andiamo a spegnere i led che comandano i due semafori
digitalWrite(rosso_tracciatoRetto, LOW);
digitalWrite(verde_tracciatoRetto, LOW);
digitalWrite(rosso_tracciatoDeviato, LOW);
digitalWrite(verde_tracciatoDeviato, LOW);
}
void Riprendi_esecuzione() {
digitalWrite(pinVerde_rgb, HIGH);// riaccendi la luce verde del semaforo della stazione
// Riprendi con l'attivazione del semaforo sul tratto dritto per 50 sec e disattiva il Timer
digitalWrite(rosso_tracciatoRetto, LOW);
digitalWrite(verde_tracciatoDeviato, LOW);
digitalWrite(verde_tracciatoRetto, HIGH);
digitalWrite(rosso_tracciatoDeviato, HIGH);
Serial.println("Riprendi.....");
Serial.println(" Vai dritto ");
Timer = LOW;/* abilitando il semaforo nel tratto dritto, riparte il programma con le istruzioni di partenza (nel Setup()),
anche non essendo passati ancora 50 sec */
}
void Funzionamento_Pulsante_semaforo_stazione() {
/* In questa funzione: a) Memorizzo il n. di millisecondi attuali; b) Verifico se sono passati 2 sec; c) Dopodichè accendo la luce
rossa del semaforo della stazione e spengo i due semafori; d) Resto in questa condizione per 60 sec; e) Dopodichè riaccendo la luce
verde, non ci sono più passeggeri sulla stazione e quindi il treno può ripartire; f) Ma prima memorizzo i sec passati nella variabile
millisOLD2 */
millisNOW2 = millis();
if ((millisNOW2 - millisOLD2) >= int2) {
millisOLD2 = millis();
Serial.println("Luce rossa Stazione ON - fermati");
digitalWrite(pinVerde_rgb, LOW);
digitalWrite(pinRosso_rgb, HIGH);
Spegniled_2_semafori();
Serial.println("Aspetta 60 sec");
delay(60000);
digitalWrite(pinRosso_rgb, LOW);
digitalWrite(pinVerde_rgb, HIGH);
Serial.println("Luce verde Stazione ON - via");
}
}
void loop() {
// 1) Verifico se il pulsante è stato premuto (! poichè risulta premuto quando il suo valore è LOW) dopodichè, esegui la funzione
if (!digitalRead(pulsanteAllarme)) Funzionamento_Pulsante_allarme();
// Se il tasto è stato premuto, interrompiamo l'esecuzione, attivando l'allarme (con stato = HIGH), spegnendo anche i semafori
if (stato_pulsanteAllarme == HIGH) {
Serial.println("INTERROMPI TUTTO");
digitalWrite(pinRosso_rgb, LOW);
digitalWrite(pinVerde_rgb, LOW);
Spegniled_2_semafori();
// Se il tasto è stato ripremuto (quindi il Timer è HIGH) e quindi l'esecuzione è ancora ferma, Riprendi_esecuzione()
} else if ((stato_pulsanteAllarme == LOW) && (Timer == HIGH)) {
Riprendi_esecuzione();
// altrimenti se il tasto invece è stato ripremuto oppure non è stato proprio premuto il Timer resta o ritorna LOW
} else if ((stato_pulsanteAllarme == LOW) && (Timer == LOW)) {
// 2) Verifico se il pulsante del semaforo della stazione è premuto, dopodichè esegui la funzione
if (!digitalRead(pulsante_semaforoStazione)) Funzionamento_Pulsante_semaforo_stazione();
else // altrimenti se non è stato premuto
digitalWrite(pinVerde_rgb, HIGH);// riaccendi la luce verde
millisNOW50 = millis();// memorizzo il numero di millisecondi che passano nella variabile millisNOW (cioè quelli attuali)
// Se è solo se sono passati 50 sec (ovvero 50msec)?, entra nella condizione
if ((millisNOW50 - millisOLD50) >= int50) {
// Se statoSemaforo è alto procedi diritto, con luce verde e via impedita (con luce rossa) nel tratto deviato
if (statoSemaforo_trattoDritto == HIGH) {
statoSemaforo_trattoDritto = LOW;
Serial.print("Tratto deviato: ");
Serial.println("via libera");
Serial.println("Aspetta 50 sec");
digitalWrite(verde_tracciatoRetto, LOW);
digitalWrite(rosso_tracciatoDeviato, LOW);
digitalWrite(rosso_tracciatoRetto, HIGH);
digitalWrite(verde_tracciatoDeviato, HIGH);
// altrimenti se statoSemaforo è basso procedi verso la deviazione, con luce verde e via impedita (con luce rossa) nel tratto diritto
} else if (statoSemaforo_trattoDritto == LOW) {
statoSemaforo_trattoDritto = HIGH;
Serial.print("Tratto dritto: ");
Serial.println("via libera");
Serial.println("Aspetta 50 sec");
digitalWrite(rosso_tracciatoRetto, LOW);
digitalWrite(verde_tracciatoDeviato, LOW);
digitalWrite(verde_tracciatoRetto, HIGH);
digitalWrite(rosso_tracciatoDeviato, HIGH);
}
millisOLD50 = millis();// memorizza i millisecondi che sono passati in questo momento, nella variabile millisOLD50(millisecondi vecchi)
} // altrimenti aspetta, restando nella condizione momentanea
}
}