millis() helps you keep track of time without stopping your program. It lets your Arduino do other things while waiting.
millis() for non-blocking timing in Arduino
Start learning this pattern below
Jump into concepts and practice - no test required
unsigned long previousMillis = 0; const unsigned long interval = 1000; // time in milliseconds void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; // do something every interval } }
millis() returns the number of milliseconds since the Arduino started.
Use unsigned long to store millis() values to avoid errors when the number gets big.
unsigned long previousMillis = 0; const unsigned long interval = 1000; void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; // toggle LED } }
unsigned long previousMillis = 0; const unsigned long interval = 5000; void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; // read sensor every 5 seconds } }
unsigned long previousMillis = 0; const unsigned long interval = 1000; void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; // do something } // other code runs here without delay }
This program blinks the built-in LED on pin 13 every second without stopping the program. It prints the LED state to the Serial Monitor each time it changes.
#define LED_PIN 13 unsigned long previousMillis = 0; const unsigned long interval = 1000; // 1 second bool ledState = false; void setup() { pinMode(LED_PIN, OUTPUT); Serial.begin(9600); Serial.println("Starting non-blocking LED blink"); } void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; ledState = !ledState; // toggle LED state digitalWrite(LED_PIN, ledState ? HIGH : LOW); Serial.print("LED is now "); Serial.println(ledState ? "ON" : "OFF"); } // Other code can run here without delay }
Time complexity: Checking millis() and comparing times is very fast, almost constant time.
Space complexity: Uses only a few variables, so very low memory use.
Common mistake: Using int instead of unsigned long for millis() values causes errors when millis() gets large.
Use millis() timing instead of delay() when you want your Arduino to do many things at once without freezing.
millis() returns the time since the Arduino started, letting you track time without stopping your program.
Use a variable to remember the last time you did something, then check if enough time passed.
This method helps your Arduino multitask and stay responsive.
Practice
millis() function in Arduino return?Solution
Step 1: Understand what
millis()measuresmillis()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 BQuick Check:
millis()= milliseconds since start [OK]
- Confusing millis() with delay()
- Thinking millis() returns seconds
- Assuming millis() gives current date/time
millis() in Arduino?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(); usesunsigned long, which can hold large millisecond values without overflow.Final Answer:
unsigned long currentTime = millis(); -> Option DQuick Check:
Use unsigned long for millis() values [OK]
- Using int which can overflow quickly
- Using float or char which are incorrect types
- Not declaring variable before assignment
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");
}
}Solution
Step 1: Understand the timing logic
The code checks if 1000 milliseconds have passed since last print usingmillis()and updatespreviousMillisaccordingly.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 CQuick Check:
Non-blocking timing prints "Tick" every second [OK]
- Thinking it prints only once
- Confusing with delay() causing blocking
- Assuming compile error due to variable scope
millis() for timing:
unsigned long previousMillis;
const long interval = 2000;
void setup() {
Serial.begin(9600);
}
void loop() {
if (millis() - previousMillis >= interval) {
Serial.println("Hello");
}
}Solution
Step 1: Check how previousMillis is used
The code checks the time difference but never updatespreviousMillisafter 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 AQuick Check:
Update previousMillis to avoid continuous printing [OK]
- Forgetting to update previousMillis
- Thinking interval type causes error
- Assuming Serial.begin() is missing
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
}
B) void loop() {
delay(500);
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
C) 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);
}
}Solution
Step 1: Identify non-blocking timing usage
Correct non-blocking blink using millis() and toggling LED usesmillis()difference and updatespreviousMilliscorrectly, toggling LED without delay.Step 2: Compare other options for blocking or logic issues
The other snippets either usedelay(), 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 AQuick Check:
Use millis() difference and update previousMillis [OK]
- Using delay() causing blocking
- Not updating previousMillis properly
- Using addition risking overflow bugs
