Arduino Forum

General Category => General Discussion => Topic started by: redtails on Aug 26, 2013, 02:03 pm

Title: Resetting Millis() to zero, reset clock
Post by: redtails on Aug 26, 2013, 02:03 pm
This topic is a little summary of the research I did this morning on the unsigned long millis(). If it doesn't add any existing knowledge, then let the post be for reference purposes only.  

Millis() function itself
Unsigned long 32bit variable. Meaning 2^32-1 milliseconds range (no negative numbers possible). This equates to: (2^32-1) / 1000ms / 60sec / 60min / 24hr = 49.71 days. Or 49 days and 17 hours. Millis() is derived from timer0_millis, and overflows result in the number returning to zero (and continuing counting from zero). Overflows do not crash the arduino, Millis() overflows do not crash your code, and the timer will not stop counting. However, if you want events to happen fewer than once every 50 days, you should use RTC and the time library.

Difficulties arising from Millis() overflow
Take a look at Gammon's explanation of the millis() issue, and what is often done wrong that causes errors (http://gammon.com.au/millis). In brief, setting your stop-time ahead of the current time, and creating an if-statement that checks when the current time exceeds the "stop-time" variable will create issues near overflow. However, Using the difference between current time and stop time, and comparing that to a set interval will never create issues. (see link for code examples).

I've edited to text below to accommodate for future reference:
Is it possible to reset Millis()? Yes, though not recommended:
According to the official wiring.c source code (see here: Wire.c (https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/wiring.c)), Millis() is derived from timer0_millis. For this reason, timer0_millis can basically be seen as just another unsigned long, in fact it is. Thus, it can be manipulated at will by the programmer. Please realize that the code below is a "hack" that shouldn't be used unless you know and you've tested its effects on your millis()-dependent libraries. It is better to use an external RTC with the Time library for accurate time management.

Before void setup(), place:
Code: [Select]
extern volatile unsigned long timer0_millis;

Whenever you want to reset millis():
Code: [Select]
noInterrupts ();
timer0_millis = 0;
interrupts ();


Thanks for reading, hope it adds some new info to this forum

Many thanks to the forum members below, especially Gammon, for careful explanation and elaboration of the issues at hand!
Title: Re: Resetting Millis() to zero, reset clock
Post by: JChristensen on Aug 26, 2013, 02:37 pm
Examples and support for some of the statements are needed.


In some situations, it is better to reset timer0 (see below) in a controlled fashion, instead of letting it overflow at its limit.


What would some of those situations be? How is letting the timer overflow less controlled than another method?

Quote

Though due to technical limitations, arduino cannot calculate numbers larger than 2^32-1 ...


Technically not true, e.g. long long myInt;

Quote

Issues arising from not resetting Millis()
Performing timepoint1 = millis();  near the overflow can (and will) result in erroneous interval comparisons if millis() returns back to zero. A recorded timepoint1, compared to overflowed millis() will return nothing: difference = timepoint2 - timepoint1; difference = 1000 - (2^32-500).


Not true, you might try it. millis() is suitable for any interval comparison, provided that the interval is < 49.71 days.

Title: Re: Resetting Millis() to zero, reset clock
Post by: AWOL on Aug 26, 2013, 02:49 pm
Quote
I personally prefer resetting timer0_millis back to 0 manually in a periodically fashion to prevent any weird stuff from happening every 50 days.

Quote
Please refrain from giving your opinion on why it is bad code practice to reset millis();
Quote
Though due to technical limitations, arduino cannot calculate numbers larger than 2^32-1,
Quote
I'm not a good-enough programmer to understand what timer0_millis is based on

{Sigh}
Title: Re: Resetting Millis() to zero, reset clock
Post by: robtillaart on Aug 26, 2013, 02:54 pm
Check this stopwatch class - http://playground.arduino.cc/Code/StopWatchClass - it can be used like a resetable millis(), micros

Does this help?
Title: Re: Resetting Millis() to zero, reset clock
Post by: JChristensen on Aug 26, 2013, 03:27 pm

Not true, you might try it. millis() is suitable for any interval comparison, provided that the interval is < 49.71 days.


Let me rephrase that:

Rollovers notwithstanding, millis() is suitable for any interval comparison, provided that the interval is < 49.71 days.

This is simple enough to simulate, so I offer the following example. Please run it and post the results for us.

Code: [Select]
//millis() rollover simulation

void setup(void)
{
    unsigned long myMillis, t1, t2, lapse;
   
    Serial.begin(9600);

    //set the simulated millis value to 50 milliseconds before the dreaded rollover
    myMillis = 4294967245;    //this is 2^32 - 51
    t1 = myMillis;            //record the start time
   
    //simulate millis incrementing for 100 milliseconds
    for (int i = 0; i < 100; i++) myMillis++;
   
    t2 = myMillis;            //record the end time
    lapse = t2 - t1;          //calculate elapsed time
   
    //print the results
    Serial.println();
    Serial.print("Start ");
    Serial.println(t1, DEC);
    Serial.print("End ");
    Serial.println(t2, DEC);
    Serial.print("Elapsed ");
    Serial.println(lapse, DEC);
}

void loop(void)
{
}


(Yes I know this code or something like it probably already exists in a dozen threads on the forum but I'm too lazy to search for it.)
Title: Re: Resetting Millis() to zero, reset clock
Post by: redtails on Aug 26, 2013, 03:56 pm
What would some of those situations be? How is letting the timer overflow less controlled than another method?

Example is given in OP. When dealing with large intervals, uncertainty of roll-over increases, making the possibility of negative return on comparisons (smaller number minus larger number) greater.

Technically not true, e.g. long long myInt;

Unsigned long long variables are not described in Arduino knowledge base. I did not know about this possibility.

Not true, you might try it. millis() is suitable for any interval comparison, provided that the interval is < 49.71 days.

I did try. Smaller number minus larger number results in no return on unsigned long. The reasoning is simple, as unsigned cannot contain negative numbers. So even if interval is smaller than 2^32-1, the return can be absent if millis() overflowed!!



Check this stopwatch class - http://playground.arduino.cc/Code/StopWatchClass - it can be used like a resetable millis(), micros

Does this help?

StopWatchClass is an interesting bit of code. I had a look around the code and it's been very cleanly written! I can see that it derives its time from millis() and determines lap-time on return _stoptime - _starttime;. I'm afraid it suffers from the same issues as millis() when starttime is greater than stoptime (like when stoptime is after an overflow). Interesting code, nonetheless
Title: Re: Resetting Millis() to zero, reset clock
Post by: AWOL on Aug 26, 2013, 04:17 pm
Quote
When dealing with large intervals, uncertainty of roll-over increases,

There is no uncertainty, so it cannot increase.
Roll-over will occur.
Deal with it properly, and all will be well.
There is no need to reset the millisecond clock.

Quote
Smaller number minus larger number results in no return on unsigned long.

I don't understand that sentence.


Title: Re: Resetting Millis() to zero, reset clock
Post by: redtails on Aug 26, 2013, 04:25 pm


Not true, you might try it. millis() is suitable for any interval comparison, provided that the interval is < 49.71 days.


Let me rephrase that:

Rollovers notwithstanding, millis() is suitable for any interval comparison, provided that the interval is < 49.71 days.

This is simple enough to simulate, so I offer the following example. Please run it and post the results for us.

Code: [Select]
//millis() rollover simulation

void setup(void)
{
    unsigned long myMillis, t1, t2, lapse;
   
    Serial.begin(9600);

    //set the simulated millis value to 50 milliseconds before the dreaded rollover
    myMillis = 4294967245;    //this is 2^32 - 51
    t1 = myMillis;            //record the start time
   
    //simulate millis incrementing for 100 milliseconds
    for (int i = 0; i < 100; i++) myMillis++;
   
    t2 = myMillis;            //record the end time
    lapse = t2 - t1;          //calculate elapsed time
   
    //print the results
    Serial.println();
    Serial.print("Start ");
    Serial.println(t1, DEC);
    Serial.print("End ");
    Serial.println(t2, DEC);
    Serial.print("Elapsed ");
    Serial.println(lapse, DEC);
}

void loop(void)
{
}


(Yes I know this code or something like it probably already exists in a dozen threads on the forum but I'm too lazy to search for it.)


Hmm this is very interesting. Even though arduino is calculating 4294967245 - 50 , it's still returning 100. Can you elaborate on this a bit? It seems to go against common logic that 4294967245 - 50 = 100. Am I missing something here? Is Arduino actually taking notes on all unsigned longs that have overflowed and dealing with them correctly arithmetically? Well I know the answer to this is yes, but can someone with deep understanding of this point me to the source-code in which this is described?
Title: Re: Resetting Millis() to zero, reset clock
Post by: CrossRoads on Aug 26, 2013, 04:37 pm
Open your calculator, to Progamming mode. Select HEX mode.
Unsigned long goes from 0000 0000 to FFFF FFFF, 32 bits.

Time comparisons are done using subtraction: current time - earlier time.
So a post rollover number, say 0000 0010, minus a pre-rollover number, FFFF FF00, will result in a correct result:
FFFF FFFF 0000 0110
Ignoring the upper 32 bits of the 64 bit result leave 0000 0110, which is the correct answer: 100 befor the rollover + 10 after = 110.
Arduino does the same - results past the lowe 32 bits fall off.
Looking in the decimal world leads to confusion - need to look at in binary world (with HEX just being a convenient to look at binary)
Title: Re: Resetting Millis() to zero, reset clock
Post by: robtillaart on Aug 26, 2013, 06:04 pm
Quote
It seems to go against common logic that 4294967245 - 50 = 100.


That would be indeed, but it is in fact 50 - 4294967245 = 100 that is shown in the sketch of Jack C.

one way to look at it is to see 4294967245 as 50 less than MAX_ULONG, you might see it as -50
then 50 - -50 == 50 + 50 = 100

Title: Re: Resetting Millis() to zero, reset clock
Post by: JChristensen on Aug 26, 2013, 08:18 pm

Hmm this is very interesting. Even though arduino is calculating 4294967245 - 50 , it's still returning 100. Can you elaborate on this a bit? It seems to go against common logic that 50 - 4294967245 = 100 (edit: jc). Am I missing something here? Is Arduino actually taking notes on all unsigned longs that have overflowed and dealing with them correctly arithmetically? Well I know the answer to this is yes, but can someone with deep understanding of this point me to the source-code in which this is described?


No notes are being taken, it is merely the magic of modular integer arithmetic (http://en.wikipedia.org/wiki/Integer_overflow). The odometer analogy is a good one. Say a six-digit odometer reads 999950 and we drive the car 100 miles. At the end, the odometer reads 50 miles. So the ending reading minus the starting reading (50 - 999950) must be 100 miles. There is no such concept as negative miles on an odometer, just as there is no concept of negative numbers with unsigned integers. The cross-check is to start with 50 miles on the odometer and drive the car backwards for 100 miles. (Assume for the sake of discussion that the odometer moves backward when the car is driven in reverse. I think this may have been true in the past when odometers were purely mechanical, but it is probably not true these days.)

Another way to look at it, add 1,000,000 to the ending reading to guarantee a positive result, then if needed, truncate the result to six digits to fit the odometer, so 1,000,050 - 999950 = 100. The fixed width of the odometer is analogous to the fixed width of an integer variable, except it's base 10 instead of base 2.
Title: Re: Resetting Millis() to zero, reset clock
Post by: AWOL on Aug 26, 2013, 08:20 pm
Quote
No notes are being taken, it is merely the magic of modular integer arithmetic

sp. "modulo"
Title: Re: Resetting Millis() to zero, reset clock
Post by: _gr33n_ on Aug 26, 2013, 08:25 pm
Hello
I have another question about this topic. How about setting timer0_millis to 4 294 963 696 (1 hour before rolover)
to test if code is rollover proof?
Title: Re: Resetting Millis() to zero, reset clock
Post by: JChristensen on Aug 26, 2013, 08:25 pm

Quote
No notes are being taken, it is merely the magic of modular integer arithmetic

sp. "modulo"


Another link for the OP: http://en.wikipedia.org/wiki/Modular_arithmetic
Title: Re: Resetting Millis() to zero, reset clock
Post by: AWOL on Aug 26, 2013, 08:37 pm
Apologies - maybe it was taught as "modulo arithmetic" in English-speaking institutions in the 1970s.
That's my recollection anyway.
Title: Re: Resetting Millis() to zero, reset clock
Post by: nickgammon on Aug 26, 2013, 10:48 pm

Overflows are registered in timer0_overflow_count, making it possible to calculate further how long the arduino has really been running beyond the unsigned long limit ...


This is not correct. That variable counts the number of times Timer0 overflows (which itself happens every 1.024 mS). It is used in one place only and that is to return the correct value from micros(). It is not a "millis() overflow count" as you seem to think.

Quote

I personally prefer resetting timer0_millis back to 0 manually in a periodically fashion to prevent any weird stuff from happening every 50 days.


This is not a useful thing to do, any more than resetting your kitchen clock each evening to stop it "rolling over" at midnight. For one thing, it isn't necessary. For another, while you are resetting the clock it is no longer counting the time.

If you have any reasonably complex sketch where you need to count multiple intervals then there will be no obvious time in which to reset the timer.

Quote

It is better coding practice to read timer0_overflow_count before and after long-running operations ...


No, that achieves nothing, as I said above.

The others are quite right. Something like this always works:

Code: [Select]
if (millis () - startTime >= interval)
  {
  // do something
  }


(Given that startTime is unsigned long).


Example is given in OP. When dealing with large intervals, uncertainty of roll-over increases, making the possibility of negative return on comparisons (smaller number minus larger number) greater.


How can a negative return be possible on comparing unsigned numbers? That is the crux. It isn't possible, and thus you get the correct answer. What other answer could you get?
Title: Re: Resetting Millis() to zero, reset clock
Post by: nickgammon on Aug 27, 2013, 12:16 am

Whenever you want to reset millis():
Code: [Select]
timer0_millis = 0;


I just want to also point out, in case you ignore my earlier advice, that this is flawed because you haven't "protected" that line from interrupts.

http://www.gammon.com.au/interrupts

Scroll down to "critical sections". If you must do the above, you have to turn interrupts off:

Code: [Select]

noInterrupts ()
timer0_millis = 0;
interrupts ();


Without doing that, at the moment you attempt to set the timer to zero, an interrupt may occur which means it is possibly only half set to zero.
Title: Re: Resetting Millis() to zero, reset clock
Post by: Grumpy_Mike on Aug 27, 2013, 12:19 am

Apologies - maybe it was taught as "modulo arithmetic" in English-speaking institutions in the 1970s.
That's my recollection anyway.

Yes you are right, that is what I was taught and what I did teach.
Title: Re: Resetting Millis() to zero, reset clock
Post by: JChristensen on Aug 27, 2013, 12:44 am

Apologies - maybe it was taught as "modulo arithmetic" in English-speaking institutions in the 1970s.
That's my recollection anyway.


None needed. Probably just another of those differences between English and Usanian ;)
Title: Re: Resetting Millis() to zero, reset clock
Post by: nickgammon on Aug 27, 2013, 11:15 am
http://gammon.com.au/millis
Title: Re: Resetting Millis() to zero, reset clock
Post by: AWOL on Aug 27, 2013, 11:21 am
Thanks Nick!

Karma++
Title: Re: Resetting Millis() to zero, reset clock
Post by: Jantje on Aug 27, 2013, 11:55 am

Thanks Nick!

Karma++

Same for me :-)
Jantje
Title: Re: Resetting Millis() to zero, reset clock
Post by: redtails on Aug 28, 2013, 01:47 pm

The others are quite right. Something like this always works:

Code: [Select]
if (millis () - startTime >= interval)
 {
 // do something
 }


(Given that startTime is unsigned long).


Example is given in OP. When dealing with large intervals, uncertainty of roll-over increases, making the possibility of negative return on comparisons (smaller number minus larger number) greater.


How can a negative return be possible on comparing unsigned numbers? That is the crux. It isn't possible, and thus you get the correct answer. What other answer could you get?


Aw sweet, it all makes sense now. I executed the following code

Code: [Select]
unsigned long var;
unsigned long varminus;

void setup(void)
{
 // initialize serial:
 Serial.begin(9600);
 var = 100;
 varminus = var-200;
 
 Serial.println("The answer to 100 minus 200 on unsigned-long vars is: ");
 Serial.println(varminus);
}

void loop(void)
{
}


And the output is:

Code: [Select]
The answer to 100 minus 200 on unsigned-long vars is:
4294967196


The odometer analogy is the perfect one for a commoner to get around obscure binary/hex-thinking.

In any case, many thanks for forum members that stuck around, I've edited OP to accommodate future reference
Title: Semantics.
Post by: Paul__B on Aug 28, 2013, 01:56 pm


Apologies - maybe it was taught as "modulo arithmetic" in English-speaking institutions in the 1970s.
That's my recollection anyway.


None needed. Probably just another of those differences between English and Usanian ;)


While a staunch defender of the "pure" English tongue, on cogitation, I do believe the term "modular arithmetic" is in fact quite correct and indeed, more accurately descriptive than "modulo arithmetic".

The modulus is a parameter of a numeric value determined by a specific operation and the act of performing that operation is described as "modulo" or a modulo function.  So the arithmetic of performing further operations - notably comparisons - on such results, the moduli as a plural, can appropriately be described as "modular" arithmetic where "modular" derives from the "moduli" in the same way we refer to "alveolar" where the (lung) alveoli are concerned, and a few other Latin terms - though I cannot quote the original Latin rules behind that (I never formally studied Latin).

There could be claimed to be the occasional word ending in o (http://wordfinder.yourdictionary.com/ending-with/o) - such as "medico" whose apparent derived adjective ("medical") ends in "al" but I suspect this is spurious and results from the colloquial addition of "o" to a word (such as "nymph") whose derived adjective did end in "al".

My point - for what it is worth :smiley-sleep: - is that "modulo" is the name of a process the result of which is the modulus and the arithmetic relating to these is concerned more with what you can do with the moduli, than how you obtain them.
Title: Re: Resetting Millis() to zero, reset clock
Post by: nickgammon on Aug 28, 2013, 10:52 pm

In any case, many thanks for forum members that stuck around, I've edited OP to accommodate future reference


Thank you.

Quote

Take a look at Gamon's explanation of the millis() issue, and what is often done wrong that causes errors.


It's "Gammon" (with two "m"s.).

Gamon was a guy in Orgrimmar in World of Warcraft, who was constantly being killed.
Title: Re: Resetting Millis() to zero, reset clock
Post by: niko23 on Jan 05, 2014, 05:20 pm
Hi,
I have solved this problem in this way:
Code: [Select]

unsigned long check_millis = 0;
long interval = 1000;
unsigned long previousMillis = 0;

void setup(){
}
void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis >= check_millis) check_millis = currentMillis;
  else {
    check_millis = 0;
    previousMillis = 0;
  }

  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;   
    //do somethings
  }
}
Title: Re: Resetting Millis() to zero, reset clock
Post by: NavyVet1959 on Dec 05, 2018, 12:49 pm
The solution that I used to avoid the rollover issue was to make my own replacement for millis() that returns a "unsigned long long int".  It calls millis() to get the current time and remembers the last value that it got from millis(), so if the current time is less than the previous time, it adds 0x0100000000UL to the previous time and then subtracts the current time (this getting the elapsed time) and then adds the elapsed time to the "unsigned long long int" variable that it uses to keep track of the current time.  There is still a possibility of a rollover, but it is pushed so far into the future that I don't consider it an issue.  The rollover would occur around the 584.9 million *year* mark.  The only issue with this method is that if successive calls to this routine do not happen at least once every millis() rollover interval, it could miss a rollover and the time it keeps track of might not be accurate.  Since I use this routine for scheduling automatic actions in a state machine instead of using delay() calls, the routine is called every time the loop() routine is called.  As such, I don't foresee there will be a case where the code is not called for a long enough period of time that the millis() rollover would be an issue.
Title: Re: Resetting Millis() to zero, reset clock
Post by: Robin2 on Dec 05, 2018, 01:02 pm
The solution that I used to avoid the rollover issue was to make my own replacement for millis() that returns a "unsigned long long int". 
That sounds awfully complicated when the rollover problem can be avoided simply by using subtraction as in
Code: [Select]
if (millis() - previousTime >= desiredInterval) {

...R
Title: Re: Resetting Millis() to zero, reset clock
Post by: Coding Badly on Dec 05, 2018, 07:23 pm
The solution that I used to avoid the rollover issue was to make my own replacement for millis() that returns a "unsigned long long int".
A truly terrible idea for the AVR processor.

Title: Re: Resetting Millis() to zero, reset clock
Post by: NavyVet1959 on Dec 06, 2018, 01:51 am
That sounds awfully complicated when the rollover problem can be avoided simply by using subtraction as in
Code: [Select]
if (millis() - previousTime >= desiredInterval) {

...R
I suspect that it's more complicated describing it than actually doing it. :)

My system consists of basically a scheduler and events that can occur.  There might be an event for turning on a particular pin in the future and another one for turning it off at some point later.  The event handler might generate future events in the handling of the current event that it is processing.  It is possible that it might be necessary to schedule an event that will happen after multiple millis() rollovers.  Each of the events in the event queue have a 64-bit time value associated with them to tell the event handler when it needs to process that event.

Something along the line of this:

Code: [Select]

typedef unsigned long long int TIME64;

TIME64  GetTime( void )
{
    static TIME64  curTime64 = 0;
    TIME64         curMillis;
    static TIME64  prevMillis = 0;

    curMillis = millis();
    if (curMillis < prevMillis) {
        /* curMillis < prevMillis, adjusting... */
        curTime64 += 0x0100000000UL + curMillis - prevMillis;
    } else {
        curTime64 += curMillis - prevMillis;
    }
    prevMillis = curMillis;

    return (curTime64);
}
Title: Re: Resetting Millis() to zero, reset clock
Post by: NavyVet1959 on Dec 06, 2018, 02:06 am
A truly terrible idea for the AVR processor.


Manipulating 64-bit integers is inefficient with these processors, but for what I use it for, it's fast enough.  The events that are being scheduled are a few seconds apart at the closest and often hours or days apart -- some might even be months apart.  Having the capability to schedule events that are across multiple millis() rollover intervals was more important to me than a few extra processor cycles being spend on 64-bit arithmetic.  I will admit though that having a 584.9M year rollover is a bit more than I needed. :)

Just did a quick timing test, printing out the elapsed time between successive calls to GetTime() in my code and it works out to be 4ms, with the occasional 5ms time.  Trying the same thing with a loop of calling millis() and displaying the elapsed time using "unsigned long int" values results in mostly 3ms with the occasional 4ms value.  It's possible that the Serial.println() call is taking up a good portion of that.

So, I decided to try another test without the console output... I used a loop of 10,000 where millis() was called, stored as the current time, calculate the elapsed time, and then store the current time as the previous time.  This results in 15ms for the 10,000 iterations of the loop.

Changing this to use the 64-bit unsigned integer in my GetTime() routine results in 187ms for the 10,000 iterations of the loop.  So, it most definitely takes a lot longer to do 64-bit math.  For some systems, this might be an unacceptable time penalty.  For other systems though, this might be perfectly acceptable.

Code: [Select]

        typedef unsigned long long int  TIME64;

        TIME64         ct;                          /* current time */
        TIME64         pt = 0;                      /* previous time */
        TIME64         et;                          /* elapsed time */
        unsigned long  startTime;
        unsigned long  endTime;
        int            i;

        Serial.println("Testing millis() loop...");
        startTime = millis();
        for (i = 0; i < 10000; i++) {
            ct = GetTime();
            et = ct - pt;
            // Serial.println(et);
            pt = ct;
        }
        endTime = millis();
        Serial.print("startTime=");
        Serial.print(startTime);
        Serial.print(", endTime=");
        Serial.print(endTime);
        Serial.print(", elapsedTime=");
        Serial.println(endTime-startTime);
Title: Re: Resetting Millis() to zero, reset clock
Post by: Robin2 on Dec 06, 2018, 09:32 am
The event handler might generate future events in the handling of the current event that it is processing.  It is possible that it might be necessary to schedule an event that will happen after multiple millis() rollovers.
That sounds like a role for a Real Time Clock

Alternatively why not use millis() to update a 1-second counter in an unsigned-long variable. That should see you out.

...R
Title: Re: Resetting Millis() to zero, reset clock
Post by: Coding Badly on Dec 06, 2018, 10:37 am
...fast enough...
"Fast enough" is secondary to the failure to produce a viable image because of the oh-so-fun inability to find a spill register.

Title: Re: Resetting Millis() to zero, reset clock
Post by: NavyVet1959 on Dec 06, 2018, 02:33 pm
"Fast enough" is secondary to the failure to produce a viable image because of the oh-so-fun inability to find a spill register.


I haven't had the pleasure to have that error *yet*, but I've done a lot of 'C' programming in non-memory-protected architectures over the years and I've had my share of fun with strange errors that were hard to trace down.  Ones where you put a printf statement in the code to see the value of some variable at some point and when you add the code, the program either starts working correctly or the error gets moved elsewhere.  Of course, you *know* you are overwriting your code *somewhere*, but trying to find it can be a pain. :)

Is there something about the "long long" data types that might cause this sort of error to occur more often?

Title: Re: Resetting Millis() to zero, reset clock
Post by: Coding Badly on Dec 06, 2018, 10:54 pm
Is there something about the "long long" data types that might cause this sort of error to occur more often?
Datatype size, the amount of data that can be stored in processor registers, and a likely compiler limitation that prevents a stack frame from being created when too much data is being squeezed into too small of a register space.