Interrupts and timers in Arduino

Interrupts and timers are important features of Arduino that allow you to perform tasks at precise intervals, respond to external events, and execute code asynchronously. Here’s an overview of how to use interrupts and timers in Arduino:

1. Interrupts: An interrupt is a signal that interrupts the normal flow of execution of a program, allowing you to respond to external events and perform time-critical tasks. Arduino supports two types of interrupts: external interrupts, which are triggered by external events such as a button press or a sensor input, and timer interrupts, which are triggered by the internal hardware timers of the Arduino board.

To use interrupts in Arduino, you need to define an interrupt service routine (ISR) that is executed when the interrupt is triggered. The ISR should be a short and fast code that performs the necessary actions, and should avoid using delay() or other blocking functions that can disrupt the normal operation of the program.

Here’s an example code that uses an external interrupt to toggle an LED when a button is pressed:

const int buttonPin = 2; // Button pin
const int ledPin = 13; // LED pin

void setup() {
  Serial.begin(9600); // Initialize the serial communication
  pinMode(buttonPin, INPUT_PULLUP); // Set the button pin as input with pull-up resistor
  pinMode(ledPin, OUTPUT); // Set the LED pin as output
  attachInterrupt(digitalPinToInterrupt(buttonPin), toggleLED, FALLING); // Attach the interrupt to the button pin
}

void loop() {
  // Do nothing
}

void toggleLED() {
  digitalWrite(ledPin, !digitalRead(ledPin)); // Toggle the LED state
}

2. Timers: A timer is a hardware component that allows you to perform time-critical tasks at precise intervals, such as generating a PWM signal, measuring the time between events, or executing code periodically. Arduino boards typically have one or more timers that can be configured and used for different tasks.

To use timers in Arduino, you need to configure the timer registers to set the timer mode, frequency, and other parameters. You can then define an interrupt service routine (ISR) that is executed when the timer interrupt is triggered, and perform the necessary actions in the ISR.

Here’s an example code that uses a timer interrupt to blink an LED every second:

const int ledPin = 13; // LED pin
volatile bool ledState = LOW; // LED state variable

void setup() {
  Serial.begin(9600); // Initialize the serial communication
  pinMode(ledPin, OUTPUT); // Set the LED pin as output
  TCCR1A = 0; // Clear the timer control registers
  TCCR1B = 0;
  TCNT1 = 0; // Clear the timer counter
  OCR1A = 15624; // Set the compare match value for a 1-second interval
  TCCR1B |= (1 << WGM12); // Set the timer mode to CTC
  TCCR1B |= (1 << CS12) | (1 << CS10); // Set the prescaler to 1024
  TIMSK1 |= (1 << OCIE1A); // Enable the timer interrupt
}

void loop() {
  // Do nothing
}

ISR(TIMER1_COMPA_vect) {
  ledState = !ledState; // Toggle the LED state
  digitalWrite(ledPin, ledState); // Set the LED state
}

Overall, interrupts and timers are important features of Arduino that can be used to perform time-critical tasks and respond to external events. By understanding how interrupts and timers work, and following the guidelines for defining ISRs and configuring timer registers, you can customize and optimize your Arduino code to meet the specific needs of your project.