In the last chapter, we know delays are used to hold the program
for some amount of defined time means the program will pause for some interval and then
again resumes the code. So the problem with the delay function is that it blocks
the code, the code after the delay statement will not execute unless and until the
time interval gets over. If we want to execute more than two tasks at the same time
interval in a parallel manner, then there will be a problem for us. So the
solution to this problem is using millis() function.
What is millis() function??
millis() functions are the Arduino built-in function that returns
times in milliseconds from where Arduino is turned ON or Arduino started. millis function
counts the number of clock ticks that are generated by a crystal oscillator. millis()
function does not block the entire code just like delay.
To know about millis() function we must know about the timer and
counter. The hardware clock generated a signal at a constant frequency, this frequency
is like a square wave. Many circuits such as crystal oscillators are used to
generate this clock signal. These clocks generate a continuous number of ticks.
Arduino has a built-in-timer counter module to count these ticks.
This module counts ticks from where Arduino is ON or get
started or power ON. When you restart or turn off the Arduino the module start
counting from 0. The maximum day module count without interruption is 49 days.
The module starts over means it again starts from 0 (zero).
int current time = millis()
To access this millis() function we have to call it, this
function returns values which will be stored in variable name as the current time.
So the question is what will be the value inside the variable
current time
The answer is it has the amount of time in milliseconds from
which Arduino was started till now.
For one minute it returns 60,000 because in one minute we
have 60 sec.
60 sec x 1000 ms = 60,000
The maximum value return by millis function is
4,29,4967,295. So the data type we need to store such a big value should also be
big. Here we have unsigned long, it is the largest datatype for storing values.
If you don’t about data types you can check my Arduino lesson.
Difference between delay() function and millis() function
delay() function | millis() function |
---|---|
Return no values | Return values (time) in milliseconds |
delay() receives parameter (time) in milliseconds | millis() has no parameter |
Blocks entire code | runs in backgrounds without blocking code |
Use for single-task applications | Use in multi-tasking applications |
delay() vs millis()
delay() function can be used in single task purpose where there is only one task to occur in a time interval because delay function blocks or holds the entire code due to this another task which depends upon time interval gets affected, whereas millis() function is used multipurpose task handling. We use millis() function when there are multiple events to occur in independent repetitive time intervals. Multiple events can overlap each other without affecting other events' timelines. millis() function does not block or hold the entire code rather it runs in the background without interfering with the main code. The task gets triggers and events occur without holding a timeline for other events.
Suppose there are two events first is turning on LED 1 every
after 5 seconds and the second event is turning LED 2 ON every 2 seconds. First, we
will see these two tasks using the delay function. First, we have to turn LED 1 ON
after 5 seconds so we introduce a delay of 5 seconds delay(5000), Later we
turn LED 1 ON. In the second event, we have to turn LED 2 ON after 2 seconds so
again we introduce a delay of 2-sec delay(2000) but the problem is that if we
introduce a delay here then the delay will block the code means in the first case delay
will hold the program for 5 seconds LED 1 will turn ON then after 2 seconds LED
2 will turn ON. so 5 seconds + 2 seconds = 7 seconds means seconds LED 2 will
turn ON after 7 seconds but in our condition, we want to turn on LED 2 every
time after 2 seconds hence events do not trigger on desire timeline also as
we know in code inside void loop repeats continuously so delay from LED 1 (5
sec) + LED 2 (2 sec) = 7 seconds means also LED 1 will turn ON after 7 seconds
but we want LED 1 to turn ON after 5 seconds hence condition will not
satisfied for LED 1, the delay affects both events in the timeline to occur due to its
blocking the code nature. So here we understand why we avoid delays for multiple
events or task handling. millis can last Upton 49 days then after 49 days
millis rolls over and start counting from 0 again.
Now let’s handle this multiple tasking problem using millis() function, as we know millis() function runs in the background so there is no blocking or interruption in code so that occurrence of the events takes place independently. We use millis() function when we need independent repetitive time events to occur. So let’s see how to use millis() functions with an example and also see how to use millis() function.
void setup() {
Serial.begin(115200);
}
void loop()
{
unsigned long currentTime = millis();
Serial.print("Current Time : ");
Serial.println(currentTime);
if (currentTime - previousTime >= eventTime)
{
Serial.print("I am inside millis ");
previousTime = currentTime;
}
}
As millis() functions return values that are very huge so we have initialized variables in unsigned long datatypes to store big values. We have initialized event time which is the time at which the occurrence of events or task takes place. We have also initialized the previous time variable and set it to 0. We have declared a variable name current time to store values return from millis(). In the void setup, we simply initialize the baud rate to 115200 to see values on serial monitoring.
In the void loop we are storing the value of millis in variable currentTime then we will check the condition in if statement. Suppose first millis returns 100ms so currentTime - previousTime >= eventInterval (100 – 0 = 100 ≠ 1000). currentTime – previousTime is not equal to eventTime (1000), we have set eventTime to 1000 means event will occur in every 1 sec. again value of millis will update to 300, so currentTime - previousTime >= eventInterval (300 – 0 = 300 ≠ 1000) currentTime – previousTime is not equal to eventTime. Again value of millis will update to 1000, so currentTime - previousTime >= eventInterval (1000 – 0 = 1000 = 1000) currentTime – previousTime is equal to eventTime now condition will get satisfied and enter inside millis() function and print “I am inside millis” and value of currentTime which is 1000 will get transfer from currentTime to previousTime means value of previousTime will get update from 0 to 1000.
Again value of millis will update to 1500, so currentTime - previousTime >= eventInterval (1500– 1000 = 500 ≠ 1000) currentTime – previousTime is not equal to eventTime. So condition will not satisfied. Again value of millis will update to 2000, so currentTime - previousTime >= eventInterval (2000– 1000 = 1000 = 1000) currentTime – previousTime is equal to eventTime. So condition will be satisfied and enter inside millis() function and print “I am inside millis” and value of currentTime which is 2000 will get transfer from currentTime to previousTime means value of previousTime will get update from 1000 to 2000. Again value of millis will update to 2500, so currentTime - previousTime >= eventInterval (2500– 2000 = 500 ≠ 1000) currentTime – previousTime is not equal to eventTime. So condition will not satisfied. So in this way millis function works, now we will see example of millis in using two different LED glowing in different time intervals.
Examples of millis() function of two events (multi-tasking)
const unsigned long eventInterval_2 = 2000;
int LED_2 = 9;
unsigned long previousTime_2 = 0;
Serial.begin(115200);
pinMode(LED_1,OUTPUT);
pinMode(LED_2,OUTPUT);
}
unsigned long currentTime = millis();
Serial.print("Current Time : ");
Serial.println(currentTime);
if (currentTime - previousTime_1 >= eventInterval_1)
{
digitalWrite(LED_1,HIGH);
Serial.print("*********************************");
Serial.print(" LED 1 : ON ");
Serial.println("*********************************");
previousTime_1 = currentTime;
}
{
digitalWrite(LED_2,HIGH);
Serial.print("*********************************");
Serial.print(" LED 2 : ON ");
Serial.println("*********************************");
}
}
We have two events here in the first event we will turn ON LED 1
in 5 seconds and the second LED 2 in 2 seconds. We have seen this example of
multi-tasking in delay and also the problem caused by using the delay() function.
As we know there are two events so we will set two-time
intervals, first LED 1 to turn ON at 5 seconds and LED 2 to turn ON at 2 seconds
therefore we have set event interval 1 = 5000 and event internal 2 = 2000 and
two LED connected at pin number 8 and pin 9 of Arduino. We also have initialized
two variables previous time 1 and previous time 2 to 0.
In the void setup, we have declared two led as output and set the baud
rate to 115200. Now In a void loop, we are storing the value of millis in variable
currentTime then we will check the condition in if statement. Suppose first
millis returns 100ms so currentTime – previousTime_1 >= eventInterval_1 (100
– 0 = 100 ≠ 5000) & so currentTime – previousTime_2 >= eventInterval_2 (100
– 0 = 100 ≠ 2000). currentTime – previousTime is not equal to both eventTime
intervals i.e. eventInterval_1 and eventInterval_2 so both conditions will not
satisfied and hence no LED will be turned ON. Suppose again millis returns 2000 ms
so currentTime – previousTime_1 >= eventInterval_1 (2000 – 0 = 2000 ≠ 5000)
& so currentTime – previousTime_2 >= eventInterval_2 (2000 – 0 = 2000 = 2000).
currentTime – previousTime is not equal to eventInterval_1 but currentTime –
previousTime_2 is equal to eventInterval_2 so the first LED 1 condition will not be satisfied but the second LED 2 condition will be satisfied and LED 2 will glow and the value of current time will be updated to previousTime_2 (from 0 to 2000).
Suppose again millis returns 4000 ms so currentTime –
previousTime_1 >= eventInterval_1 (4000 – 0 = 4000 ≠ 5000) & so currentTime
– previousTime_2 >= eventInterval_2 (4000 – 2000 = 2000 = 2000). currentTime
– previousTime_1 is not equal to eventInterval_1 but currentTime – previousTime_2
equal to eventInterval_2 as value of previousTime_2 is updated from 0 to 2000. so
first LED 1 condition will not be satisfied but the second LED 2 condition will be satisfied and LED 2 will glow and the value of current time will be updated to
previousTime_2 (from 2000 to 4000).
Again millis returns 5000 ms so currentTime – previousTime_1 >= eventInterval_1 (5000 – 0 = 5000 = 5000) & so currentTime – previousTime_2 >= eventInterval_2 (5000 – 4000 = 1000 ≠ 2000). currentTime – previousTime_1 is equal to eventInterval_1 but currentTime – previousTime_2 not equal to eventInterval_2 as value of previousTime_2. So first of LED 1 condition will be satisfied and LED 1 will glow and the value of the current time will be updated to previousTime_1 (from 0 to 5000). But second LED 2 condition will not be satisfied and LED 2 will not glow. In this way, we can use millis() functions to run multiple events in code without blocking or affecting the timeline of other events making events independent from each other.
Now we used the serial monitor to observe the output. To open up the serial monitor, click on Tools > Serial Monitor or use the shortcut (SHIFT + CONTROL + M). Here you can see in the Serial monitor when a time interval for a particular event occurs it gets executed without blocking the timeline of another event. as we know we want to turn ON LED 1 at 5 seconds so using millis() we have to turn it ON at 5 seconds we have printed the text "LED 1: ON" for understanding. similarly, we know we want to turn ON LED 2 at 2 seconds we have to turn it ON at 2 seconds we have printed the text "LED 2: ON".
Conclusion -
Today we learn about what is millis() function is, how to use millis() function in Arduino, why we required millis() function, and the drawbacks of the delay() function. when to use millis functions, why to use millis() function instead of delay and we have also seen two LEDs glowing Event example using millis().
"I hope you find this IoT blog very helpful to you. In the upcoming lesson, we will see more about IoT sensors till then bye. See you all in my next blog."