Strange delay behaviour

I have posted about this earlier, but I’d like to return to this again. My Duemilanoves delay() function behaves oddly. The following piece of code:

void loop()
{
  delay(1000);
  unsigned long secs = millis()/1000;
  Serial.println(secs);
}

produces output like:

1
1
1
1
1
1
1
2
2
2
2
2
2
2
2
3
3
3
3
3
3
3
3
4
4
4
4
4

The code works perfectly on Nano and on OakMircos board.

If I put this function in my sketch and use it instead of delay()

void arduino_delay(unsigned long ms)
{
        unsigned long start = millis();
        
        while (millis() - start <= ms)
                ;
}

it ticks like a clock. I can’t understand that, because that’s exactly the same code as the delay()'s implementation in wiring.c.

Btw, shouldn’t the delay() check if millis() overflows?

I.e., wouldn’t the correct implementation be something like:

delay(unsigned long ms)
{
   unsigned long start_at = millis();
   unsigned long expires = start_at + ms;
   unsigned long now;
   if (expires < start_at) 
        // will overflow
        while ((now = millis()) >= start_at || now <= expires);
   else 
        // normal case
        while (millis() <= expires); 
                
}

I modified your code slightly:

void loop()
{
  delay(1000);
  unsigned long msec = millis();
  unsigned long secs = msec/1000;
  
  Serial.print("Seconds: ");
  Serial.print(secs);
  Serial.print("    Milliseconds: ");
  Serial.println(msec);
}

I got this output:

Seconds: 1    Milliseconds: 1001
Seconds: 2    Milliseconds: 2035
Seconds: 3    Milliseconds: 3069
Seconds: 4    Milliseconds: 4103
Seconds: 5    Milliseconds: 5136
Seconds: 6    Milliseconds: 6170
Seconds: 7    Milliseconds: 7204
Seconds: 8    Milliseconds: 8238
Seconds: 9    Milliseconds: 9271
Seconds: 10    Milliseconds: 10305
Seconds: 11    Milliseconds: 11341
Seconds: 12    Milliseconds: 12377
Seconds: 13    Milliseconds: 13412
Seconds: 14    Milliseconds: 14448
Seconds: 15    Milliseconds: 15484
Seconds: 16    Milliseconds: 16520
Seconds: 17    Milliseconds: 17556
Seconds: 18    Milliseconds: 18592
Seconds: 19    Milliseconds: 19628
Seconds: 20    Milliseconds: 20663
Seconds: 21    Milliseconds: 21699
Seconds: 22    Milliseconds: 22735

Could you run this on your Arduino, and show the results?

Seconds: 1    Milliseconds: 1001
Seconds: 1    Milliseconds: 1006
Seconds: 1    Milliseconds: 1011
Seconds: 1    Milliseconds: 1017
Seconds: 1    Milliseconds: 1023
Seconds: 2    Milliseconds: 2030
Seconds: 2    Milliseconds: 2035
Seconds: 2    Milliseconds: 2040
Seconds: 2    Milliseconds: 2046
Seconds: 3    Milliseconds: 3054
Seconds: 3    Milliseconds: 3059
Seconds: 3    Milliseconds: 3064
Seconds: 3    Milliseconds: 3070
Seconds: 4    Milliseconds: 4078
Seconds: 4    Milliseconds: 4083
Seconds: 4    Milliseconds: 4088
Seconds: 4    Milliseconds: 4094
Seconds: 5    Milliseconds: 5102
Seconds: 5    Milliseconds: 5107
Seconds: 5    Milliseconds: 5112
Seconds: 5    Milliseconds: 5118
Seconds: 6    Milliseconds: 6126
Seconds: 6    Milliseconds: 6131
Seconds: 6    Milliseconds: 6136
Seconds: 6    Milliseconds: 6142
Seconds: 7    Milliseconds: 7150
Seconds: 7    Milliseconds: 7155
Seconds: 7    Milliseconds: 7160
Seconds: 7    Milliseconds: 7166

Serial baud rate was 57600.

There is nothing wierd with these results.

You delay for (about) a second. Do some calculations, and print them to the serial.

void loop()
{
  unsigned long pre = millis();
  delay(1000);
  unsigned long post = millis();
  unsigned long secs = post - pre;
  Serial.println(secs);
}

There IS something weird about the results. We are running, theoretically, the same sketch, and seeing different results. Mine look right. His do not.

Sorry :-[

Maybe pekka is running at 4MHz ? [edit]Wait. That is not a logical proposal.

What version of the IDE, which board, at what frequency?[/edit]

There is nothing wierd with these results.

Nothing wierd :o? I thought that it should take at least a second before delay(1000) returns. And yet I was able to call delay(1000) four times within a second.

This is what your code prints out:

1001
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1001
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1001
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1001
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

Im running Arduino Duemilanove. I tested on both 0015 and 0017 ide versions. I haven't do anything to change the frequency, so I think it is 16MHz. What puzzles me most is that if I move the delay implementation from wiring.c in to the sketch it works as expected.

Btw, I believe that delay()'s implementation in wiring.c is incorrect because I does not check if millis() overflows. This certainly does not have anything to do with the strange behaviour I encountered, but it may cause problems if a sketch runs longer than 2**32-1 milliseconds (about 50 days).

Btw, I believe that delay()'s implementation in wiring.c is incorrect because I does not check if millis() overflows. This certainly does not have anything to do with the strange behaviour I encountered, but it may cause problems if a sketch runs longer than 2**32-1 milliseconds (about 50 days).

I will move discussion about this possibly incorrect delay implementation to another thread because it does not probably have anything to do with the actual problem I am troubleshooting here.

I ran your code, AlphaBeta, and I get a string of 1001's, which is wat I would expect.

Quoting myself again:

Quote: Btw, I believe that delay()'s implementation in wiring.c is incorrect because I does not check if millis() overflows. This certainly does not have anything to do with the strange behaviour I encountered, but it may cause problems if a sketch runs longer than 2**32-1 milliseconds (about 50 days).

I will move discussion about this possibly incorrect delay implementation to another thread because it does not probably have anything to do with the actual problem I am troubleshooting here.

I was probably wrong about that and there isn't an overflow problem after all.