If vero con millis ma non eseguibile per giorni/mesi

Ciao ragazzi, sto facendo degli esercizi con millis e mi sono imbattuto in un qualcosa che ad oggi non mi era mai capitato e mi stanno sorgendo dubbi...

Premetto che sono da cell....

Questo è cosa verifico con millis

If ((millis() - inizio_count) > 43200000) //12 ore

Il punto è che dopo che sono passate le 12 ore di attesa questo if giustamente mi diventa vero ma nel 90% dei casi non mi entra all'interno del programma perché le altre variabili che sono dentro questo stesso if non si avverano. In pratica questo blocco di 12 ore mi deve assicurare di far passare moolto tempo tra l'eventuale esecuzione di una parte del codice, ma allo stesso tempo essere pronto dopo le 12 ore di attesa ad rieseguirlo se tutte le altre variabili dopo l'if sopra sono vere.
Quindi i miei dubbi sono che, passate le 12 ore si può presentare anche che per mesi la parte del codice subito dopo questo if non venga eseguita e di fatto la variabili inizio_count non aggiornata da tempo...
Quali rischi corro?

Grazie

L'unica parte di codice che hai riportato è corretta. Che cosa rischi?... Rischi che ciò che vorresti che sia eseguito non venga eseguito. (???...)

Quindi il fatto che millis si riavvia dopo tot giorni non mi influenza? Nn è che mi hai chiarito molto i dubbi che avevo....

Premesso che millis è una variabile di tipo uint32_t e quindi non si riavvia (mica è una MCU/CPU), ma, al limite, che dopo poco meno di 50 giorni, va in overflow e ricomincia da zero, la cosa è già stata spiegata molte volte e puoi studiarla QUI.

Guglielmo

La sintassi usata nel mio esempio dovrebbe essere esente già dall'overflow di millis... o sbaglio? Sarebbe la soluzione 2

SI, esatto, lo puoi anche scrivere senza le parentesi interne ... il compilatore è piuttosto sveglio :grin:

if ( millis() - inizio_count > 43200000 ) { ... }

Guglielmo

Quindi se ho capito bene dopo le prime 12 ore quell'if risulterà sempre vero(anche mesi)fino a quando inizio_count nn viene rimesso uguale a millis, corretto? Nn mi state rispondendo in maniera esplicita...non sto capendo... eheheh

... e neanche lo faremo ... hai tutte le informazioni per capirlo da solo :upside_down_face:

Guglielmo

Secondo me il problema ce lho eccome ad ogni azzeramento di millis, in base a quanto vale inizio_count....

Quindi se ho ragione che devo fare per risolvere? Uff..

... ristudiarti di nuovo il testo di Leo perché NON lo hai capito !

Guglielmo

Credo di aver capito... nel mio caso devo sfruttare l'overflow..... in questo modo(leggendo meglio l'articolo che mi hai postato)

if (millis() > iinizio_count)

T'ho già risposto al post #6 ...

Guglielmo

P.S.: ... e, da quanto scrivi, purtroppo NON hai capito nulla dell'articolo di Leo :roll_eyes:

Ahaahha mi sto impicciando alla grabde....

Sto sempre da celll.. queata è la parte che mi sta confondendo... presa dall'articolo

Ammettiamo che tempo_precedente valga 4.294.967.000 e che intervallo valga 1000. Ad un certo punto millis() va in overflow e riparte da zero. Il confronto diventa:

0 - 4294967000 > 1000

Si tenderebbe a pensare che il confronto diventi:

-4294967000 > 1000

ma usando interi di tipo unsigned la sottrazione in realtà restituisce come valore 296. Questo perché un unsigned non può trattare numeri negativi per cui il risultato è in realtà dato dal massimo valore contenibile, 232 ossia 4.294.967.296, meno 4.294.967.000, per cui 296. A questo punto il confronto è diventato:

296 > 1000

che ovviamente è falso. Solo quando millis supera il valore di 704 il confronto diventa vero.......

Nel mio caso l'esenpio sopra mi farebbe diventare falso quell'if o sbaglio? Cosa che io nn voglio... per assurdo quell'if mi deve rimanere vero anche per sempre.... estremizzando

Bravo e pure senza pc hai fatto i conti giusti. Comunque certi conti io li faccio fare ad arduino (o al pc o al simulatore online). Quando è così io faccio in questo modo:

if (inizio_count == 0) {
    inizio_count = millis();
}
if ( !isStart && (millis() - inizio_count > 43200000) ) {
   isStart = true;
}

if (isStart) {
   // quello che devo fare per sempre dopo le 12 ore
}

Ciao.

. . .

if ( !isStart && (millis() - inizio_count > 43200000) ) { isStart = true; }

if (isStart) {

// quello che devo fare dopo le 12 ore se le condizioni lo permettono
inizio_count = millis();
isStart = false;
}
. . .
Farei più cosi grazie dell'idea,non ci avevo pensato..

@gpb01 non ho ancora capito come avrei risolto il punto rileggendo l'aeticolo... lho fatto mantorno allo stesso punto di prima... c'è un'altro modo?

No se isStart è false riabiliti la if (! isStart && ...
e anche inizio_count = millis() messo li non serve.

if ( ! isStart && (millis() - inizio_count > 43200000) ) {
   isStart = true;
   // qui ci entra una sola volta e per entrarci 
   // isStart == false e 
   // millis() - inizio_count > 43200000
}

Comunque se hai capito il meccanismo lo usi come ti pare.

Considera anche lo switch case che alle volte è proprio necessario e rende tutto molto più chiaro specie per salvare il valore di millis. Alias macchine a stati finiti, cerca nel forum.

Ciao.

Se dopo 12 ore dall'accensione devi avere una condizione sempre vera, semplicemente usa una variabile che, trascorse 12 ore dall'accensione, diventa vera e non cambia più.

grazie a tutti per le riflessioni e gli spunti. ho risolto con una bel flag!! :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.