Go Down

Topic: maximum delay() is 32767ms ? (Read 7 times) previous topic - next topic

TomP

From playing with it, it looks like the argument to the delay() function is treated as a signed int, making the maximum delay something like 32767 milliseconds.  Is that correct?  If so, it would be helpful to update the reference page for delay() to make this clear.  Currently there's no mention there of a maximum possible delay.  

I noticed this when I tried setting a delay of 60*1000 (one minute) and found that my sketch just hung at that point.  A delay of 30000 works, on the other hand.

Thanks.

TomP

My bad.  I see now (from wiring.h) that the delay() function takes an unsigned long, so it should work for much longer delays than I was trying to use.  My mistake was multiplying a signed integer variable and a signed integer constant to get the delay time.  Making the variable unsigned long fixed things.

Sorry for the distraction...

tkbyd

#2
Feb 13, 2008, 10:43 am Last Edit: Feb 13, 2008, 10:49 am by tkbyd Reason: 1
"Your bad".... NOT!

I'm puzzled why the 60 * 1000 didn't work but passed (I presume?) the compiler's validity tests, and would welcome claification on that point.

And even though it wasn't the answer to what you were seeing, I'd welcome what you suggested. If someone who knows the answer would modify the entry at....

http://www.arduino.cc/en/Reference/Delay

... to make explicit what the largest acceptable arguement is, I think it would be a good addition. The entries for miilis and pulseIn are very good in this respect. It would be great if the explicit statement of different functions needs were to be extended.

mellis

I just did a few quick tests, and I think the issue is not with the delay() function, but with the multiplication.  The compiler treats an "integer literal" (e.g. 60 or 1000) as an "int" (which can hold numbers from -32,768 to 32,767) not as a long (which goes from negative to positive 2 billion or so).  So when you try to multiply the two integers 60 and 1000, the result (60,000) is bigger than what can fit in an int, and so it overflows to a negative number.  Then delay() gets called with a negative number (which actually gets turned into a very large positive one, since delay() takes an unsigned long), which makes it hang.  You can get around this by putting an L after one or both of the numbers, e.g. delay(60L * 1000L); (as described, though not in much detail on the integer constants page).

I'll add something about not passing a negative number to delay(), and try to clarify what happens when arithmetic overflows on the arithmetic page.  And also the fact that numbers like 60 are treated as integers (not longs).

kg4wsv

Could some C++ strong typing, function overloading, and an extra version or three of delay() take care of this problem?  Maybe one delay() for each of the following input types: int, unsigned int, long, unsigned long.

Of course, there's not a lot of room on the ATmega for code bloat...

-j


Go Up