progetto semaforo con chiamata pedonale

Ciao a tutti! Sono nuovo nel forum e ho iniziato circa 2 settimane fa a leggere qualche libro per svolgere i primi passi all'utilizzo di arduino ed ora mi sto cimentando in alcuni circuiti su breadboard, tra cui l'ultimo tratta di 2 semafori che regolano un incrocio stradale che si alternano ad intervalli regolari. Questo è lo sketch funzionante perfettamente:

#define VERDE1 13    //definizione dei pin
#define GIALLO1 12
#define ROSSO1 11
#define VERDE2 10
#define GIALLO2 9
#define ROSSO2 8

int durata_verde = 6000;   //Durata delle luci verdi
int durata_giallo = 3000;  //e gialle.
int intervallo = 1000;     //intervallo tra semaforo rosso 1 e verde 2

void setup(){
  pinMode(VERDE1,OUTPUT);  //impostazione dei pin dei led come uscite
  pinMode(GIALLO1,OUTPUT);
  pinMode(ROSSO1,OUTPUT);
  pinMode(VERDE2,OUTPUT);
  pinMode(GIALLO2,OUTPUT);
  pinMode(ROSSO2,OUTPUT);
}

void loop(){
  digitalWrite(ROSSO1,LOW);
  digitalWrite(VERDE1, HIGH);    //inizialmente il semaforo 1 è verde
  digitalWrite(ROSSO2, HIGH);    //mentre il 2 è rosso
  delay(durata_verde);
  
  digitalWrite(VERDE1, LOW);
  digitalWrite(GIALLO1, HIGH);   //il semaforo 1 diventa giallo
  delay(durata_giallo);
  
  digitalWrite(GIALLO1, LOW);    //il semaforo 1 diventa rosso
  digitalWrite(ROSSO1, HIGH);
  delay(intervallo);             //intervallo
  
  digitalWrite(ROSSO2, LOW);    //il semaforo 2 diventa verde
  digitalWrite(VERDE2, HIGH);
  delay(durata_verde);
  
  digitalWrite(VERDE2, LOW);    //il semaforo 2 diventa giallo
  digitalWrite(GIALLO2, HIGH);
  delay(durata_giallo);
  
  digitalWrite(GIALLO2, LOW);  //il semaforo 2 diventa rosso
  digitalWrite(ROSSO2, HIGH);
  delay(intervallo);           //intervallo
}

Detto ciò, vorrei fare un salto di qualità aggiungendo un altrettanto semaforo con pulsante per la chiamata pedonale, l'idea che mi è venuta è modificare lo sketch così:

#define VERDE1 13    //definizione dei pin
#define GIALLO1 12
#define ROSSO1 11
#define VERDE2 10
#define GIALLO2 9
#define ROSSO2 8
#define VERDEPED 7
#define GIALLOPED 6
#define ROSSOPED 5
#define PULSANTE 4

int durata_verde = 6000;   //Durata delle luci verdi
int durata_giallo = 3000;  //e gialle.
int intervallo = 1000;     //intervallo tra semaforo rosso 1 e verde 2
int chiamata = 0;

void setup(){
  pinMode(VERDE1,OUTPUT);  //impostazione dei pin dei led come uscite
  pinMode(GIALLO1,OUTPUT);
  pinMode(ROSSO1,OUTPUT);
  pinMode(VERDE2,OUTPUT);
  pinMode(GIALLO2,OUTPUT);
  pinMode(ROSSO2,OUTPUT);
  pinMode(VERDEPED,OUTPUT);
  pinMode(GIALLOPED,OUTPUT);
  pinMode(ROSSOPED,OUTPUT);
  pinMode(PULSANTE,INPUT);
  
  digitalWrite(ROSSO2, HIGH);    //inizialmente i semafori strada 2 e pedonale sono rossi
  digitalWrite(ROSSOPED, HIGH);
}

void loop(){
  
  if (digitalRead(PULSANTE)==HIGH){  //se il pulsante è premuto, memorizza 1 nella variabile "chiamata"
    chiamata = 1;
  }
  
  digitalWrite(ROSSO1,LOW);
  digitalWrite(VERDE1, HIGH);    //inizialmente il semaforo 1 è verde
  delay(durata_verde);
  
  digitalWrite(VERDE1, LOW);
  digitalWrite(GIALLO1, HIGH);   //il semaforo 1 diventa giallo
  delay(durata_giallo);
  
  digitalWrite(GIALLO1, LOW);    //il semaforo 1 diventa rosso
  digitalWrite(ROSSO1, HIGH);
  delay(intervallo);             //intervallo
  
  digitalWrite(ROSSO2, LOW);    //il semaforo 2 diventa verde
  digitalWrite(VERDE2, HIGH);
  delay(durata_verde);
  
  digitalWrite(VERDE2, LOW);    //il semaforo 2 diventa giallo
  digitalWrite(GIALLO2, HIGH);
  delay(durata_giallo);
  
  digitalWrite(GIALLO2, LOW);  //il semaforo 2 diventa rosso
  digitalWrite(ROSSO2, HIGH);
  delay(intervallo);           //intervallo
  
  if(chiamata==1){                  //se è stata effettuata la chiamata pedonale
    digitalWrite(ROSSOPED, LOW);    //tale semaforo diventa verde
    digitalWrite(VERDEPED, HIGH);
    delay(durata_verde);
    
    digitalWrite(VERDEPED, LOW);    //poi giallo
    digitalWrite(GIALLOPED, HIGH);
    delay(durata_giallo);
    
    digitalWrite(GIALLOPED, LOW);  //poi rosso
    digitalWrite(ROSSOPED, HIGH);
    delay(intervallo);             //intervallo
    chiamata = 0;                  //reset chiamata pedonale
  }
}

Come si nota all'inizio di void loop() ho inserito il comando che memorizza 1 nella variabile "chiamata" se il pulsante pedonale viene premuto, però in questo modo si attiva la richiesta solo se questo è premuto all'inizio del ciclo. Cioè se premo il pulsante durante il funzionamento normale dei semafori (ad esempio durante la durata del verde), la variabile "chiamata" rimane 0. Giusto? Come posso evitare questo? Conto su di voi :) Grazie

Ciao, prima di tutto, essendo il tuo primo post, ti consiglio di presentarti QUI e di leggere il REGOLAMENTO ...

Poi ... chiaramente se il tuo codice si "ferma" per attendere lo scadere dei vari delay() ... non potrai mai fare altro ... come, ad esempio, rilevare la pressione di un pulsante.

Devi rivedere TUTTA la logica usando metodi NON bloccanti .. tramite l'uso della funzione millis().

Studiati prima QUESTO link e subito dopo QUESTO ... ;)

Guglielmo

Presentazione, Regolamento, Blink Without Delay. ;) L'ABC del Forum. :grin:

Fatto, mi sono presentato nell'apposito topic. Grazie dei consigli, ora ci lavoro su :)