/*
Author: Juan M. Gandarias
Date: 03/11/2023
Description: ejemplo_timer_builder-2
*/
#define LED_PIN 26 // LED conectado a GPIO26
#define BUTTON_PIN 27 // Botón conectado a GPIO27
#define POT_PIN 4 // Potenciómetro conectado a GPIO04
long int t; // Variable para contar tiempo
bool button_state = false; // Variable para guardar el estado del botón
const uint8_t numberOfBlinks = 10; // Constante de número de blinks. Tener en cuenta que un blink es apagado y encendido. 10 blinks significa que el LED parpadea 5 veces
hw_timer_t *timer = NULL; // Puntero al timer del hardware.
// Lo he llamado "timer" por simplificar, pero podría haberlo llamado como quisiera. P.ej.:
// hw_timer_t *temporizador_0 = NULL;
volatile uint8_t interrupt_counter = 0; // Variable volátil para contar cuántas veces se produce la interrupción
volatile bool timer_activated = false; // Variable volátil que determina que se ha activado el timer
// Callback ISR botón presionado
void IRAM_ATTR buttonPressed()
{
digitalWrite(LED_PIN, LOW); // Se apaga el LED
interrupt_counter = 0; // Se resetea el contador de timer
timerAlarmEnable(timer); // Habilitar timer
}
// Callback ISR interrupción del timer
void IRAM_ATTR timerInterrupt()
{
interrupt_counter++; // Se incrementa el contador de interrupciones del timer
timer_activated = true; // Se indica que ha habido una interrupción del timer
}
// Función setup
void setup()
{
Serial.begin(115200); // Inicialización puerto serie
pinMode(LED_PIN, OUTPUT); // Configurar LED como output
pinMode(BUTTON_PIN, INPUT_PULLUP); // Configurar botón como input
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonPressed, RISING); // Configurar la interrupción de pulsación del botón
// Inicializar el timer
// Parámetro 1: Timer que queremos usar. El ESP32 tiene 4 timers => valores válidos 0,1,2,3
// Parámetro 2: Prescaler. El reloj por defecto del ESP32 va a 80MHz. Si ponemos 80, dividimos el reloj por 80, dándonos 1 000 000 ticks/s
// Parámetro 3: true indica que el timer empieza en ON, false sería OFF
timer = timerBegin(0, 80, true); // Timer 0, divisor de reloj 80
timerAttachInterrupt(timer, &timerInterrupt, true); // Adjuntar la función de manejo de interrupción
timerAlarmWrite(timer, 5e5, true); // Interrupción cada medio segundo (500ms ON, 500ms OFF)
}
// Función loop
void loop()
{
if (timer_activated) // Si ha habido una interrupción del timer
{
if (interrupt_counter < numberOfBlinks) // Si el contador del número de interrupciones del timer es menor que el número de blinks
{
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Alternar el estado del LED
}
else if (interrupt_counter == numberOfBlinks) // Si se ha producido la última interrupción del timer
{
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Alternar el estado del LED
interrupt_counter = 0; // Poner a 0 el contador de interrupciones del timer
timerAlarmDisable(timer); // Deshabilitar el timer
}
timer_activated = false; // Se indica que la tarea debido a una interrupción del timer ya se ha realizado
}
// Mandar datos por puerto serie (frecuencia y valor del potenciómetro)
Serial.println("freq: ");
Serial.println(1 / double((millis() - t) / 1e3));
Serial.println("Sensor pot_value: ");
Serial.println(analogRead(POT_PIN));
t = millis();
// Loop cada 50ms => 20Hz
delay(50);
}