Ciao a tutti sono un nuovo utente ,volevo chiedere una cosa ai più esperti ... dunque
Ho necessità che una variabile duri esattamente 1 giorno ed ho risolto con questa riga di codice:
timelicense =(millis()/1000 %86400; infatti a 86399 torna a zero. (86400 sono i secondi in un giorno)
La domanda è questa , che differenza esiste tra questa riga e l'eventualità di staccare millis dall'interrupt azzerarlo e riattaccarlo???
ho modificato la linea in questo modo : timelicense =(millis()/1000 );
ed ho aggiunto prima di void setup : extern volatile unsigned long timer0_millis;
e in fine in void loop :
if(timelicense==86400)
{noInterrupts ();
timer0_millis = 0;
interrupts ();}
Ho visto che funziona bene e mi garantisce che millis sia resettato una volta al giorno,
dunque estrarre il modulo (n) di millis() come ho fatto all'inizio equivale a resettare la variabile
di millis??
Dopo i fatidici 57 giorni il contenuto della variabile che valore assumerà?
No alla prima domanda, nel primo caso non vai a resettare la variabile, ma vai semplicemente a eseguire il calcolo solo sul resto della divisione millis()/86400 che si puo valutare come considero solo la parte di millis che comprende i millisecondi passati dall'inizio della giornata. In qeul caso incontrerai il problema dell overflow e il 57 giorno (o quello che è) potrebbe essere conteggiato male. Nel secondo caso invece resetti proprio il contatore ad ogni termine della giornata, cosi facendo il valore massimo che assumerà sarò 86400 quindi il contatore non andrà mai in overflow.
PS puoi anche scrivere solo timer0_millis = 0 senza disabilitare gli interrupt, tanto l'operatore di assegnazione puro completa l'operazione in un ciclo di clock.
Dopo i fatidici 57 giorni il contenuto della variabile che valore assumerà?
Prima o poi ritorna a 0, il contatore è di tipo intero senza segno profondo 32bit e quindi dopo avere acceso tutti e 32bit si azzera (e continua a contare), per questo motivo si dice che va in overflow.
Ho visto che funziona bene e mi garantisce che millis sia resettato una volta al giorno,
dunque estrarre il modulo (n) di millis() come ho fatto all'inizio equivale a resettare la variabile
di millis??
No, con il modulo puoi temporizzare altre porzioni di codice, mentre se azzeri timer0_millis influenzi le altre temporizzazioni, cioè se ci pensi è come forzare l'overflow, questo è il motivo principale per cui si dice di non azzerare millis, a meno che non si sappia cosa si sta facendo, tipo mi serve una sola temporizzazione e azzero millis.
Se cerchi nei vecchi post trovi maggiori informazioni su millis e come lavora internamente.
PS puoi anche scrivere solo timer0_millis = 0 senza disabilitare gli interrupt, tanto l'operatore di assegnazione puro completa l'operazione in un ciclo di clock.
Siamo sicuri di ciò? Modificare il valore di 4 byte non è considerato operazione atomica, ma lo è su singolo byte.
No hai ragione, non avevo ragionato sul fatto che sono ben 4 parole, chiedo venia, ignora il mio PS.
Io invece ho pensato che avessi controllato che C++ rende atomico le variabili che necessitano di essere rese atomiche, poi mi sono chiesto come potrebbe fare ciò il compilatore?
Meglio così, preferisco che sia il programmatore a stabilire cosa deve o mene essere compiuto senza interruzione, diversamente avrei un altro motivo per preferire il C al C++. .
Essendo il tuo primo post Ti invitiamo a presentarti QUI
(dicci quali conoscenze hai di elettronica e di programmazione) e a leggere il regolamento QUI
se non lo hai già fatto.
azzerare millis quando si hanno altre porzioni di codice è evidente che si crea uno scompiglio..
Nel caso esposto quel millis è utilizzato solamente per quella temporizzazione e nulla altro.
Non ci sono altri processi di tempo coinvolti...
Ho provato a inserire il codice nello sketch e funziona bene , anche senza la dichiarazione di sgancio dall'interrupt...
Almeno sono tranquillo e non penso alla sindrome del quarantanovesimo giorno.
Inoltre c è da dire che in questo modo si hanno temporizzazioni perfette nel tempo , utilizzando il modulo invece nel momento dell'overflow di millis sicuramente si potrebbe generare un evento temporale in anticipo o in ritardo...dal numero delle divisioni successive difficilmente avremo resto zero!.
grazie a tutti!!!
@vbextreme.... Non è troppo complesso ... è solo un fatto di scelta.
Comunque se hai voglia e tempo me lo puoi spiegare passo dopo passo??
oppure mettigli un commento!
purtroppo sono alle prime armi!!!
grazie per la pazienza!!
non è che ci sia un gran che da spiegare.
Prelevo il tempo A, sottraggo dal tempo attuale B il tempo A (B-A) e ottengo il tempo trascorso e lo posso direttamente confrontare con i millisecondi di un giorno:
(B - A == 86400000) allora è trascorso un giorno.
Quando si usano numeri grandi è facile sbagliare e quindi gli tolgo i 10 lsb in modo da poter effetture un confronto piu semplice:
( (B - A) >> 10 == 84375 ) allora è trascorso un giorno.
@vbextreme grazie della delucidazione per te evidente.... sarò de coccio ma
il tempo A in quale fase lo prelevi e che counter ha assunto (nella dichiarazione di setup?)
il tempo B in quale fase lo prelevi e che counter ha assunto (è il tempo assunto dalla variabile millis?)
rotazione di 10 bit e confronto.
il numero 84375 da dove viene??
Grazie per la sicura brutta figura che faro...!!!!
A lo prendi quando vuoi iniziare a contare e B quando vuoi iniziare a controllare.
Il valore reale di A e B è superficiale, quello che interessa è la differenza.
Esempio:
Guarda un orologio e segni su un foglio le ore i minuti e i secondi(A)
dopo due/tre ore Guarda di nuovo l'orologio e segni ore, minuti, secondi(B)
adesso fai B-A e ottieni quanto tempo è trascorso tra le due letture.