Home ArduinoArduino Tutorials Tutorial: Arduino Time Functions

Tutorial: Arduino Time Functions

by shedboy71

In Arduino, time-related functions allow you to manage delays, measure intervals, and execute actions based on timing. These functions are critical for applications like blinking LEDs, managing sensor data, or creating clocks.

This tutorial introduces the built-in time functions in Arduino, explains how to use them, and provides practical examples.

Table of Contents

1. What Are Time Functions in Arduino?

Time functions in Arduino allow you to:

  • Create delays.
  • Measure elapsed time.
  • Perform tasks at specific intervals.

2. Built-in Time Functions

2.1 millis()

  • Returns the number of milliseconds since the Arduino board started running the current program.
  • Rolls over to 0 after approximately 50 days.

Example: Print Milliseconds

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(millis());  // Print the elapsed time in milliseconds
  delay(1000);               // Wait for 1 second
}

2.2 micros()

  • Returns the number of microseconds since the program started.
  • Rolls over to 0 after approximately 70 minutes.

Example: Print Microseconds

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(micros());  // Print the elapsed time in microseconds
  delay(1000);               // Wait for 1 second
}

2.3 delay()

  • Pauses the program for a specified number of milliseconds.
  • Blocks further code execution during the delay.

Example: Blink an LED Using delay()

const int ledPin = 13;

void setup() {
  pinMode(ledPin, OUTPUT);
}

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

2.4 delayMicroseconds()

  • Pauses the program for a specified number of microseconds.
  • Useful for high-speed operations.

Example: Generate a Square Wave

const int ledPin = 13;

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  digitalWrite(ledPin, HIGH);
  delayMicroseconds(500);  // Wait for 500 microseconds
  digitalWrite(ledPin, LOW);
  delayMicroseconds(500);  // Wait for 500 microseconds
}

3. Using millis() for Non-Blocking Timing

millis() is commonly used for non-blocking timing. Unlike delay(), it allows other parts of the program to run during the interval.

Example: Non-Blocking LED Blink

const int ledPin = 13;
unsigned long previousMillis = 0;
const long interval = 1000;  // 1 second

void setup() {
  pinMode(ledPin, OUTPUT);
}

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

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;       // Save the last time the LED was toggled
    digitalWrite(ledPin, !digitalRead(ledPin));  // Toggle LED
  }
}

4. Practical Examples

4.1 Blinking an LED at Different Intervals

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

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

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

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));
  }
}

4.2 Measuring Time Intervals

unsigned long startTime;

void setup() {
  Serial.begin(9600);
  startTime = millis();  // Record the start time
}

void loop() {
  unsigned long elapsedTime = millis() - startTime;  // Calculate elapsed time
  Serial.print("Elapsed Time: ");
  Serial.print(elapsedTime);
  Serial.println(" ms");

  delay(1000);  // Update every second
}

4.3 Simple Stopwatch

const int startStopButton = 2;
const int resetButton = 3;

unsigned long startTime = 0;
unsigned long elapsedTime = 0;
bool running = false;

void setup() {
  pinMode(startStopButton, INPUT_PULLUP);
  pinMode(resetButton, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  if (digitalRead(startStopButton) == LOW) {
    delay(200);  // Debounce
    if (!running) {
      startTime = millis() - elapsedTime;  // Start or resume stopwatch
      running = true;
    } else {
      elapsedTime = millis() - startTime;  // Pause stopwatch
      running = false;
    }
  }

  if (digitalRead(resetButton) == LOW) {
    delay(200);  // Debounce
    elapsedTime = 0;
    running = false;
  }

  unsigned long displayTime = running ? millis() - startTime : elapsedTime;
  Serial.print("Elapsed Time: ");
  Serial.print(displayTime);
  Serial.println(" ms");

  delay(100);  // Refresh display
}

5. Best Practices for Using Time Functions

  1. Use millis() for Non-Blocking Code:
    • Avoid delay() in critical applications where other tasks need to run simultaneously.
  2. Handle millis() Rollover:
    • millis() resets to 0 after ~50 days, but using subtraction (currentMillis – previousMillis) ensures rollover doesn’t cause issues.
  3. Optimize Microsecond Delays:
    • Use delayMicroseconds() for short delays; avoid delay() for intervals under 1ms.
  4. Avoid Long Blocking Delays:
    • Long delay() calls can make the program unresponsive. Use millis() for better control.
  5. Synchronize Timing for Multiple Tasks:
    • Maintain separate timing variables for different tasks.

Conclusion

Time functions in Arduino are essential for creating responsive and efficient applications. Whether you’re blinking LEDs, measuring time intervals, or designing non-blocking programs, understanding how to use millis(), micros(), and delay() effectively will help you build robust projects.

For more details, visit the official Arduino reference.

You may also like