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

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:

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.cc 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();
}

Changelog
2017-11-27 – Added Timer classes and Blynk.

2017-11-09 – Fixed a bunch of mistakes and typos.