Arduino Delay Function: Why you need it and How to Use it. This is an Extremely Useful
function which you can use to get small delays. However, sometimes
it's not the right function to use - there is another!
Arduino delay:
It is useful for initializing some chips (sometimes you need to wait for them).
You do actually need a delay() function to allow human interaction - processors are too fast!
Another function with finer resolution is delayMicroseconds().
There is an alternative non-blocking delay function: millis() (a bit more complex to use).
Find out a gotcha in using delay().
Why you need the Arduino Delay function
The Arduino delay() function allows you to pause the program execution for a
specified number of milliseconds, which is useful when you need to
synchronize events or actions with real-world timing.
Note: This is a super-important-point: Pausing means the processor stops doing anything! - you'll see the implications of this later on!
It helps control
the speed of programs and operations.
The delay() function is commonly used when
initializing peripherals, waiting for readings to settle, or pacing
animated sequences. Without delay, code would execute at full speed and
it would be difficult to perceive what is happening.
There are two reasons for using the delay function:
1. Chip initialization.
2. Human interaction.
You will want to use delay() to slow down the processor e.g. to see
an LED flashing or to slow it down between sending commands to devices
Some chips require specific delays when you initialize them for
instance the Hitachi HD44780 needs milliseconds delay at a specific
time in its startup process. The delay function is appropriate in that process since
the delay is small and the processor does not need to
do anything else during startup.
Microcontrollers operate at a very fast rate (16MHz for an Arduino Uno - the ESP8266 runs at 80 or 160MHz!) and this is a good
thing since you can do more processing. The problem is that to interact
with the real world, you need to slow the processor down since real
world actions do not go at MHz rates! This is where the Arduino delay
function is useful.
Note: The corresponding Arduino microsecond delay function is delayMicroseconds().
Parameters for delay()
The delay() function requires one unsigned long integer parameter,
which specifies the number of milliseconds to pause program execution
for. Values must be between 0 and approximately 50 days due to data type
limitations (to understand this more there is an analysis of the millis() function, which examines this limit). Common delay times include:
Short delays between 0-100ms for blinking LEDs, button debouncing etc.
Medium delays 100-1000ms for user feedback, animation sequences
Long delays 1-60,000ms (1 minute) for sleep modes, slow sampling rates
It is a function that stays in a loop for the
number of milliseconds that you give it as an argument. A millisecond is
1/000th of a second so there are 1000 milliseconds in one second ( 1000ms = 1s ).
For a 1 second delay you would use the function delay() in your program as follows:
delay(1000);
Arduino Delay Function LED Example
For quick simple programs the Arduino delay() function provides a convenient
slow-down mechanism. Here's an example program for flashing the on-board LED
attached to pin 13 of the Arduino uno - the pin set to the relevant LED pin on different boards.
// Simple LED flash
#defineLED LED_BUILTIN//////////////////////////////////////////////
voidsetup(void){
pinMode(LED,OUTPUT);
}//////////////////////////////////////////////
// Arduino Delay LED flash
voidloop(){
delay(500);digitalWrite(LED,HIGH);
delay(500);
digitalWrite(LED,LOW);
}
Code Explanation
All it does is initialise the pin as an output in setup(). Then it
repeatedly executes the code in loop(). That is, it waits for half a second,
then sets the LED on, waits another half a second and sets the LED off. So over
the course of 1 second the LED is turned on for half a second and off for half
a second i.e. a rate of 1Hz. Then that action is repeated endlessly.
Useful Debug code
When you get into difficulties in using microcontrollers
(and you will!). Always go back to basics and use a program such as the one
above, since it is one of the simplest, and it will give you confidence that
the hardware is working e.g. that the power supply wires or ground wires are
connected correctly.
TIP: Use the simple LED flash code above to check a board works.
This is more important when you attach a development board
such as a solderless breadboard where connections can get unstuck!
Note: It should work on most boards as the LED_BUILTIN definition is used, and this is changed for each different board that you use.
Delay details
Delay variants
Arduino Delay milliseconds
You have seen the function delay() which takes one parameter representing milliseconds.
Arduino Delay microseconds
Another function you can use delayMicroseconds() which again takes a
parameter but this time representing micro seconds. Each microsecond is a
millionth of a second i.e. 1/1e6 seconds.
Arduino Delay nanoseconds
This is too small a delay for a microcontroller. For an Arduino Uno
the basic instruction takes 1/16e6 or 62.5ns. So having a function that
delays for a number of nano seconds can't be done. You can do it with a
faster processor but even a 240MHz processor's instruction is ~4ns so
you can't get lower than that.
In practice it is not used as the times involved are small to be useful to external operation.
Nano second delays only become important in circuit design using fast
logic chips (not microcontrollers) i.e. for normal HC chips a
propagation delay is ~20ns. You can get very high speed (ECL) chips that
run at 100MHz so operating with signals of the order of 10ns pulses is
needed for these chips.
Example delay values
Here are some common delay values for common time delays.
One Second delay Example
Use delay(1000) to pause for 1 second.
30 seconds delay Example
Use delay(30000) to pause for 30 seconds.
1 minute delay Example
Use delay(60000) to pause for 1 minute (60 seconds).
15 minute delay Example
Use delay(15*60000) to pause for 15 * 1 minute.
1 hour delay Example
Use delay(60*60000) to pause for 1 hour (60 minutes).
1 Day delay Example
Use delay(24 * 60 * 60 * 1000) to pause for 1day.
The Problem with Arduino
Delay
So far, everything looks great; Delays work fine and LEDs flash on and off,
but delay() has a skeleton in the cupboard.
delay() is a lazy function - it is a DO
NOTHING function or a blocking function.
When you use delay(), even though it is sometimes useful, you are throwing
away processing power straight out of the window never to be recovered!
TIP: Only use delay() for the simplest of programs.
When you start to write more substantial programs you will find that using
delay interferes with operations.
For example if you wanted to read a input button and react to that button
quickly e.g. within 100ms. If you had used a 200ms on/200ms off delay to flash
an LED on and off, you could not meet that requirement; 400ms would be lost
waiting in the delay routines. This is time that could be better spent in doing
useful processing.
Warning: Do not use delay() in an interrupt routine. since it
uses interrupts itself the interrupt routine would hang. Instead use
delayMicroseconds() - That function creates hard coded delays that are
interrupt safe.
So the question now becomes how do you actually create a delay but at the
same time use a delay that uses up minimal processor time.
The first option is easier and is explained more here.
The second is more advanced and involves using low level interrupt routines
and more hardware (to allow several keys to operate into one interrupt pin).
Arduino Delay Gotchas
This Arduino delay gotcha is fairly subtle and you may have already come
across it. It is all to do with scoping ( C/C++ rules of when a variable is
visible to other functions) and how the Arduino environment (although
convenient) does hide what is going on behind the scenes - and this can catch
you out.
The following code is trying to control the delay time by passing a variable
to the delay function which is changed when a button is pressed.
When you look at the code it looks perfectly reasonable; Use a variable to
hold the delay value and change the value dependent of the state of an input
button press, however it does not work! All that happens is that the Arduino
delay value is only ever set to 200.
The reason is that the functions setup() and loop() are artificial constructs that make programming
easier (sort of).
The setup() and loop() functions are inherited from the "processing"
environment which is a graphics coding system based on openGL. These two
functions make it easier to explain how a program is written i.e. you
first initialise variables and ports in setup() and then execute code
repeatedly in loop().
In fact the underlying compiler only starts a program from main()
and ends at the end of main() - there is no loop! You roll your own loops as
required! The actual code that lies above the familiar Arduino words 'setup'
and 'loop' is something like this:
Note: The main() function is the program that is called first
in a C/C++ program and it must always be present otherwise the compiler does
not know where to begin!
// main construct
voidmain(void){
setup();// Call the user defined code for setup
while(1)loop();// Continuously call the user defined code for loop.
}
As shown above when 'main()' is called, first of all the code within
function setup() is executed and then the function loop() is called repeatedly
(in a so-called endless loop). This is standard programming practice and all
that the Arduino code has done is removed the outer layer so it sort-of
simplifies the proceedings so that you only need to write those functions (
setup() and loop() ).
However you can't actually see that loop() is called (hidden in the Arduino
code similar to the code above) since you are never aware of the main()
function.
The key point is that scoping rules force all local
variables to be initialised at the start of any function and lost at
exit of that function. Therefore the value of dly is lost at the end of loop()
and so the code that sets the new value has no effect. All that happens is that
each time the function is started the dly variable is initialised to 200.
Note: Local variables are variables declared at the start of a
function (or for C++, within the function somewhere) and you use them to hold
temporary values throughout the function. They are lost at exit of the
function.
To make a function remember values between calls you need to preceded the
variable with the word static - meaning that the value of that variable is
going no where and is retained between calls to the function.
#defineLED LED_BUILTIN #defineINPUT5
//////////////////////////////////////////////
// Arduino Delay LED flash that works
voidloop(){
staticuint16_tdly=200;delay(dly);digitalWrite(LED,HIGH);
delay(dly);
digitalWrite(LED,LOW);
if(digitalRead(INPUT))dly=100;elsedly=10;}
More Usual Compiler Operation
Or how "normal" compilers work - not the Arduino compiler!
The real reason that there is a problem is that in a "standard compiler" program you
could have written the whole thing as follows using the main() function.
Warning: This is example code. You can not run this code in
the Arduino IDE - you would need to use an AVR compiler (and you will need a
bit more chip-setup code as well).
// main construct Full program non-Arduino compiler code.
// Arduino pins
#defineINPUT5#defineLED13
voidmain(void){
uint16_tdly=200;pinMode(LED,OUTPUT);// This was the code within setup()
while(1){}// Endless loop code
delay(dly);// This was the code within loop()
digitalWrite(LED,HIGH);
delay(dly);
digitalWrite(LED,LOW);
if(digitalRead(INPUT))dly=100;elsedly=10;
}
}
In this case the definition of dly does not need to be static since the
variable's scope is the whole of the main() function. In this case anything
within main() can see and use the variable dly.
This is the sort of code that you will have to write for most
microcontrollers since compiler makers do not mess about giving you the easy
route that the Arduino IDE/compiler does!
Conclusions
The Arduino delay function is a useful function allowing you to
interact with your design. It slows the processor down enough so that
the high speed of the processor is reduced to allow a person to see what
is going on.
The problem is that it is a blocking function, which means that it
wastes processor time, and you should really not use the Arduinino delay function, instead use the
millis() function.
The millis() function allows non blocking delays so that the
processor can get on with other operations even while the delay is being
calculated.
You can find more on the millis() function in this link. It is slightly more complicated to use but will ley your programs work better.
How to get accurate DHT22 digital humidity sensor readings with an Arduino. Did you know it also measures temperature as Well? Find out why, in this page...
A PIR sensor lets your Arduino sense movement without contact. This tutorial covers PIR sensor basics, connecting one to an Arduino board and coding a motion detector.
Arduino Hall Effect Sensor: Add magnetic sensing superpowers to your Arduino projects with an easy-to-use hall effect sensor. With full code and layout...
Comments
Have your say about what you just read! Leave me a comment in the box below.
Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.