Jump into concepts and practice - no test required
or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Using millis() for Non-Blocking Timing in Arduino
📖 Scenario: You want to blink an LED on your Arduino board without stopping the rest of your program. Using delay() stops everything, so you will learn how to use millis() to blink the LED without blocking other code.
🎯 Goal: Build a program that blinks the built-in LED on and off every second using millis() for timing, so the program can do other things without waiting.
📋 What You'll Learn
Create a variable to store the LED pin number
Create a variable to store the interval time in milliseconds
Use millis() to check elapsed time without blocking
Toggle the LED state every interval
Print the LED state to the Serial Monitor
💡 Why This Matters
🌍 Real World
Non-blocking timing is important in real devices to keep them responsive while doing tasks like blinking LEDs or reading sensors.
💼 Career
Understanding how to use <code>millis()</code> for timing is a key skill for embedded systems and Arduino programming jobs.
Progress0 / 4 steps
1
Set up LED pin and initial variables
Create a variable called ledPin and set it to LED_BUILTIN. Create a variable called previousMillis and set it to 0. Create a variable called interval and set it to 1000 (milliseconds).
Arduino
Hint
Use int for ledPin, unsigned long for previousMillis, and const long for interval.
2
Initialize the LED pin and Serial in setup()
Write a setup() function. Inside it, use pinMode(ledPin, OUTPUT); to set the LED pin as output. Also, start serial communication with Serial.begin(9600);.
Arduino
Hint
Remember to open the serial monitor at 9600 baud to see the output.
3
Write the non-blocking timing logic in loop()
Write a loop() function. Inside it, create a variable currentMillis and set it to millis(). Use an if statement to check if currentMillis - previousMillis is greater than or equal to interval. If yes, update previousMillis to currentMillis, toggle the LED state using digitalWrite().
Arduino
Hint
Use a static bool ledState to remember the LED state between loops.
4
Print the LED state to Serial Monitor
Add a Serial.print("LED is "); and Serial.println() inside the if block in loop() to print "ON" when the LED is on and "OFF" when it is off.
Arduino
Hint
Use the ternary operator ledState ? "ON" : "OFF" to print the correct state.
Practice
(1/5)
1. What does the millis() function in Arduino return?
easy
A. The current date and time
B. The number of milliseconds since the Arduino board started running the current program
C. The number of microseconds since the last reset
D. The current time in seconds
Solution
Step 1: Understand what millis() measures
millis() returns the time in milliseconds since the Arduino started running the program.
Step 2: Compare options with the definition
Only The number of milliseconds since the Arduino board started running the current program correctly describes this behavior; others mention seconds, microseconds, or date/time which are incorrect.
Final Answer:
The number of milliseconds since the Arduino board started running the current program -> Option B
Quick Check:
millis() = milliseconds since start [OK]
Hint: Remember millis() counts milliseconds since start [OK]
Common Mistakes:
Confusing millis() with delay()
Thinking millis() returns seconds
Assuming millis() gives current date/time
2. Which of the following is the correct way to store the current time using millis() in Arduino?
easy
A. char currentTime = millis();
B. int currentTime = millis();
C. float currentTime = millis();
D. unsigned long currentTime = millis();
Solution
Step 1: Identify the correct data type for millis()
millis() returns an unsigned long value representing milliseconds.
Step 2: Match the data type with variable declaration
Only unsigned long currentTime = millis(); uses unsigned long, which can hold large millisecond values without overflow.
Final Answer:
unsigned long currentTime = millis(); -> Option D
Quick Check:
Use unsigned long for millis() values [OK]
Hint: Use unsigned long to store millis() time [OK]
Common Mistakes:
Using int which can overflow quickly
Using float or char which are incorrect types
Not declaring variable before assignment
3. What will the following Arduino code print to the Serial Monitor?
unsigned long previousMillis = 0;
const long interval = 1000;
void setup() {
Serial.begin(9600);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
Serial.println("Tick");
}
}
medium
A. Prints "Tick" once and stops
B. Prints "Tick" continuously without delay
C. Prints "Tick" every 1000 milliseconds without stopping the program
D. Causes a compile error due to variable scope
Solution
Step 1: Understand the timing logic
The code checks if 1000 milliseconds have passed since last print using millis() and updates previousMillis accordingly.
Step 2: Analyze the output behavior
When 1000 ms pass, it prints "Tick" and continues looping without blocking, so it prints every second repeatedly.
Final Answer:
Prints "Tick" every 1000 milliseconds without stopping the program -> Option C
Quick Check:
Non-blocking timing prints "Tick" every second [OK]
Hint: Check millis() difference to print repeatedly [OK]
Common Mistakes:
Thinking it prints only once
Confusing with delay() causing blocking
Assuming compile error due to variable scope
4. Identify the error in this Arduino code using millis() for timing:
unsigned long previousMillis;
const long interval = 2000;
void setup() {
Serial.begin(9600);
}
void loop() {
if (millis() - previousMillis >= interval) {
Serial.println("Hello");
}
}
medium
A. previousMillis is never updated, so "Hello" prints continuously
B. interval should be unsigned long, not long
C. Serial.begin() is missing in setup()
D. millis() cannot be used in loop()
Solution
Step 1: Check how previousMillis is used
The code checks the time difference but never updates previousMillis after printing.
Step 2: Understand the effect of missing update
Without updating, the condition stays true, so "Hello" prints repeatedly without delay.
Final Answer:
previousMillis is never updated, so "Hello" prints continuously -> Option A
Quick Check:
Update previousMillis to avoid continuous printing [OK]
Hint: Always update previousMillis after action [OK]
Common Mistakes:
Forgetting to update previousMillis
Thinking interval type causes error
Assuming Serial.begin() is missing
5. You want to blink an LED every 500 milliseconds without stopping other code from running. Which code snippet correctly uses millis() for this non-blocking timing?
A)
unsigned long previousMillis = 0;
const long interval = 500;
void loop() {
if (millis() - previousMillis >= interval) {
previousMillis = millis();
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
// other code runs here
}
unsigned long previousMillis = 0;
const long interval = 500;
void loop() {
if (millis() >= previousMillis + interval) {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
previousMillis = millis();
}
}
D)
unsigned long previousMillis = 0;
const long interval = 500;
void loop() {
if (millis() - previousMillis > interval) {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
}
}
hard
A. Correct non-blocking blink using millis() and toggling LED
B. Uses delay(), which blocks other code from running
C. Correct logic but may cause overflow issues with addition
D. Uses delay() inside if, causing blocking and incorrect blink
Solution
Step 1: Identify non-blocking timing usage
Correct non-blocking blink using millis() and toggling LED uses millis() difference and updates previousMillis correctly, toggling LED without delay.
Step 2: Compare other options for blocking or logic issues
The other snippets either use delay(), which blocks other code from running, or use addition in the condition, which can cause overflow issues with large millisecond values.
Final Answer:
Correct non-blocking blink using millis() and toggling LED -> Option A
Quick Check:
Use millis() difference and update previousMillis [OK]
Hint: Toggle LED using millis() difference, avoid delay() [OK]