Jan 2, 2026

A better way to create non-blocking timed events in C++ /Arduino

I've been using the usual if / counter / compare style timers for years — increment a counter, check thresholds, reset, repeat. It works, but it's easy to get edge cases wrong, and it clutters logic. I recently learned a much cleaner approach that treats time as a phase and simply asks a question: “am I in the ON window right now?”

The result is a tiny helper that returns a boolean. No counters, no wrap bugs, no blocking. Just compute phase and decide.


// Return true during the ON window of a periodic heartbeat
bool heartbeatActive(uint32_t now_ms,
                     uint32_t period_ms,
                     uint32_t on_ms)
{
    // compute position within the cycle
    uint32_t phase = now_ms % period_ms;
    return (phase < on_ms);
}

Usage becomes very declarative. The function name explains intent, and assignment is a single line.


uint32_t now = millis();

device_state = heartbeatActive(now,
                               HB_PERIOD_MS,
                               HB_ON_MS);

digitalWrite(LED_PIN, device_state);

This replaces the usual pattern of counters, comparisons, and manual resets. There’s no state to maintain, no rollover logic to reason about, and no blocking delays. You can reuse the same helper for multiple GPIOs just by passing different parameters.


digitalWrite(LED_STATUS,
    heartbeatActive(now, 1000, 50));

digitalWrite(LED_ERROR,
    heartbeatActive(now, 250, 25));

digitalWrite(LED_ACTIVITY,
    heartbeatActive(now, 2000, 200));

What I like about this approach:

  • no counters to overflow or go negative
  • no hidden state — behavior is a pure function of time
  • easy to reason about and reuse
  • scales cleanly when multiple timers are needed

This feels closer to how I want to think about timing logic: define the period, define the active window, and let the math do the rest.

No comments: