I want to use the following function to display MCU's uptime, but after several hours I get error.
void uptime(char *ret_clk)
{
byte days = 0;
byte hours = 0;
byte minutes = 0;
byte seconds = 0;
int sec2minutes = 60;
int sec2hours = (sec2minutes * 60);
int sec2days = (sec2hours * 24);
unsigned long time_delta = millis() / 1000UL;
days = (int)(time_delta / sec2days);
hours = (int)((time_delta - days * sec2days) / sec2hours);
minutes = (int)((time_delta - days * sec2days - hours * sec2hours) / sec2minutes);
seconds = (int)(time_delta - days * sec2days - hours * sec2hours - minutes * sec2minutes);
sprintf(ret_clk, "%01dd %02d:%02d:%02d", days, hours, minutes, seconds);
}
after 2:55 hours I got a correct answer : 0d 02:55:27
also after 4 hours, a correct answer : 0d 04:06:44
but roughly after 12 hours i get an error: 1d 02:01:27
and after roughly 20 hours I get : 2d 23:74:26
What is wrong in uptime
?
2 Answers 2
On an 8-bit Arduino an int
can only hold values in the range -32768 to +32767. One day's worth of seconds is 86400, which is far outside that range.
You should replace your sec2...
variables with literals, maybe #define
d - and don't forget to force the length for longer values:
#define SEC2MINUTES 60
#define SEC2HOURS 3600
#define SEC2DAYS 86400UL
-
what is the bennefit define it using
#define
? whould define asusgined long
save the problem ?guyd– guyd2021年05月03日 13:04:22 +00:00Commented May 3, 2021 at 13:04 -
1@Guy.D If you put it in a variable and use that variable to calculate other variables to do your calculations with it has to calculate them every single iteration. By using #define (or you could use
const unsigned long
if you wish) it calculates it at compile time (which I shortcut by just calculating it myself).Majenko– Majenko2021年05月03日 13:06:09 +00:00Commented May 3, 2021 at 13:06 -
what might be that cause getting this result :
upTime[0d 10:123:33]
? code was corrected as you suggestedguyd– guyd2021年05月05日 16:13:34 +00:00Commented May 5, 2021 at 16:13
The millis function increments rapidly, hence it easily exceeds the maximum value of int - -32768 to +32767.
So, use unsigned long data types for millis and other stuff that's large.
4 billion and some change is the max value that unsigned long data types can store, hence no overflowing till about 49 days.