Software timers

Since 0.4.7:

Software Timers provide a way to have timed actions in your program. FreeRTOS provides the ability to have up to 10 Software Timers at a time with a minimum resolution of 1 millisecond. It is common to use millis() based "timers" though exact timing is not always possible (due to other program delays). Software timers are maintained by FreeRTOS and provide a more reliable method for running timed actions using callback functions. Please note that Software Timers are "chained" and will be serviced sequentially when several timers trigger simultaneously, thus requiring special consideration when writing callback functions.

// EXAMPLE
SerialLogHandler logHandler;

Timer timer(1000, print_every_second);

void print_every_second()
{
    static int count = 0;
    Log.info("count=%d", count++);
}

void setup()
{
    timer.start();
}

Timers may be started, stopped, reset within a user program or an ISR. They may also be "disposed", removing them from the (max. 10) active timer list.

The timer callback is similar to an interrupt - it shouldn't block. However, it is less restrictive than an interrupt. If the code does block, the system will not crash - the only consequence is that other software timers that should have triggered will be delayed until the blocking timer callback function returns.

  • You should not use functions like Particle.publish from a timer callback.
  • Do not use Serial.print and its variations from a timer callback as writing to Serial is not thread safe. Use Log.info instead.
  • It is best to avoid using long delay() in a timer callback as it will delay other timers from running.
  • Avoid using functions that interact with the cellular modem like Cellular.RSSI() and Cellular.command().

Software timers run with a smaller stack (1024 bytes vs. 6144 bytes). This can limit the functions you use from the callback function.

// SYNTAX

Timer timer(period, callback, one_shot)

  • period is the period of the timer in milliseconds (unsigned int)
  • callback is the callback function which gets called when the timer expires.
  • one_shot (optional, since 0.4.9) when true, the timer is fired once and then stopped automatically. The default is false - a repeating timer.

Software timers are currently implemented as a thin layer over FreeRTOS timers. The semantics of how they work is not clearly defined by FreeRTOS. For example, changing the period also resets it to zero, however this is not documented. Furthermore, future versions of Device OS could use a different timing system. If you require very precise control of how your timers behave in various edge cases, it's best to implement your own thread and handle it yourself. This will also allow you to change the stack size.