Semaforo si blocca dopo 10-15 secondi... [SOLVED]

SOLUZIONE:

Avevo erroneamente dichiarato ad int t0 e t1 alle quali assegnavo il risultato della funzione millis(). Cambiandolo da int a unsigned long, tutto funziona perfettamente non andando più in overflow la variabile.

Ciao a tutti. Finalmente oggi mi sono deciso ad acquistare arduino e mi sono cimentato in un piccolo esperimento.
Ho fatto un semaforo, molto easy. 3 led dei colori ovvi, verde acceso per 4 secondi, giallo per 2, rosso per 5 e daccapo.
Non capisco però come mai dopo la 3a/4a esecuzione, si blocca con il rosso acceso.
Se diminuisco il tempo, mettendo 400ms (invece di 4000) il semaforo scorre tranquillamente per molti più loops, anche se poi si blocca comunque.
E' normale? Io direi di no, ma non conoscendo bene il sistema, chiedo aiuto a voi.
A seguire il listato del sorgente. Che ne pensate?

D.

int statoSemaforo;
int t0;
int t1;
int durataRosso = 5000; //milliseconds
int durataGiallo = 2000;
int durataVerde = 4000;

void setup() {
statoSemaforo = 0; //verde
t0 = millis();
t1 = durataVerde;
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(13,HIGH);
}

boolean isRosso() {
return statoSemaforo == 2;
}

boolean isVerde() {
return statoSemaforo == 0;
}

boolean isGiallo() {
return statoSemaforo == 1;
}

void switchSemaforo(int nuovoStato) {
switch (nuovoStato) {
case 0:
digitalWrite(13,HIGH);
digitalWrite(11,LOW);
digitalWrite(12,LOW);
break;
case 1:
digitalWrite(12,HIGH);
digitalWrite(11,LOW);
digitalWrite(13,LOW);
break;
default :
digitalWrite(11,HIGH);
digitalWrite(12,LOW);
digitalWrite(13,LOW);
break;
}
statoSemaforo = nuovoStato;
}

void loop() {
if (millis() > (t0 + t1)) { //devo cambiare stato al semaforo
if (isVerde()) {
switchSemaforo(1);
t1 = durataGiallo;
}
else {
if (isGiallo()) {
switchSemaforo(2);
t1 = durataRosso;
}
else {
switchSemaforo(0);
t1 = durataVerde;
}
}
t0 = millis();
}
}

t0 e t1 le hai dichiarate di tipo "int" mentre millis restituisce un tipo unsigned long. Metti unsigned long anche per t0 e t1.

Grazie mille della risposta. QUesto pomeriggio provo e ti so dire.
La cosa che mi lascia perplesso è che funziona per 3 cicli e poi si blocca.. Ma effettivamente se il tipo variabile è sbagliato, potrebbe giustificare una perdita di dati :slight_smile:
Grazie 8)
D.

perchè dopo la variabile che hai usato và in overflow

Ahhhh. Ma millis() sono i millisecondi da quando ho acceso arduino?
Allora ho capito :slight_smile:

Grazie a tutti. :grin:

djhell:
Ahhhh. Ma millis() sono i millisecondi da quando ho acceso arduino?

+1

Restituisce un valore compreso fra 0 e 2^32-1. Va in overflow dopo 49,7 giorni, ricordatelo se devi tenere fisso acceso il tuo Arduino.

okkey 8)

Grazie delle preziose informazioni.

Per il tuo progetto può essere utile questa libreria: Arduino Playground - TimedAction Library

Scusate,ma perchè farlo così complicato?
io farei così:

void setup()
{
  pinMode(2,OUTPUT);// settiamo il pin 2 come OUTPUT
  pinMode(3,OUTPUT);//settiamo il pin 3 come OUTPUT
  pinMode(4,OUTPUT);//settiamo il pin 4 come OUTPUT
}
void loop()
{
  digitalWrite(2,HIGH);// accendi il pin 2(LED verde)
  delay(4000);         // aspetta 4 secondi
  digitalWrite(2,LOW); // spegni il pin 2(LED verde)
  digitalWrite(3,HIGH);//accendi il pin 3(LED giallo)
  delay(2000);         // aspetta 2 secondi
  digitalWrite(3,LOW); // spegni il pin 3 (LED giallo)
  digitalWrite(4,HIGH);// accendi il pin 4(LED rosso)
  delay(5000);         // aspetta 5 secondi
  digitalWrite(4,LOW); // spegni il pin 4(LED rosso)
}

perchè il delay è bloccante. Funziona è vero, ma se dovessi gestire altre cose non puoi...

Sono al secondo giorno con arduino, non mi permetto di insegnare niente a nessuno, per carità. Però leggendo qua e la, il problema del delay credo sia proprio pesante se utilizzato
con altre istruzioni o controlli che devono susseguirsi.

Correggetemi se sbaglio, voglio imparare :slight_smile:

ps: ho cambiato con unsigned long e il semaforo sta girando da qualche minuto. 8)
pps: interessante la libreria.
D.

djhell:
interessante la libreria.

Il Playground è pieno di cose interessanti. :smiley:

Buon lavoro. :wink:

@Riccardo Faggiolo e djhell:
la soluzione di Riccardo è semplice, e nella sua semplicità non è neanche sbagliata. Va bene però solo se il micro non deve fare nessun tipo di compito aggiuntivo oltre a quello di gestire il semaforo. Se deve fare altro, o se col tempo i compiti dovranno essere aggiunti al programma, allora verranno fuori i limiti di delay detti da djhell. Quindi se si pensa di sviluppare ulteriormente il software in futuro è bene partire col piede giusto fin da subito, per evitare di dover rimettere mano al software in un secondo tempo.