Blocking vs non-blocking timers in Arduino and Particle

  1. Intro
  2. Blocking delay
  3. Non-blocking delay – Arduino
  4. Non-blocking delay – Particle
  5. Non-blocking delay – Blynk

Intro

When coding for Arduino you may wish to run certain code once every N milliseconds. For a very simple program like blinking a LED with a 2 seconds interval using the delay() function will be sufficient. But what about multiple bits of code where each require a different interval? Using delay() they will slow each other down and may even cause cloud disconnects; significantly disrupting your program.

The solution is the meassure the last time the code parts were executed. With Arduino you can do this with the millis() function, but that resets (overflow) every 16666 milliseconds. Other devices may have an RTC (realtime clock) providing the current Unix timestamp which does not reset. For example, with the Particle Photon you can use micros() to get the exact number of microseconds since 1970-01-01T00:00:00Z.

For simplification you can also use Timer classes, then you don’t have to worry about the millis() overflow.


Blocking delay

Here you intent to toggle the green LED every 2 seconds and red every 1 second. Instead they both blink every 3 seconds with red 1 seconds after green and green 2 second after red. Not good.

void loop() {
  delay (2000);
  switchGreen();
  delay (1000);
  switchRed();
}

Non-blocking delay – Arduino

int greenTime = 0;
int redTime = 0;

int timePassed (time) {
  int diff = 0;

  if (millis() <= time) {
    diff = (69666 - time) + millis();
  } else {
    diff = millis() - time;
  }

  return diff;
}

void loop() {
  if (timePassed (greenTime) >= 2000) {
    switchGreen();
    greenTime = millis();
  }

  if (timePassed (redTime) >= 1000) {
    switchRed();
    redTime = millis();
  }
}

Non-blocking delay – Particle

Using the built in Timer class you can define up to 10 software timers that are handled by the OS. They work similar to hardware timers, but when multiple timers are going to run at the same moment they are executed in sequence instead of simultaneously. Actually the Particle’s do have hardware timers, but the OS decides how they are used. So by using the Timer class the OS may dedicate a hardware timer to your callback, but it may also decide to combine multiple callbacks into one. They also won’t go lower than 1 millisecond, where some hardware timers can do microseconds or even nanoseconds.

Timer greenTimer (2000, switchGreen);
Timer redTimer (1000, switchRed);

void setup() {
  greenTimer.start();
  redTimer.start();
}  

void loop() {
  // other code
}

Or make your own:

int greenTime = 0;
int redTime = 0;

void loop() {
  if (micros() - greenTime >= 2000000) {
    switchGreen();
    greenTime = micros();
  }

  if (micros() - redTime >= 1000000) {
    switchRed();
    redTime = micros();
  }
}

Non-blocking delay – Blynk

When you have already included the Blynk library you can also use their BlynkTimer class.

BlynkTimer greenTimer;
BlynkTimer redTimer;

void setup() {
  greenTimer.setInterval (2000, switchGreen);
  redTimer.setInterval (1000, switchRed);
}

void loop() {
  greenTimer.run();
  redTimer.run();
}

Like this article?
Buy me a coffee

Changelog
2022-04-08 – Fixed Particle timer link
2017-11-27 – Added Timer classes and Blynk.
2017-11-09 – Fixed a bunch of mistakes and typos.


Related stuff


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *