Extra 5% OFF Use Code: OL05
Free Shipping over ₹999

Timing and Delays

In Arduino, managing timing is essential for controlling the flow of a program and coordinating tasks. There are two common ways to handle timing:

  1. delay(): Pauses the program for a specified amount of time, which can be useful but blocks other code from running.
  2. millis(): A non-blocking alternative that allows other code to run while keeping track of elapsed time.

1. delay(): Basic Timing with Blocking

The delay() function pauses the entire program for a set amount of milliseconds (1 second = 1000 milliseconds). This can be helpful for simple timing tasks but is limiting if you want multiple things to happen simultaneously.

Example 1: Blinking an LED with delay()

In this example, an LED blinks every second using delay().

const int ledPin = 13; // Built-in LED on pin 13

void setup() {
  pinMode(ledPin, OUTPUT); // Set LED pin as an output
}

void loop() {
  digitalWrite(ledPin, HIGH); // Turn the LED on
  delay(1000); // Wait for 1 second (1000 ms)
  
  digitalWrite(ledPin, LOW); // Turn the LED off
  delay(1000); // Wait for 1 second
}

Explanation

  • digitalWrite(ledPin, HIGH); turns the LED on.
  • delay(1000); waits for 1 second.
  • digitalWrite(ledPin, LOW); turns the LED off, followed by another delay(1000); to keep it off for 1 second.

Limitations: During the delay() period, the Arduino is unresponsive and cannot perform other tasks.

2. Non-blocking Timing with millis()

The millis() function provides a way to keep track of elapsed time without stopping the program. It returns the number of milliseconds since the Arduino started running the program. This allows us to track time intervals and control timing without blocking other code from running.

Example 2: Blinking an LED with millis() (Non-blocking)

This example accomplishes the same task (blinking an LED) but uses millis() instead, allowing other code to run in parallel.

const int ledPin = 13;        // Built-in LED on pin 13
unsigned long previousMillis = 0; // Stores the last time the LED was updated
const long interval = 1000;       // Interval at which to blink (1000 ms)

void setup() {
  pinMode(ledPin, OUTPUT); // Set LED pin as an output
}

void loop() {
  unsigned long currentMillis = millis(); // Get the current time

  // Check if the interval has passed
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis; // Save the last time the LED was updated

    // Toggle the LED state
    int ledState = digitalRead(ledPin); // Read the current state of the LED
    digitalWrite(ledPin, !ledState);    // Set it to the opposite state
  }
  
  // Other code can run here without being affected by the LED timing
}

Explanation

  • unsigned long currentMillis = millis();: Reads the current time in milliseconds.
  • if (currentMillis - previousMillis >= interval): Checks if the specified interval (1 second) has passed since the last time the LED changed state.
  • previousMillis = currentMillis;: Updates previousMillis to the current time.
  • digitalWrite(ledPin, !ledState);: Toggles the LED’s state, switching it from on to off or vice versa.

This approach allows other tasks to execute in the loop() function without being paused by delay().

Combining millis() with Multiple Timers

Using millis() also allows you to run multiple timers simultaneously. Here’s an example where two LEDs blink at different intervals without interfering with each other.

Example 3: Two LEDs with Different Intervals

const int ledPin1 = 12;          // LED on pin 12
const int ledPin2 = 13;          // LED on pin 13
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
const long interval1 = 500;      // Blink interval for LED 1 (500 ms)
const long interval2 = 1000;     // Blink interval for LED 2 (1000 ms)

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

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

  // Timer for LED 1
  if (currentMillis - previousMillis1 >= interval1) {
    previousMillis1 = currentMillis;
    digitalWrite(ledPin1, !digitalRead(ledPin1)); // Toggle LED 1
  }

  // Timer for LED 2
  if (currentMillis - previousMillis2 >= interval2) {
    previousMillis2 = currentMillis;
    digitalWrite(ledPin2, !digitalRead(ledPin2)); // Toggle LED 2
  }
}

Explanation

Each LED has its own previousMillis and interval, allowing them to blink independently. This lets multiple events be timed without any blocking.

Key Takeaways

  • delay() is useful for simple timing but stops other code from running.
  • millis() offers a non-blocking approach to timing, ideal for running multiple tasks simultaneously.

Using millis() enables more responsive and versatile projects, particularly useful when you need multiple actions to happen at different intervals.

    Leave a Reply

    Your email address will not be published.

    Need Help?