micros() for microsecond precision in Arduino - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
We want to understand how the time taken by code using micros() changes as the program runs longer.
How does the number of operations grow when measuring time in microseconds?
Analyze the time complexity of the following code snippet.
unsigned long startTime = micros();
while (micros() - startTime < 1000) {
// wait for 1000 microseconds (1 millisecond)
}
This code waits for 1000 microseconds by repeatedly checking the current time using micros().
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The
whileloop repeatedly callsmicros()to check elapsed time. - How many times: The loop runs until the difference reaches 1000 microseconds, so about 1000 times.
Explain the growth pattern intuitively.
| Input Size (microseconds) | Approx. Operations (loop iterations) |
|---|---|
| 10 | ~10 calls to micros() |
| 100 | ~100 calls to micros() |
| 1000 | ~1000 calls to micros() |
Pattern observation: The number of loop iterations grows directly with the microseconds to wait.
Time Complexity: O(n)
This means the time spent waiting grows linearly with the number of microseconds you want to wait.
[X] Wrong: "Calling micros() inside the loop is instant and does not affect timing."
[OK] Correct: Each call to micros() takes some time, so the loop runs about as many times as the microseconds you wait, making the total time proportional to the wait time.
Understanding how loops with time checks grow helps you write efficient timing code in embedded systems, a useful skill for real projects and interviews.
"What if we replaced micros() with a function that updates less often, like millis()? How would the time complexity change?"
Practice
micros() return?Solution
Step 1: Understand the purpose of
Themicros()micros()function returns the time in microseconds since the Arduino program began running.Step 2: Compare options with the function's behavior
Only The number of microseconds since the program started correctly states it returns microseconds since start. Others mention milliseconds or seconds, which are incorrect.Final Answer:
The number of microseconds since the program started -> Option AQuick Check:
micros()= microseconds since start [OK]
- Confusing micros() with millis()
- Thinking it returns seconds
- Assuming it resets every second
Solution
Step 1: Identify the data type returned by
Themicros()micros()function returns an unsigned long integer representing microseconds.Step 2: Match the correct variable type to store the value
Onlyunsigned longcan hold the large values frommicros()without overflow or sign issues.Final Answer:
unsigned long time = micros(); -> Option AQuick Check:
Use unsigned long for micros() values [OK]
- Using int which is too small
- Using float which loses precision
- Using signed long which can cause negative values
unsigned long start = micros(); // some delay here unsigned long end = micros(); unsigned long diff = end - start; Serial.println(diff);Assuming the delay is about 500 microseconds.
Solution
Step 1: Understand the timing measurement
The code measures the time difference in microseconds between two calls tomicros().Step 2: Interpret the delay and difference calculation
If the delay is about 500 microseconds, the differencediffwill be close to 500, printed as a positive number.Final Answer:
A number close to 500 -> Option DQuick Check:
diff = end - start ≈ 500 [OK]
- Expecting milliseconds instead of microseconds
- Thinking difference can be negative
- Confusing delay units
unsigned long start = micros(); // some code unsigned long end = micros(); int elapsed = end - start; Serial.println(elapsed);
Solution
Step 1: Check variable types for time difference
The difference between twomicros()values can be very large, exceeding the range ofint.Step 2: Understand overflow risk
Usingint(usually 16-bit) can cause overflow and incorrect negative values. It should beunsigned long.Final Answer:
Using int for elapsed can cause overflow -> Option BQuick Check:
Use unsigned long for elapsed time to avoid overflow [OK]
- Using int instead of unsigned long
- Thinking micros() returns signed values
- Assuming Serial.println can't print integers
micros(). Which approach correctly handles the timing even if the program runs longer than 70 minutes (when micros() overflows)?Solution
Step 1: Understand micros() overflow behavior
micros()overflows roughly every 70 minutes, wrapping back to zero.Step 2: Use unsigned long subtraction to handle overflow
Unsigned subtraction correctly calculates elapsed time even if overflow happens, somicros() - startworks safely.Final Answer:
Store start time, then calculate elapsed asmicros() - startusing unsigned long subtraction -> Option CQuick Check:
Unsigned subtraction handles micros() overflow correctly [OK]
- Thinking micros() never overflows
- Using millis() which has lower precision
- Resetting Arduino unnecessarily
