/*
Author: Juan M. Gandarias
Date: 03/11/2023
Description: ejemplo_timer_builder-2
*/
#define LED_PIN 26 // LED connected to GPIO26
#define BUTTON_PIN 27 // Button connected to GPIO27
bool button_state = false; // Variable to store the button state
const uint8_t NUM_BLINKS = 10; // Number of blink events. Note: one blink = off + on. 10 blinks -> LED toggles 5 times
hw_timer_t *timer = NULL; // Pointer to the hardware timer.
// Named "timer" for simplicity; any valid identifier is fine, e.g.:
// hw_timer_t *temporizador_0 = NULL;
volatile uint8_t interrupt_counter = 0; // Volatile counter for how many times the interrupt has occurred
volatile bool timer_activated = false; // Volatile flag indicating the timer has fired
// ISR callback for button press
void IRAM_ATTR buttonPressed()
{
digitalWrite(LED_PIN, LOW); // Turn off the LED
interrupt_counter = 0; // Reset the timer interrupt counter
timerAlarmEnable(timer); // Enable the timer alarm
}
// ISR callback for timer interrupt
void IRAM_ATTR timerInterrupt()
{
interrupt_counter++; // Increment the timer interrupt counter
timer_activated = true; // Indicate a timer interrupt occurred
}
// setup function
void setup()
{
Serial.begin(115200); // Initialize serial port
pinMode(LED_PIN, OUTPUT); // Configure LED as output
pinMode(BUTTON_PIN, INPUT_PULLUP); // Configure button as input with internal pull-up
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonPressed, RISING); // Configure button press interrupt
// Initialize the timer
// Parameter 1: Timer index to use. ESP32 has 4 timers => valid values 0,1,2,3
// Parameter 2: Prescaler. The ESP32 default clock runs at 80 MHz. If we set 80, we divide the clock by 80, giving 1,000,000 ticks/s (1 tick = 1 µs)
// Parameter 3: true indicates the timer counts up, false would count down
timer = timerBegin(0, 80, true); // Timer 0, clock divider 80
timerAttachInterrupt(timer, &timerInterrupt, true); // Attach the interrupt handler
timerAlarmWrite(timer, 5e5, true); // Alarm every 500 ms (500000 µs), auto-reload
}
// loop function
void loop()
{
if (timer_activated) // If a timer interrupt occurred
{
if (interrupt_counter < NUM_BLINKS) // If interrupt count is less than NUM_BLINKS
{
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle the LED state
}
else if (interrupt_counter == NUM_BLINKS) // If the final scheduled interrupt occurred
{
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle the LED state
interrupt_counter = 0; // Reset the interrupt counter
timerAlarmDisable(timer); // Disable the timer alarm
}
timer_activated = false; // Clear the flag indicating the timer-related task has been handled
}
// Loop every 10ms => 100Hz
delay(10);
}