0
0
AutocadHow-ToBeginner · 3 min read

How to Run Multiple Tasks in Arduino Without Delay

To run multiple tasks in Arduino without using delay(), use the millis() function to track elapsed time and execute code only when needed. This approach lets your program do other things while waiting, avoiding pauses caused by delay().
📐

Syntax

The basic syntax to run tasks without delay uses millis() to check elapsed time. You store the last time a task ran and compare it to the current time. If enough time has passed, you run the task and update the last run time.

  • unsigned long currentMillis = millis(); gets the current time in milliseconds since the Arduino started.
  • if (currentMillis - previousMillis >= interval) checks if the set interval has passed.
  • previousMillis = currentMillis; updates the last run time.
arduino
unsigned long previousMillis = 0;
const long interval = 1000; // interval in milliseconds

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    // Run your task here
  }
}
💻

Example

This example blinks two LEDs at different intervals without using delay(). It shows how to run multiple tasks independently by checking elapsed time for each.

arduino
const int ledPin1 = 13;
const int ledPin2 = 12;

unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;

const long interval1 = 500;  // Blink LED1 every 500 ms
const long interval2 = 1000; // Blink LED2 every 1000 ms

void setup() {
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis1 >= interval1) {
    previousMillis1 = currentMillis;
    digitalWrite(ledPin1, !digitalRead(ledPin1));
  }

  if (currentMillis - previousMillis2 >= interval2) {
    previousMillis2 = currentMillis;
    digitalWrite(ledPin2, !digitalRead(ledPin2));
  }
}
Output
LED on pin 13 blinks every 0.5 seconds; LED on pin 12 blinks every 1 second.
⚠️

Common Pitfalls

Many beginners use delay() which stops all code and blocks other tasks. This causes the Arduino to be unresponsive during the delay.

Another mistake is not updating the previousMillis variable, which causes the task to run repeatedly without pause.

arduino
/* Wrong way: Using delay blocks all tasks */
void loop() {
  digitalWrite(13, HIGH);
  delay(1000); // Blocks here
  digitalWrite(13, LOW);
  delay(1000); // Blocks here
}

/* Right way: Using millis() for non-blocking timing */
unsigned long previousMillis = 0;
const long interval = 1000;

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    digitalWrite(13, !digitalRead(13));
  }
}
📊

Quick Reference

  • Use millis() to get current time without blocking.
  • Store last run time in a variable like previousMillis.
  • Check if enough time passed by comparing currentMillis - previousMillis to your interval.
  • Update previousMillis after running the task.
  • Repeat this pattern for each independent task.

Key Takeaways

Use millis() instead of delay() to avoid blocking your Arduino program.
Track elapsed time with previousMillis and currentMillis variables.
Update previousMillis each time a task runs to keep timing accurate.
Check each task's timing separately to run multiple tasks independently.
Avoid delay() to keep your Arduino responsive and multitasking smoothly.