Foundations ยท responsive-timing
Make a sketch responsive
Question: Why can a long `delay()` make a robot feel unresponsive?
Understand the idea
The Arduino sketch repeatedly runs `loop()`. A long blocking delay pauses that ordinary program flow, so the sketch cannot promptly check a button, sample a sensor, or update another task during that pause.
A non-blocking timer compares the current `millis()` value with the time a task last ran. Use unsigned time values and subtraction (`now - previous >= interval`); this remains correct when the millisecond counter rolls over.
Scheduling is not the same as real-time guarantees. A loop can still be late if one task takes too long. Keep work bounded, measure timing, and move very time-critical work to an appropriate timer or interrupt design.
Worked example
If a status LED should toggle every 500 ms, store `previous = millis()`. When unsigned `(millis() - previous) >= 500`, update `previous` and toggle the output. The rest of the loop remains available between toggles.
Try it at the bench
- Blink one LED with `delay(500)` and notice how other code waits.
- Rewrite the blink using `millis()` and a saved previous timestamp.
- Add a button or serial command and verify it responds while the LED continues blinking.
Check your understanding
Why is `millis() - previous >= interval` safer than comparing `millis()` to `previous + interval`?
Show the answer
Unsigned subtraction handles the counter wrapping back to zero, provided the interval is much shorter than the counter's full range.