/*
Author: Juan M. Gandarias
Date: 08/11/2024
Description: ejemplo_timer_builder-3
*/
// GPIO
#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 *temporizador = NULL; // Puntero al timer del hardware.
// Lo he llamado "temporizador" por simplificar, pero podría haberlo llamado como quisiera. P.ej.: hw_timer_t *my_timer_0 = NULL;
int timer_frequency = 1000000; // Frecuencia del timer en Hz (como de rápido cuenta el timer)
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
timerStart(temporizador); // 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
temporizador = timerBegin(timer_frequency); // Inicializar el timer que contará a la frecuencia timer_frequency
timerAttachInterrupt(temporizador, &timerInterrupt); // Adjuntar la función de manejo de interrupción
// Establecer la alarma del timer temporizador (parámetro 1) para que llame a timerInterrupt cada medio segundo (parámetro 2 - valor en microsegundos)
// Poner a true que se repita la alarma (parámetro 3) y lo haga de forma indefinida (parámetro 4 - 0=indefinido)
timerAlarm(temporizador, 500000, true, 0);
timerStop(temporizador); // El timer empezará cuando se pulse el botón
}
// 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
timerStop(temporizador); // Parar la cuenta del 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);
}