My program stops after 9h32m

I wrote a program that executes a block of code every second. The main idea is:

void setup() {
   long time0 = 0;
   long time1 = 0;
}
void loop() {
   time1 = millis();
   if(time1 – time0 >= 1000) {
      // Execute this block of code every second.
      // Execution of this block continues aprox. 200ms.
      Serial.print(time1);
      ?
      time0 = millis();
   }
}

Program output is:

1336 ?  
2365 ?
3395 ? 
?
?
?
34357347 ? 
34358382 ?  
34359417 ?

// Here (after ~9h32min) millis() counter restarts, but program continues.

0 ?  
1326 ?  
2355 ?  
3384 ? 
?
?
?

I made some improvements and additional features. New version counts every second but the block of code executes every minute:

void setup() {
   long secCNT = 0;
   long time0 = 0;
   long time1 = 0;
}
void loop() {
   time1 = millis();
   if(time1 – time0 >= 1000) {
      // Execute this block of code every second.
      // Execution of this block continues up to 10ms.
      secCNT++;
      ?
      if(secCNT%60 == 0) {
            // Execute this block of code every minute.
            // Execution of this block continues aprox 200ms.
         Serial.print(secCNT);
         ?
      }
      ?
      time0 = millis();
   }
}

Program output is:

60 ? 
120 ? 
180 ? 
? 
? 
?
33900 ?
33960 ? 
34020 ?

// Here (after ~9h32min) millis() counter restarts, and my program stops!

My questions are:

  1. Why my program stops in 2nd example. Maybe I have to add delay(200ms) in "every-one-sec-block”?

  2. In Example 1 I've got time error aprox. 1 sec per hour, In Example 2 the error is aprox. 30 sec. per hour. In Ex.2 I call function millis() more frequently, is this matters?

  3. With Arduino can I use ATMega8 16-bit Timer as more curate timer?

Thanks!

This is because the millis() function overflows after that amount of time. See here:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1167861718

Hmm, you could try making time0 and time1 of type unsigned long instead of long. If not doesn't work, can you post the complete code for your two programs (or a smaller version that shows the problem)? The ones you've posted don't actually compile. The millis() function operates with interrupts, so it should be just as accurate regardless of your code, with one exception: the delayMicroseconds() function disables interrupts to get better precision, which could throw of the timing of millis(). Or maybe it's just because you're printing minutes instead of seconds?

Now I spend my time to improve software processing of analog inputs, also I have to make some hardware changes. After this I will make some experiments about problems with my software clock and will write results, questions etc?

I know that the programs in my post can't compile. I just try to explain the algorithm because they're 6K. In the future I'll try to list the real code or part of him.

For now I can write several new facts:

  1. More about time error in Example 2 – The clock work with accuracy 1 second per hour but after 2h30min (aprox.) suddenly appears 70 seconds error. There aren't lost seconds or minutes in serial printing, I just saw this error when I compare with my PC clock.
  2. I've made changes in Example 2 and add delay(200) to “every-second-code” and delay(100) to “every-minue-code”. The results was terrible, clock worked but with worse accuracy (time error few minutes per hour). And again there aren't lost seconds or minutes in serial printing.

Whatever? maybe I make some stupid mistakes or something else?
After few days I'll write software clock program without additional features and then I'll make experiments and conclusions.

Thanks!

There are some logical mistakes in Example 1 and Example 2 above.

But here is my very simple code that I've tasted:

// Example 3
#define dTimeStep 1000
#define pinDSysLED 13

unsigned long tSCNT = 0;
unsigned long tSTimeK0 = 0;
unsigned long tSTimeKN1 = 0;

void setup() {
  pinMode (pinDSysLED, OUTPUT);
  Serial.begin(9600);
}

void loop () {

  tSTimeK0 = tSTimeKN1 = millis();
  printNewline();
  Serial.println("Task Manager starts... ");
  Serial.print("At tSCNT = ");
  Serial.print(tSCNT);
  Serial.print(" time is ");
  Serial.print(tSTimeK0);
  Serial.println(" ms.");

  while(true) {
    tSTimeK0 = millis();
    if(tSTimeK0 < tSTimeKN1) tSTimeKN1 = 0;
    if(tSTimeK0 - tSTimeKN1 >= dTimeStep) {
      digitalWrite(pinDSysLED, HIGH);
      tSCNT++;
      Serial.print("At tSCNT = ");
      Serial.print(tSCNT);
      Serial.print(" time is ");
      Serial.print(tSTimeK0);
      Serial.println(" ms.");
      tSTimeKN1 = tSTimeK0;
      digitalWrite(pinDSysLED, LOW);
    }
  }
}

And this is the output:

Task Manager starts... 
At tSCNT =  0 time is 0 ms. 
At tSCNT = 1 time is 1000 ms. [color=#00cc00]// time step is 1000 ms – OK![/color]
At tSCNT = 2 time is 2000 ms.
At tSCNT = 3 time is 3000 ms.
?
At tSCNT = 108 time is 108000 ms.
At tSCNT = 109 time is 109000 ms.
At tSCNT = 110 time is 110000 ms.
At tSCNT = 111 time is 111148 ms. [color=#ff0000]< - - - !?!? // time step is 1148 ms[/color]
At tSCNT = 112 time is 110920 ms. [color=#ff0000]< - - - !?!? // time step is MINUS 228 ms and the time is wrong[/color]
At tSCNT = 113 time is 111920 ms. [color=#ff0000]// and again the time step is 1000 ms but the time is wrong[/color]
At tSCNT = 114 time is 112920 ms.
?
At tSCNT = 420 time is 418920 ms.
At tSCNT = 421 time is 419920 ms.
At tSCNT = 422 time is 420920 ms.
At tSCNT = 423 time is 422050 ms. [color=#ff0000]< - - - !?!?[/color]
At tSCNT = 424 time is 421823 ms. [color=#ff0000]< - - - !?!?[/color]
At tSCNT = 425 time is 422823 ms.
At tSCNT = 426 time is 423823 ms.
At tSCNT = 427 time is 424823 ms.
At tSCNT = 428 time is 425823 ms.
At tSCNT = 429 time is 426823 ms.
At tSCNT = 430 time is 427823 ms.
At tSCNT = 431 time is 428823 ms.
At tSCNT = 432 time is 429824 ms. [color=#ff0000]< - - - !?!?[/color]
At tSCNT = 433 time is 430824 ms.
At tSCNT = 434 time is 431824 ms.
?
At tSCNT = 569 time is 566824 ms.
At tSCNT = 570 time is 567824 ms.
At tSCNT = 571 time is 568824 ms.
At tSCNT = 572 time is 569900 ms. [color=#ff0000]< - - - !?!?[/color]
At tSCNT = 573 time is 569672 ms. [color=#ff0000]< - - - !?!?[/color]
At tSCNT = 574 time is 570672 ms.
At tSCNT = 575 time is 571672 ms.
?
At tSCNT = 866 time is 862672 ms.
At tSCNT = 867 time is 863672 ms.
At tSCNT = 868 time is 864672 ms.
At tSCNT = 869 time is 865860 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 870 time is 865633 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 871 time is 866633 ms.
At tSCNT = 872 time is 867633 ms.
?
At tSCNT = 1209 time is 1204633 ms.
At tSCNT = 1210 time is 1205633 ms.
At tSCNT = 1211 time is 1206633 ms.
At tSCNT = 1212 time is 1207696 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 1213 time is 1207471 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 1214 time is 1208471 ms.
At tSCNT = 1215 time is 1209472 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 1216 time is 1210472 ms.
At tSCNT = 1217 time is 1211472 ms.
?
At tSCNT = 1427 time is 1421472 ms.
At tSCNT = 1428 time is 1422472 ms.
At tSCNT = 1429 time is 1423472 ms.
At tSCNT = 1430 time is 1424489 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 1431 time is 1424264 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 1432 time is 1425264 ms.
At tSCNT = 1433 time is 1426264 ms.
?
At tSCNT = 2152 time is 2145264 ms.
At tSCNT = 2153 time is 2146264 ms.
At tSCNT = 2154 time is 2147264 ms.
At tSCNT = 2155 time is 2214591 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 2156 time is 2147519 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 2157 time is 2148519 ms.
At tSCNT = 2158 time is 2149519 ms.
At tSCNT = 2159 time is 2150519 ms.
At tSCNT = 2160 time is 2151519 ms.
At tSCNT = 2161 time is 2152519 ms.
At tSCNT = 2162 time is 2153519 ms.
At tSCNT = 2163 time is 2154519 ms.
At tSCNT = 2164 time is 2155520 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 2165 time is 2156520 ms.
At tSCNT = 2166 time is 2157520 ms.
?
At tSCNT = 2208 time is 2199520 ms.
At tSCNT = 2209 time is 2200520 ms.
At tSCNT = 2210 time is 2201520 ms.
At tSCNT = 2211 time is 2202532 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 2212 time is 2202307 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 2213 time is 2203307 ms.
At tSCNT = 2214 time is 2204307 ms.
?
At tSCNT = 3557 time is 3547307 ms.
At tSCNT = 3558 time is 3548307 ms.
At tSCNT = 3559 time is 3549307 ms.
At tSCNT = 3560 time is 3550477 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 3561 time is 3550252 ms.[color=#ff0000] < - - - !?!?[/color]
At tSCNT = 3562 time is 3551252 ms.
At tSCNT = 3563 time is 3552252 ms.
?
At tSCNT = 3629 time is 3618252 ms.
At tSCNT = 3630 time is 3619252 ms.
? Etc ?

If we look tSCNT after 1 hour the time error is +30 seconds.
If we look time in [ms] after 1 hour the time error is +19 seconds.

Try something like this:

unsigned long now = millis();
if (now > c_nextMillis || now - c_nextMillis <= 0 )
{
if (now > c_nextMillis) c_nextMillis = now + 1000 - (now - c_nextMillis);
if (now - c_nextMillis <= 0) c_nextMillis = now + 1000;
c_second++;

and make c_nextMillis global as a ULong.

Marco.