Buongiorno a tutti, vi chiedo come mai in uno sketch come questo:
int led = 11;
unsigned long time;
unsigned long accensione;
unsigned long spegnimento;
void setup() {
time=millis();
accensione=millis();
spegnimento=millis();
pinMode(led, OUTPUT);
Serial.begin(9600);
}
void loop() {
time=millis();
if (time>accensione+2000){
digitalWrite(led, HIGH);
Serial.println (time);
}
if(time>spegnimento+4000){
digitalWrite(led, LOW);
Serial.println (time);
accensione=millis();
spegnimento=millis();
}
}
tutto funziona...
ma se cambio il tempo di " accensione" esempio in 4000 e lo "spegnimento" in 1000
tutto si ferma.
Se ho capito bene ad ogni ciclo di if {} di millis corrisponde un tempo indipendente....
evidentemente non è cosi' o sbaglio?
Per capire come funziona e come applicare la funzione millis(), puoi studiare prima QUI, poi QUI ed infine leggere anche QUI e QUI e questo post di Claudio_FF... vedrai che ti sarà tutto più chiaro
si e penso anche di averli compresi, ma non mi torna la logica.
Se uso due "delay()" ognuno conta il suo tempo, ma con millis() no.
E' qui che mi fermo
Non lio hai compresi se non ti torna la logica
A parte gli scherzi, è un errore in cui è facile cadere, delay è una funzione che blocca l'esecuzione del programma nel punto in cui è posizionata per un certo numero di mS quindi è vero che conta il suo tempo ma nel frattemo la MCU non può far nient'altro.
La funzione millis(9 invece ti restituisce in numero di mS trascorsi dall'avvio della MCU, sta a te determinare un istante d'inizio e di fine (su cui effettuare la necessaria differenza matematica) per determinare se il tempo voluto è trascorso e da li fare le operazioni desiderate. Se ritrovo un'immagine postata tempo fa sul forum molto bella ed esplicativa forse il concetto sarà ancora più chiaro.
se faccio un if {millis() > vecchiomillis +2000}
secondo me vuol dire che 2000 è il tempo che voglio che passi
in effetti è cosi'....solo che se ne aggiungo un'altro per far fare il contrario o altro a millis() secondo me si incasina e non conta più ne il primo ne il secondo tempo
sembra quasi che i due tempi interagiscono uno con l'altro
Guarda questo post qui magari ti aiuta.
Non è che si bloccano a interagiscano semplicemente sei tu che ti segni nel posto sbagliato l'ora d'inizio se dici al programma di accenderi dopo 4 secondi ma di spegnersi dopo 1 e allo spegnimento dici di nuovo accenditi tra 4 secondi ma spegniti tra 1 capisci bene da solo che i 4 secondi non arriveranno mai, così come hai scritto tu il programma ti funziona come vuoi tu se e solo se il tempo di spegnimento è maggiore del tempo di accensione. ma essendo logicamente difficile da comprendere come l'hai scritto ti consiglio di modificare il programma anche perché così capisci meglio come funziona la logica dietro millis() e sarai libero di riapplicarla in futuro.
vai tranquillo che, per così poco, non si incasina.
dato che il tuo programma è semplicissimo...fatti un debug a mano...cioè scriviti su un pezzo di carta i valori delle tue varibili...considerando che il loop() è ciclico...e guarda come si comportano le due if()...cioè verifica se e quando le condizioni sono rispettate.
e certo...sarà sempre verificata prima la if e poi la seconda dipendendo da quest'ultima la prima...
quando inverti i valori (nel senso di ritardare l'accensione e ridurre il tempo di HIGH per lo spegnimento) cosa succede?
è semplice, verrà verificata come TRUE (VERO) sempre prima lo spegnimento che a sua volta aggiorna le variabile... tradotto ---> il led non si accenderà MAI! e tu pensi di essere de coccio
CONSIGLIO: Usa millis() in questo modo
if (accensione-millis()>=2000) {
digitalWrite(LEDBUILTIN, HIGH);
accensione = millis();
}
così evitiamo di arrivare a parlare di nuovo di overflow di variabili e di che cosa accade e perché accade e tutti ci iniziamo a fare di nuovo le pippate sulle lancette dell'orologio...(ammetto, io l'ho capito con quello )
ultima, ma non per importanza, quando la condizione è verificata, oltre a far accendere o spegnere il led devi aggiornare anche la variabile interessata, cosa che hai fatto nello spegnimento, ma non nell'accezione.
Quindi se accensione - millis() è maggiore o uguale a 2000 accendi il led e accensione = millis()
PS: ho risposto da smartphone, mi scuso per errori grossolani
ok ho letto l'orologio.....ma non ci arrivo
quindi ditemi se sbaglio(di sicuro)
devo sempre aspettare che il primo tempo che imposto sia maggiore del tempo che passa tra la prima e la seconda operazione?????
no non devi aspettare nessun tempo semplicemnete devi iniziare a contare il tempo che deve trascorrere per o spegnimento solo quanto hai acceso e viceversa, stai leggendo i post quantomeno con poca attenzione in modi differenti ti è stata suggerita la cosa già nei post #3, #5, #7, #8, #9 sempre in modi differenti ma il succo era quello.
Se ancora non riesci a capirlo allora il consiglio è quello di fare un passo indietro, ovvero fai un semplice programma che
all'avvio memorizza millis() (Setup), entra nel loop e dopo N secondi (diciamo 5) accende il led e nientaltro
Quando il punto uno ti funziona allora aggiungerai la funzionalità che quando il led è stato acceso (trascorsi 5 secondi dall'accensione) lo spenga dopo 2 secondi
Quando ti funzionano il punto 1 e 2 allora aggiungerai la funzionalità per riaccendere il led dopo che sono trascorsi 5 secondi dopo che è stato spento.
per lo OP:
Se posso fare un commento
il tuo errore è semplice e non grave
tu hai capito (più o meno) l'uso di millis,
ma stai tentando di usarlo per due differenti temporizzazioni,
quando in realtà tu devi pensare ad un'unica temporizzazione ciclica
questo sarebbe il classico esempio di macchina a stati: stato 1->stato2->stato1 etc etc
Per il resto (trascurando l'errore dell'overflow dopo 1192 ore) si tratta solo di due parti di programma concorrenti. Come dice Standardoil è un compito affrontabile più facilmente usando una logica a "situazioni" (una variabile "situazione" va usata assieme alle altre if per "abilitare" di volta in volta solo quelle corrispondenti alla situazione attuale).
Ad esempio, per usare le tue stesse variabili (ma si potrebbe semplificare):