Arduino Timer Tutorial

Arduino Timer Tutorial

Timers are an essential feature of microcontrollers, allowing you to perform tasks at precise intervals without relying on delays. The Arduino Uno has three built-in hardware timers (Timer0, Timer1, and Timer2) that can be configured for various functions like generating PWM signals, timing events, or scheduling tasks. This tutorial will guide you through understanding and using Arduino timers.


What You Will Need

  1. Arduino Uno (or a compatible board)
  2. LED and 220-ohm resistor (for timing-based examples)
  3. Breadboard and jumper wires
  4. Arduino IDE installed on your computer

Step 1: Understanding Arduino Timers

The Arduino Uno’s ATmega328P microcontroller has three hardware timers:

Timer Bit Resolution Primary Usage
Timer0 8-bit Millis(), micros(), PWM on pins 5, 6
Timer1 16-bit Servo library, PWM on pins 9, 10
Timer2 8-bit Tone() function, PWM on pins 3, 11

Key Features of Timers

  • Timers can generate PWM signals.
  • Timers can trigger interrupts.
  • Timers are used internally by Arduino functions like delay() and millis().

Step 2: Generating a Simple PWM Signal

PWM (Pulse Width Modulation) signals are commonly used to control LED brightness or motor speed. Let’s use Timer0 to create a PWM signal.

Example Code: LED Brightness Control with PWM

#define ledPin 6 // Pin 6 uses Timer0 for PWM

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

void loop() {
  for (int brightness = 0; brightness <= 255; brightness++) {
    analogWrite(ledPin, brightness); // Increase brightness
    delay(10);
  }

  for (int brightness = 255; brightness >= 0; brightness--) {
    analogWrite(ledPin, brightness); // Decrease brightness
    delay(10);
  }
}

Step 3: Using Timers with Interrupts

You can configure timers to trigger interrupts at regular intervals. For example, Timer1 can be set up to toggle an LED every second.

Example Code: Timer1 Interrupt

#define ledPin 13 // Built-in LED

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

  // Configure Timer1
  noInterrupts(); // Disable interrupts during setup
  TCCR1A = 0;     // Clear Timer1 control registers
  TCCR1B = 0;
  TCNT1 = 0;      // Initialize counter value to 0

  OCR1A = 15624;  // Compare match register (1Hz at 16MHz with 1024 prescaler)
  TCCR1B |= (1 << WGM12); // CTC mode
  TCCR1B |= (1 << CS12) | (1 << CS10); // 1024 prescaler
  TIMSK1 |= (1 << OCIE1A); // Enable Timer1 compare interrupt

  interrupts(); // Enable interrupts
}

ISR(TIMER1_COMPA_vect) {
  digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle LED
}

void loop() {
  // Main loop does nothing; timer handles the LED
}

Step 4: Measuring Time with Timers

You can use timers to measure precise durations. Timer2 is suitable for small intervals because it is an 8-bit timer.

Example Code: Timer2 for Time Measurement

volatile unsigned long overflowCount = 0;

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

  // Configure Timer2
  noInterrupts();
  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2 = 0;

  TCCR2B |= (1 << CS22); // Prescaler 64
  TIMSK2 |= (1 << TOIE2); // Enable Timer2 overflow interrupt

  interrupts();
}

ISR(TIMER2_OVF_vect) {
  overflowCount++;
}

void loop() {
  unsigned long timeElapsed = overflowCount * 16.384; // Each overflow = 16.384ms
  Serial.print("Time elapsed: ");
  Serial.print(timeElapsed);
  Serial.println(" ms");
  delay(1000);
}

Step 5: Using Timer Libraries

To simplify working with timers, you can use libraries like TimerOne or TimerThree.

Using the TimerOne Library

  1. Install the TimerOne library in the Arduino IDE.
  2. Use it to schedule tasks easily:
#include <TimerOne.h>
#define ledPin 13

void toggleLED() {
  digitalWrite(ledPin, !digitalRead(ledPin));
}

void setup() {
  pinMode(ledPin, OUTPUT);
  Timer1.initialize(1000000); // Set timer to 1 second (1,000,000 microseconds)
  Timer1.attachInterrupt(toggleLED); // Attach the interrupt function
}

void loop() {
  // Main loop does nothing; Timer1 handles the LED
}

Applications of Timers

  1. Generating precise PWM signals for motor control
  2. Scheduling tasks without blocking code (e.g., multitasking)
  3. Measuring time intervals for events
  4. Creating precise delays without using delay()
  5. Managing periodic actions like blinking LEDs or sending data

Troubleshooting

  • Timer conflicts: Ensure you don’t use the same timer for multiple functions (e.g., Servo library and PWM).
  • Interrupts not working: Check that interrupts are enabled with interrupts().
  • Unexpected behavior: Double-check prescaler and compare match values for correct timing.

Conclusion

You’ve learned how to use Arduino timers for generating PWM signals, handling interrupts, and measuring time. Mastering timers unlocks powerful features for creating efficient and precise Arduino projects. Experiment with different configurations and apply timers to optimize your next project!

Leave a comment

Notice an Issue? Have a Suggestion?
If you encounter a problem or have an idea for a new feature, let us know! Report a problem or request a feature here.