Ticker: call a function every few milliseconds without delay()
Stefan Staub’s Ticker library is a tidy wrapper around the millis() pattern: you create a Ticker with a function and an interval, start it, and call its update() from loop(); each time the interval has passed, update() calls the function. Several Tickers can run side by side at different rates, which is the usual way out of a sketch full of delay() calls.
Built in on Mokxi: #include <Ticker.h> and it builds, with nothing to install. Free, and no account needed.
What Ticker does
A Ticker can run for ever or a set number of times: Ticker timer2(printCounter, 1000, 5) calls printCounter five times and then stops itself. The resolution is chosen with the last argument, MILLIS or MICROS, and the callbacks run from your loop(), not from an interrupt, so they may use Serial and take their time.
On the ESP32 and ESP8266 the core ships a different library also named Ticker, and the Arduino IDE picks the core’s. Its API is attach(seconds, function) and once(), and it runs the callbacks from a timer task with no update() needed. A sketch written for one does not compile with the other, so check which kind a tutorial uses.
| Library Manager name | Ticker |
|---|---|
| Author | Stefan Staub |
| Include | #include <Ticker.h> |
| Boards | every board Mokxi compiles for |
| In the simulator | Simulated: it runs against the part the way it does on the bench. |
Install it
It builds on every board Mokxi compiles for.
In Mokxi it is built in: #include <Ticker.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "Ticker" by Stefan Staub from the Arduino IDE’s Library Manager (Sketch, Include Library, Manage Libraries), or add Ticker to lib_deps in PlatformIO. Mokxi follows the calls of release 4.4.0, so a sketch written here builds there too.
What to know in the simulator: The ESP cores’ Ticker runs its calls on time while the sketch is in delay(), as their timer task does.
ESP32-C3 · Arduino Uno · Arduino Nano · Arduino Mega 2560 · Arduino Leonardo · SparkFun Pro Micro · Arduino Micro · ESP32-C6 · ATtiny85 · Raspberry Pi Pico · Raspberry Pi Pico W · Seeed XIAO SAMD21 · STM32 · STM32 Nucleo-F411RE · STM32 Blue Pill · micro:bit V2 · Arduino Uno R4 · ESP32 DevKit · ESP32-S3-DevKitC-1 · ESP8266 NodeMCU · Arduino Pro Mini 3.3 V · Seeed XIAO ESP32-C3 · ESP32-C3 SuperMini · Seeed XIAO ESP32-C6 · ESP32-DevKitC V4 · LOLIN32 Lite · Wemos D1 R32 · Cheap Yellow Display · TTGO T-Display · Seeed XIAO ESP32-S3 · Arduino Nano ESP32 · Arduino Nano RP2040 Connect · Seeed XIAO RP2040 · Waveshare RP2040-Zero · Arduino Uno R4 WiFi
The calls you will use
In the order a sketch meets them.
Ticker timer1(blink, 500)
A Ticker that calls blink() every 500 ms, for ever. A third argument sets how many times, 0 meaning for ever.
timer1.start()
Starts counting from now. Nothing runs until start() is called.
timer1.update()
Checks the time and calls the function when the interval has passed. Call it for every Ticker on every pass of loop().
void loop() {
timer1.update();
timer2.update();
}timer1.pause()
Stops the timer and keeps the time already counted; resume() carries on from there. stop() resets it.
timer2.counter()
How many times the callback has run since the last start().
blinker.attach(0.5, blink)
ESP32 and ESP8266 core Ticker only: calls blink() every half second from the core’s timer, no update() needed. attach_ms() takes milliseconds.
blinker.once(2, stopMotor)
ESP core Ticker only: calls the function once, two seconds from now. detach() cancels an attached Ticker.
Example: Two tickers: a fast one and a countdown
On the Arduino Uno R3. It runs in the browser exactly as printed.
#include "Ticker.h"
int blinks = 0;
void blink() { blinks++; }
int left = 5;
void countdown() {
Serial.print("countdown ");
Serial.println(left--);
}
Ticker blinker(blink, 100, 0, MILLIS); // every 100 ms, for ever
Ticker counter(countdown, 200, 5, MILLIS); // five times, then it stops
void setup() {
Serial.begin(9600);
blinker.start();
counter.start();
}
void loop() {
blinker.update();
counter.update();
if (counter.state() == STOPPED && left == 0) {
Serial.print("done after ");
Serial.print(blinks);
Serial.println(" blinks");
left = -1;
}
}Common errors and how to fix them
The callback never runs
Either start() was never called, or update() is missing from loop(), or a long delay() elsewhere in loop() keeps update() from running on time. Call start() in setup() and update() on every pass.
no matching function for call to 'Ticker::Ticker(void (&)(), int)' on an ESP32
On ESP boards the core’s own Ticker is used, which has an empty constructor and attach(). Rewrite as Ticker t; t.attach_ms(500, blink);, or rename the library’s header if you need Stefan Staub’s on that board.
'class Ticker' has no member named 'attach' on an Uno
attach() and once() belong to the ESP cores’ Ticker. On AVR and other boards use this library’s form: Ticker t(blink, 500); t.start(); and t.update() in loop().
Try Ticker without installing anything
Open the example, change the sketch, and keep your version in a free account.