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
- Arduino Uno (or a compatible board)
- LED and 220-ohm resistor (for timing-based examples)
- Breadboard and jumper wires
- 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()
andmillis()
.
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
- Install the TimerOne library in the Arduino IDE.
- 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
- Generating precise PWM signals for motor control
- Scheduling tasks without blocking code (e.g., multitasking)
- Measuring time intervals for events
- Creating precise delays without using
delay()
- 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!