Timer Interval Best Practice Question

Is there a best practice as to how I should be setting intervals for my timers? I feel like I should stagger them so they’re not interfering with each other - but is that necessary? In other words, is this:

timer.setInterval(1000L, sendSensor1);
timer.setInterval(1000L, sendSensor2);

going to cause problems? Whereas this:

timer.setInterval(1000L, sendSensor1);
timer.setInterval(1500L, sendSensor2);

would be ideal? Basically, should I be staggering my timer intervals?

The code is executed sequentially, so (normally) when it’s done with sendSensor1 it moves on to sendSensor2.

Awesome, thanks for the clarification.

Actually, I have found great benefits in staggering them (as needed), since while these are not multitasking systems, timers are based on interrupts… so multiple timers all set for 1000ms (1 second) WILL try to process their respective functions in a pseudo simultaneous method… and this can really mess up longer functions.

If you need something(s) to happen all at “the same time”, and as long as they are fast enough functions, then simply lump them all into a single timer control.

Otherwise, if you just need them to keep their own schedule, then stagger them so as to not “correspond” with each other to many times over a period. E.g. Timer1 @ 1000ms and Timer2 @1500ms WILL try to process at the same “time” once every 3000ms. so I usually just add or subtract 10 - 20ms here and there to minimise that happening.

timer.setInterval(1000L, sendSensor1);
timer.setInterval(1010L, sendSensor2);

Okay - that was my intuition. Thanks for clarifying, @Gunner. I’ll stagger my timers.

That’s why I wrote “(normally)” :wink: But can you elaborate this? I’m not implying you’re wrong, just want to learn - and perhaps change my timers.

It is mostly based on my experience in testing many functions, all running with their own independent purpose, on my Blynk testbench project. Arduino Mega with diYode Codeshield, and more… formerly running via USB and now connecting via ESP-01.

I used to have a bunch of timers all set to the same, or eventually corresponding, timeframe… was not stable!

This is my current void setup() Probably still not perfect as something still bogs down every once in awhile… hence the WDT

// ===== Timer Setup =====
  PingTimer = timer.setInterval(550L, PingSensor);  // Ping distance routine - switched
  timer.disable(PingTimer);  // Disable timer until needed

  PIRTimer = timer.setInterval(650L, PIRSensor);  // PIR motion routine - switched
  timer.disable(PIRTimer);  // Disable timer until needed

  timer.setInterval(500L, whiteLED);  // White LED button monitor on CodeShield
  //timer.setInterval(505L, readVcc);  // Voltmeter
  timer.setInterval(2000L, clockDisplay);  // Time and Date Widget
  timer.setInterval(1010L, SuperCapVoltage);  // Super Cap charge display
  timer.setInterval(2020L, AnalogSensors);  // Misc analog sensors on CodeShield
  timer.setInterval(30000L, DHTSensor);  // DHT22 sensor
  //HTBLEDTimer = timer.setInterval(5000L, HeartBeatLED);  // Heartbeat LED
  //timer.setTimeout(10000L, StartUpEmail);  // Send Start Up Email
  //timer.setInterval(11000L, reconnectBlynk); // check every 11 seconds if we are connected to the server
  timer.setInterval(30010L, thermTemp);  // Thermistor  on CodeShield
  //timer.setInterval(60015L, HeartBeatPrint);  // Heartbeat Print
  timer.setInterval(6000L, sendUptime);  // Up Time Widget
}  // END Setup Loop

I have added a simple LED routine to my void loop()

digitalWrite(HTB, !digitalRead(HTB));

When everything is running smoothly the LED tends to have a fairly consistent flicker… but when something is getting bogged down, it tends to stay ON or OFF for extended periods (1/2-2 seconds at times). and if that happens too often, then I fiddle around with the timer offsets and check results.

I have another quick question @Gunner @distans - I’m trying to make a physical LED stay lit while I’m connected to Blynk. It’s working - but it turns off for about a second or two every now and again - it doesn’t follow a strict pattern. Here’s the code:

void checkConnection() {
  if (! Blynk.connected()) {
    digitalWrite(connectionLED, LOW);
  else {
    digitalWrite(connectionLED, HIGH);

I have checkConnection running on a timer at 1520L intervals. Below are the rest of my timers in setup:

  timer.setInterval(1000L, readTemp);
  timer.setInterval(1520L, checkConnection);
  timer.setInterval(43200000L, readDate);
  timer.setInterval(86400000L, resetMinMax);

Any idea why I’m getting an intermittent LOW on my LED?

See my post just prior… that is the same idea I had… works quite well actually… and the longer pauses are simply something blocking/delaying the primary loop (in my case) or blocking/delaying your checkConnection() loop.

I set my LED in the main loop as follows… Combined with the WDT in the void setup() it is currently set to reset the Mega if disconnected from Blynk for 8 seconds.

void loop()
  if (Blynk.connected()) 
    digitalWrite(HTB, !digitalRead(HTB));
    wdt_reset();  // make sure this gets called at least once every 8 seconds!
}  // END Void loop

I’ll bet you’re using Adafruits library for the DHT22 with a built-in 250 ms delay :wink: Check my post:

I only have 6 timers in my sketch and the fastest interval is 1 second. But you have a lot going on at a fast rate so I can understand why it gets bogged down now and then. I haven’t experienced any problems but will add a LED and change the timers a bit.

Yes, I am :slight_smile: but I only call that sensor every 30 seconds (and get data from a bridged, outside one, every 5 min)… and only that fast as I am testing stuff and don’t want to wait 5-10 minutes to see if the display changes… 1/4 second per read isn’t that bad for a sensor that shouldn’t be read more than once every 2-5 seconds in the first place.

…primarily becasue it is my testbench setup. Mostly independent routines; testing code snippets for flashing, latching, sweeping, bridging, etc. Absolutely noting is critical… but it is where I determine if a code routine can survive here, it should work just fine in a separate project :smiley: Problem is I rarely remove the test afterwards… as it is also my goto for stored snippets since I can’t remember how to spel, let alone remember code syntax :stuck_out_tongue:

True, but I have always wondered why everyone want to read their temp sensors so frequently. It might be critical if you cook meth or something (guessing, don’t really know) but for normal in/outdoor temperature it seems excessive.

Still, 6 ms with Arduino’s recommended lib must be tempting to use instead :wink:

@Gunner do you have any definitive test that timer intervals really matter? I’m not convinced it makes any difference. With all the hardware you have hooked up I don’t think you would know one way or another if it’s timer related.

Perhaps just run 2 functions both set at 1000L to see if there is any clash.

I guess it can’t do any harm to use 1020L rather than 1000L though.

1 Like

Hey just want to let you know the best way to stagger the timers.

You want to have them all the same 1000ms (or whatever you want as long as they’re syncing somehow).
Then start each one staggered use setTimeout()

timer.setTimeout(100, [](){
  timer.setInterval(1000L, sendSensor1);
timer.setTimeout(200, [](){
  timer.setInterval(1000L, sendSensor2);

Now each one will run every second but not over the top of each other.


Definitive… no, mainly because I am just not feeling that methodical most of the time :stuck_out_tongue:

But the fact that I can have so much happening, and on a slow 16MHz Arduino, without total system uselessness is primarily becasue I started modifying how I set the timers. Before I started doing that I couldn’t activate certain functions like the PIR or Ultrasonic scanners (they are the first two timers in my post… and are set so as they can be enabled only when required) without commenting everything else out… But now I can run them and not have immediate issues.

No one in their right frame of coding sense would have a project that runs like my testbench… Everything works, but can get sketchy if I activate to much at once, and there is a little bit of jerkiness in some of the actions that would normally be smooth if running alone, (like the timer based slow motion servo sweep)… but then thats not the purpose of this project… testing and code retention is :wink:

Easy (I think)… but add in 14 more and you might have a different story :wink: Unless the functions are dirt simple and not time critical.

Not a bad idea… keeps the slow creep of the cumulative 10-20ms from adding up over time.

1 Like

Give it a go…

1 Like

The other possible issue that I have a hard time confirming or denying, is WiFi interference and network overload. Most of my testing at my workbench, at the back of the RV, while my server and router is at the front… and I am running many, many, much things 24/7/365

4 - ESPs
5 - WiFi IP cameras
1 - WiFi laptop, feeding another USB camera signal
1 - Phone
3 - Tablets
1 - RPi Zero W and NoIR camera - experimenting with motion activated pictures sent to dropbox - a very recent addition thanks to another sponsored project.

Plus 4 wired computers, 1 old wired RPi, 1 wired IP camera (and 4 more USB cameras streaming from some of the PC’s)

And 1 lowly 433MHz test sending a constant signal to flash an LED… very important data there I am sure :stuck_out_tongue:

And ever once in awhile I occasionally power up another phone or WiFi MCU (I have three C.H.I.P.s and that other sponsored RPi Zero W project).

I was testing my Local Server on a C.H.I.P. but becasue it is WiFi, I think that was causing additional issues with my Blynk stuff… so my Local Server is back on it’s wired netbook.

And finally my router is also pulling in 4 separate camera feeds from out of town, to add to my own… and perhaps the odd movie or so :skull_and_crossbones: Thank heavens for fast internet!

… I am amazed anything works at all… :boom:

But other then all that, yes… I have found some improvement with tweaking timers :wink:

1 Like