There’s actually a library that makes that easy - called Metro (for metronome I suppose, not the game or as a reference to the area around a city). That easily lets you run multiple things each with their own intervals. I use it in my turnout controller so it can monitor the local buttons, the remote inputs, and move the servos all at the same time.
The repository for it will tell you that it’s old and point you to a replacement, which has more parameters (which for most of these purposes just makes it more complicated) so I’ve stuck with the Metro library.
Once the library is installed, in addition to your pin definitions and other setup, you declare a Metro object with the desired delay (this comes BEFORE the Setup() function):
Metro hbMetro(750)
That creates a Metro object called hbMetro with a trigger time of 750ms
In your main Loop(), you just encapsulate everything in an If conditional:
if (hbMetro.check() == 1) {
(stuff you want to happen every 750ms)
}
For example, in my servo controller, I use this to blink a heartbeat LED so I know the program is running. The full code is:
if (hbMetro.check() == 1) { // Heartbeat LED
if (hbstate == HIGH) hbstate = LOW;
else hbstate = HIGH;
digitalWrite(HBLED, hbstate);
}
Every 750ms, it simply turns the LED on if it was off, or turns it off if it was on.
The obvious (or maybe not so obvious) thing is that the code inside the if block cannot take longer than the time interval to actually execute or the timing will be messed up. Arduino and ATMega328 micros do not do preemptive multitasking like say Windows does - if one block takes a long time to execute, any following blocks with different intervals will not happen on time.
Note there is no delay() used - that’s because what’s inside the if only r