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

  1. Blink one LED with `delay(500)` and notice how other code waits.
  2. Rewrite the blink using `millis()` and a saved previous timestamp.
  3. 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.

Browse all course lessons