In Arduino is there a Maximum delay time when using the fuction(Delay)

15,867

Solution 1

From the arduino reference page for delay the parameter for delay is an unsigned long

Unsigned longs on the arduino can reach from 0 to 4,294,967,295.

It is likely that the number being passed to 'delay' is being interpreted as an int. This would mean the delay is limited to a max of 32,767.

You should explicitly declare your delay value as an unsigned long like the solution in this post.

unsigned long seconds = 1000L; //Notice the L 
unsigned long minutes = seconds * 60;

delay(minutes); //for 60,000 milliseconds

Solution 2

Yeesh... someone cited this thread elsewhere, here is the correct explanation:

delay() takes an unsigned long (32-bit number between 0 and 2^32-1, or about 4.2 billion). And delay(60000) works fine. There are two ways that one could get into trouble trying to pass numbers larger than those used in blink, but smaller than 4.2 billion to delay()

First, if you generate the number on the spot by multiplying numbers together, for example delay(60*1000);

Both of these numbers will default to int (16-bit signed integer from -32768 to 32767), so that multiplication will overflow that… leaving you with -5536 if my math serves me… Then, that gets converted to an unsigned long, leaving you with 2^32-5536, or, well, approximately 4.2 billion.

Solution is simple - explicitly tell the compiler that you intend for that literal to be an unsigned long, by putting UL after one of the numbers (the other will be automatically promoted to unsigned long to match):

delay(60UL*1000);

The other way an arduino user could get in trouble here (really, the same way, only through a different route) would be if they assigned the delay to a data type that couldn’t fit it, for example:

int time=60000; //this ends up as -5536 too...

delay(time); //same result!

Solution is also quite simple - just declare time as an unsigned long, instead of int.

Note that the first case (but not the second), where the constant expression generates an overflow, would actually generate a compiler warning…. Except, arduino turns off compiler warnings by default. You can turn them back on in File -> preferences. Sometimes it will warn about things that are fine, but when you see warnings, and it’s not doing what you want, the warnings are a good place to start looking.

Background on delayMicroseconds()

The issue with delayMicroseconds() having the maximum length of 16383 is unrelated - that limitation is because delayMicroseconds is, under the hood, implemented completely differently from delay(). delay() is based on micros() and the millis timer system (a hardware timer is configured prior to setup() being called, with the overflow interrupt incrementing a global count of milliseconds; millis() uses that count, and micros uses that plus the current count on the timer). delayMicroseconds, however, needs much higher accuracy than that method could achieve (micros takes something like 7-8us to return, and has resolution of 4us, since the timer in question runs off the 16MHz clock with /64 prescale); it's implemented by counting clock cycles. It takes an unsigned int (16-bit) instead of unsigned long, first off. It multiplies the requested delay by 4 (for 16MHz clock, at least), converting it into the number of iterations of a loop written in inline assembler that takes 4 clock cycles per iteration. So that's where the apparent 14-bit limit comes from: the number of 4-cycle loops has to fit in 16 bits, so the number of microseconds is 1/4th that (assuming 16 MHz system clock - so an 8 MHz pro mini, for example, you could specify twice as long of a delay to delayMicroseconds()!). On an (admittedly rare) 20 MHz one, the longest delay would be around 13000 ((2^16-1)/(20/4=5)) Long before that, though, you're better off just doing a while loop that checks micros()...

Solution 3

given this link: https://www.arduino.cc/en/Reference/DelayMicroseconds

Currently, the largest value that will produce an accurate delay is 16383. This could change in future Arduino releases. For delays longer than a few thousand microseconds, you should use delay() instead.

all of which seems to indicate that the function is only paying attention to the lower 14 bits.

So even in the longer delay function: delay() it is likely that only the lower 14 bits are being utilized.

Share:
15,867
Mufaro Shumba
Author by

Mufaro Shumba

Updated on June 19, 2022

Comments

  • Mufaro Shumba
    Mufaro Shumba almost 2 years
    {
        digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(1000);              // wait for a second
        digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
        delay(1000);              // wait for a second
    }
    

    I am trying to set the Delay to 60,000 but when outputting it to the Arduino after 1 minute passes the light does not switch on.

    • user3629249
      user3629249 over 8 years
      Please post the code. What does the documentation say about the delay limitations? This seems to be a runtime question. You have indicated the expected and actual output. The next (and major) requirement for stackoverflow,com, is the source code.
    • Eugene Sh.
      Eugene Sh. over 8 years
      Are you calling it as delay(60000) or something like delay(60*1000)?
  • Mufaro Shumba
    Mufaro Shumba over 8 years
    Then it should work, but what I have decided to do was to split up my values and look through and that seems to work perfectly. But thank you for the response.