Ciao a tutti,
con arduino ho realizzato un cronometro utilizzando la funzione "millis", mi sono però accorto che con il passare del tempo perdo del tempo (scusate il gioco di parole)
ho fatto un test è dopo 8 ore ho perso circa 1 ora... di seguito un frammento del codice interessato
long tempo= 0;
long calcola_t(long t){
return (millis() - t) / 1000;
}
if (tempo== 0) {
tempo= millis();
}
Serial.println(calcola_t(tempo));
sapreste spiegarmi perche? come posso risolvere?
perche solo long non va bene?
millis è unsigned long
In ogni caso è normale che sia poco preciso, dipende da cosa ci devi fare.
Se ti serve qualcosa di più affidabile, usa un modulo RTC.
guarda accetto un margine di errore di 10 minuti in un ora... esiste un modo per ridurre l'errore?
ahaha ok lo provo e vi faccio sapere
vbextreme:
usa "unsigned long"
Corretto, però con il problema in questione non c'entra nulla, usare la "long" al posto della "unsigned long" crea problemi solo se il conto totale della millis supera i 24.85 giorni,
Anche se il clock di Arduino normalmente è ottenuto da un risonatore ceramico, invece di un quarzo, l'errore massimo nel computo del tempo è quantificabile in qualche decina di secondi al giorno e non certo un'ora ogni otto, è come dire che ogni 8 secondi ne conta solo 7, semplicemente assurdo, nemmeno con il clock rc c'è un simile errore.
Però se non viene specificato esattamente l'hardware utilizzato e lo sketch completo, con i frammenti non ci facciamo nulle, è impossibile capire da cosa dipende il problema.
ecco la parte dove uso il cronometro
timer_on e timer_off vengono valorizzati con il tempo espresso in secondi
calcola_tempo.ino (71 Bytes)
GET_sensor.ino (1.76 KB)
risolto... il problema era proprio la funzione
long calcola_t(long t){
return (millis() - t) / 1000;
}
mi restituiva 1 o 0 invece di 1.2 o 999
Forza sempre le costanti al tipo giusto. Usa 1000L e non 1000 Con quella L forzi la costante a Long (UL=unsigned long)
nid69ita:
Forza sempre le costanti al tipo giusto. Usa 1000L e non 1000 Con quella L forzi la costante a Long (UL=unsigned long)
Questa è una mezza leggenda metropolitana 
Ho perso il conto di quanti anni sono che scrivo codice in C/C++, sicuramente più di 30, e di quante righe di codice ho scritto, sicuramente qualche milione visto che sono decenni che lo faccio tutti i giorni.
Non mi è mai servito nemmeno una volta specificare il tipo dato per una costante espressa come numero, sono solo pippe mentali. 
Rammento che quando inserisci un valore numerico direttamente nel codice il compilatore lo tratta automaticamente come un tipo dato idoneo a contenerlo, se scrivi 1000 automaticamente diventa un int e trattarlo come un long non serve a nulla visto che se fai operazioni tra valori long e int il risultato sarà sempre quello atteso.
Per contro forzare il cast di 1000 a long fa sprecare due byte di flash inutilmente, provare per credere 
Astro, anche nel caso di calcoli misti tra float e numeri senza virgola ?
nid69ita:
Astro, anche nel caso di calcoli misti tra float e numeri senza virgola ?
Certo che si, ovviamente il risultato finale dipende dal tipo di variabile che riceve il valore scaturito dall'operazione.
Esempio se "A" è un float e "B" è un int il calcolo "B = A/10" oppure "B = A/10.0" oppure "B =A/10f" fornisce sempre lo stesso risultato salvo l'eventuale, errore di arrotondamento, dato dalla conversione tra float e int per via della particola natura esponenziale dei float, che occasionalmente può portare a variazione di +/- 1 sul valore finale dentro l'int.
Quanto sopra è uno dei motivi per cui consiglio sempre di evitare i float, se possibile, sulle mcu 8 bit visto che i double non sono disponibili, un float che in teoria dovrebbe valere 1.00000 in realtà può tranquillamente essere 1.00001 oppure 0.9999, se devi assegnarlo ad un int puoi ritrovarti con uno 0 al posto di un 1.
Unico caso in cui può realmente convenire dichiarare il tipo di una costante numerica è se il calcolo è totalmente tra float/double, inserire un valore che per il compilatore è un intero può, in casi rarissimi, generare risultati errati.
astrobeed:
Unico caso in cui può realmente convenire dichiarare il tipo di una costante numerica è se il calcolo è totalmente tra float/double, inserire un valore che per il compilatore è un intero può, in casi rarissimi, generare risultati errati.
Non ricordo, era dai tempi del msdos che non lavoravo in C. Forse mi era capitato questo raro errore oppure ai tempi quei compilatori (turbo c/ms c) ottimizzavano a muzzo. Trovandomi un errore nei calcoli dato da una costante non specificata, da allora mi ero dato la regola di tipizzarle (poi non lavoravo su MCU ma windows senza problemi di ram)