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?
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.
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
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
}
// 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.
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ù.