Output prolungato di un bottone

Ciao a tutti,
premetto che non voglio complicare troppo il codice se non necessario, piuttosto preferisco avere qualche riga, ma ogni consiglio è ben accetto.
Sto lavorando ad un incrocio semaforico a chiamata che col tempo verrà ampliato con suoni, sensori e modalità notte/giorno e infine modellino.
L'intento è questo: quando viene premuto (come nella realtà, con un solo click di mouse) il pulsante di chiamata "bottone" dovrebbe lasciar finire il ciclo normale, iniziare il ciclo pedoni e riprendere il normale.
Il risultato è questo: il ciclo normale continua all'infinito e il pedonale attivato solo sotto una pressione costante durante l'intero ciclo.
Chiedo se esiste un modo di dire che il segnale proveniente dal bottone venga prolungato.
Vi lascio il codice e un'immagine del progetto fatto con thinkercad.

int bottoneVal=0;
const int bottone=1;
//i semafori macchine sono accoppiati con il loro opposto
const int vm1=2;
const int vm2=3;
const int gm1=4;
const int gm2=5;
const int rm1=6;
const int rm2=7;
const int rp=8;
const int gp=9;
const int vp=10;
const int vm[2]={vm1, vm2};
const int gm[2]={gm1, gm2};
const int rm[2]={rm1, rm2};
const int pl[2]={gp, vp};

void setup(){
  for(int pinNumber=2; pinNumber<11; pinNumber++){
    pinMode(pinNumber, OUTPUT);
  }
  pinMode(bottone,INPUT);  
}

void loop(){
  bottoneVal=digitalRead(bottone);
  if(bottoneVal==0){
// ciclo normale
    digitalWrite(rp, HIGH);
    digitalWrite(vm1, HIGH);
    digitalWrite(rm2, HIGH);
    delay(5000);
    digitalWrite(gm1, HIGH);
    digitalWrite(vm1, LOW);
    delay(3000);
    digitalWrite(vm2, HIGH);
    digitalWrite(rm2, LOW);
    digitalWrite(rm1, HIGH);
    digitalWrite(gm1, LOW);
    delay(5000);
    digitalWrite(gm2, HIGH);
    digitalWrite(vm2, LOW);
    delay(3000);
    digitalWrite(rm1, LOW);
    digitalWrite(gm2, LOW);
  }
// ciclo pedoni
  else if(bottoneVal==1){
    for (int i = 0; i < 2; i++)  digitalWrite(rm[i], HIGH);
    delay(500);
    for (int i = 0; i < 2; i++)  digitalWrite(gm[i], LOW);
    digitalWrite(vp, HIGH);
    digitalWrite(rp, LOW);
    delay(5000);
    digitalWrite(gp, HIGH);
    digitalWrite(vp, LOW);
    delay(5000);
    digitalWrite(gp, LOW);
    for (int i = 0; i < 2; i++)  digitalWrite(rm[i], LOW);
    digitalWrite(rp, HIGH);
    delay(500);
  }
}

Il problema è che, temporizzando con i delay, l'esecuzione del programma passa nel punto della rilevazione del pulsante solo per un attimo ogni decine di secondi!
Devi usare millis() e una macchina a stati finiti.

Ma perché non cercate mai?

E nemmeno leggete gli aiuti che sono in stichy?

"Aiutateci ad aiutarvi"
"La pappa è fatta"

Ma soprattutto:
"Semaforo etimologia e costruzione"

Non vedo scorre() e setta(), che dovrebbero significare leggi_pulsante() e aggiorna_led()...

Ci sono...

Ci sono

Serve di "ruspare" un po'

Tieni conto che è tutto collaudato
Da me di persona personalmente

E comunque "qui" funge solo da ispirazione
Anche se non andasse andrebbe bene
Anzi
Se non andasse sarebbe anche meglio, costringerebbe a pensare

Ma scusa:
Tu c'eri nella discussione citata
Non ti ricordi?

Sì, ma ho dato solo un'occhiata e sono uscito a passeggiare...

Passeggiata lunga tre suole e una tomaia...

:smile::smile::smile:
Oggi ho dato un'occhiata e sono uscito...

Perfetto, allora mi studierò le macchine, aggiusterò dove dovuto e farò le opportune prove.
Devo dare precedenza alla scuola, ma vi farò sapere i risultati!

Ammetto di non aver controllato il terzo post, ma non tutti i nuovi arrivati andrebbero a cercare qualcosa con i primi due nomi.
In "semaforo etimologia e costruzione" tu parli di codice binario (di cui non ne capisco l'uso in quel caso) e una struttura, due cose che personalmente non vorrei andare ancora a toccare se non necessario.
È bello trovarsi le cose già pronte, ma è ancora più bello farsele. Inoltre questo progetto potrebbe essere messo in mostra per qualche laboratorio con i bambini delle medie quindi devo mantenere un certo livello di difficoltà.

1 Like

E chi te lo vieta ?

Prendi ispirazione se vuoi, se no , no

Non ricordo, dove ?

Per le strutture: dovresti impararle

Preferisci classi e gli oggetti?
Ad esempio se ci fosse una classe di nome Semaforo da usare così:

Semaforo S5(1, 2, 3);
Semaforo S4(4, 5, 6);

void setup() {
    S5.setTime(5000, 1000, 5000);
    // tempo   Verde, Giallo, Rosso
    S4.setTime(5000, 1000, 3000);
    S4.start();   // Per default parte da verde.
    S5.start(RED);  // Inizia con il rosso.
}

void loop() {
    S5.run();
    S4.run();
}

Con la classe Semaforo non "bloccante", cioè che non usa delay(t).

Ciao.

Interessante

Ma così gestisci solo un palo del semaforo
Una via sola
Come fai a garantire il sincronismo tra le due vie?

E gestire eventi asincroni come appunto i pedoni?

Un sistema con semafori distanti probabilmente andrebbe realizzato con un'unità principale che, tramite seriale (485), riceve (per i pulsanti) e manda comandi alle periferiche in ogni semaforo. Se qualcosa non quadra nei ritorni, l'unità principale non manda più un comando fisso periodico e i semafori avviano la sequenza di emergenza che termina con tutti i gialli intermittenti.

La proposta della classe era per capire se preferisce usare delle classi al posto di struct al fine di nascondere l'implementazione così come accade per le librerie arduino, ciò avrebbe semplificato la spiegazione agli alunni, poiché non spieghi i dettagli della implementazione, ma solo come funzionano quelle classi e come usarle, come accade con tutte le altre librerie di arduino.

Quindi il codice è buttato li senza pensare a tutto il resto, in sostanza manca la regia e più precisamente non ho scritto neanche una riga di codice funzionante. Però ho scoperto che l'argomento semafori veri è complesso e sarebbe interessante saperne di più sul loro funzionamento.

Ciao.

Ho letto un tuo vecchio post sui semafori dove alleghi anche un PDF, ho letto anche altri post vecchi di un utente con tanto di codice che però ho solo intuito come funziona. La prima cosa che credo di avere compreso è che ogni semaforo accetta comandi da c string, ma come le usa non lo so.

Leggendo più volte quello che hai scritto ho avuto un visione più chiara.
Abbiamo quindi:

  • una o più lanterne semaforiche, L01, L02, ecc.
  • una centrale locale in prossimità delle lanterne CS01.
  • Lanterne L01, L02 e pulsanti P01, P02 connessi a CS01.
  • CS01 è interconnessa in qualche modo con una regia.

Quindi ad esempio L01 non riceve più interrogazioni e dopo tot tempo entrano in stato di emergenza nel quale controllano periodicamente se arrivano messaggi da CS01. In tal caso non funziona nulla, neanche i pulsanti pedonali.

Che ne pensi?
Hai altre info, link in merito?

Ciao.

Non mi sono mai occupato di semafori, ma è come mi verrebbe in mente di realizzarli per garantire la sicurezza.

Secondo l'IA, le singole lanterne hanno le lampade a LED collegate direttamente alla centralina dell'incrocio. Quest'ultima è connessa in F.O. alla centrale di controllo cittadina.

Ah scusa
Non lo avevo capito

Così hai ragione, tu giustamente domandi che paradigma di programmazione preferisce

Interessante
Linki?