The every
construct lets you run a piace of code at regular intervals in a fluent way. If you don't need to start, stop, pause your timer, this construct is a valid alternative to more complex timer libraries already available: it only takes a time interval as argument and will execute the code block periodically.
Definition
#define every(interval) \
static uint32_t __every__##interval = millis(); \
if (millis() - __every__##interval >= interval && (__every__##interval = millis()))
How to use
// these are for greater code readability
#define Millis
#define Second *1000
#define Seconds *1000
int interval = 1 Second;
void setup() {
Serial.begin(115200);
}
void loop() {
every(1000 Millis) {
Serial.println("This line is printed every 1 second");
}
every(2000 Millis) {
Serial.println("This line is printed every 2 seconds");
}
every(interval) {
interval += 1 Second;
Serial.print("You can have variable intervals too! ");
Serial.print("This line will be printed again in ");
Serial.print(interval / 1000);
Serial.println(" seconds");
}
}
Caveats
every
is just a macro definition and is not a proper timer, so it has some limitations:
- you can't stop, pause or resume it: once set, it will run forever
- its argument must be the suffix of a valid identifier
- you can't use several
every
with the exact same argument: you have to put all the code that needs to happen at the same interval in the same block
Caveat #2
The macro works by generating a variable named like __every__##argument
every(1) ==> uint32_t __every__1;
every(2) ==> uint32_t __every__2;
every(a_given_interval) ==> uint32_t __every__a_given_interval;
every(an invalid interval) ==> uint32_t __every__an invalid interval; // Syntax error
every(1 Second) ==> uint32_t __every__1 *1000; // Syntax error
So every integer literal and any variable are all valid arguments. Any expression is forbidden.
Caveat #3
If you use two every
with the exact same argument, two variables with the exact same name will be created and it will rise a compile-time error.
If you can live with this limitations, every
only needs the space of an uint32_t
to work.