//****************************************************************
// Librerías
//****************************************************************
#include <Arduino.h>
//****************************************************************
// Definición de etiquetas
//****************************************************************
#define LED_1B_PIN GPIO_NUM_33 //Led 1 Contador
#define LED_2B_PIN GPIO_NUM_25 //Led 2 Contador
#define LED_3B_PIN GPIO_NUM_26 //Led 3 Contador
#define LED_4B_PIN GPIO_NUM_27 //Led 4 Contador
#define LED_1T_PIN GPIO_NUM_23 //Led 1 Timer
#define LED_2T_PIN GPIO_NUM_22 //Led 2 Timer
#define LED_3T_PIN GPIO_NUM_1 //Led 3 Timer
#define LED_4T_PIN GPIO_NUM_3 //Led 4 Timer
#define LED_A_PIN GPIO_NUM_21 //Led de Alerta
//****************************************************************
// Prototipos de funciones
//****************************************************************
void actualizarLEDB(); //Actualizar Led Contador
void actualizarLEDT(); //Actualizar Led Temporizador
void actualizarLedA(); //Actulizar Led de Alerta
//****************************************************************
// Variables Globales
//****************************************************************
bool ledState; //Led de Alerta
volatile int interruptCounter;
int contadorT;
int contadorB;
unsigned long button_time = 0;
unsigned long last_button_time = 0;
//****************************************************************
// Definición de Estructura de Botones
//****************************************************************
struct Button {
const uint8_t PIN;
volatile bool pressed;
};
Button btnD = {34, false}; //Decremento de Contador Button
Button btnI = {35, false}; //Incremento de Contador Button
Button btnT = {36, false}; //Boton Tactil
//****************************************************************
// ISR: Interrupciones
//****************************************************************
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
//Interrupción Boton Decrementar
void IRAM_ATTR handlerBTNDISR() {
portENTER_CRITICAL_ISR(&mux);
button_time = xTaskGetTickCount(); //millis();
if (button_time - last_button_time > 250) {
btnD.pressed = true;
last_button_time = button_time;
}
portEXIT_CRITICAL_ISR(&mux);
}
//Interrupción Boton Incrementar
void IRAM_ATTR handlerBTNIISR() {
portENTER_CRITICAL_ISR(&mux);
button_time = xTaskGetTickCount(); //millis();
if (button_time - last_button_time > 250) {
btnI.pressed = true;
last_button_time = button_time;
}
portEXIT_CRITICAL_ISR(&mux);
}
//Interrupción Boton Tactil
void IRAM_ATTR handlerBTNTISR() {
portENTER_CRITICAL_ISR(&mux);
button_time = xTaskGetTickCount(); //millis();
if (button_time - last_button_time > 250) {
btnT.pressed = true;
last_button_time = button_time;
}
portEXIT_CRITICAL_ISR(&mux);
}
//Interrupción Timer
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR handlerTimerISR() {
portENTER_CRITICAL_ISR(&timerMux);
interruptCounter++;
portEXIT_CRITICAL_ISR(&timerMux);
}
//****************************************************************
//Configuración
//****************************************************************
void setup() {
//Definir LEDs como salidas
pinMode(LED_1B_PIN, OUTPUT); //Led1 Contador
pinMode(LED_2B_PIN, OUTPUT); //Led2 Contador
pinMode(LED_3B_PIN, OUTPUT); //Led3 Contador
pinMode(LED_4B_PIN, OUTPUT); //Led4 Contador
pinMode(LED_1T_PIN, OUTPUT); //Led1 Timer
pinMode(LED_2T_PIN, OUTPUT); //Led2 Timer
pinMode(LED_3T_PIN, OUTPUT); //Led3 Timer
pinMode(LED_4T_PIN, OUTPUT); //Led4 Timer
pinMode(LED_A_PIN, OUTPUT); //Led de Alerta
//Definir boton Decrementar como entrada e interrupción del botón
pinMode(btnD.PIN, INPUT_PULLDOWN);
attachInterrupt(btnD.PIN, handlerBTNDISR, FALLING);
//Definir boton Incrementar como entrada e interrupción del botón
pinMode(btnI.PIN, INPUT_PULLDOWN);
attachInterrupt(btnI.PIN, handlerBTNIISR, FALLING);
//Definir boton Incrementar como entrada e interrupción del botón
pinMode(btnT.PIN, INPUT_PULLDOWN);
attachInterrupt(btnT.PIN, handlerBTNTISR, FALLING);
//Definir Parametros de Timer
timer = timerBegin(0, 80, true); // (No. Timer, Prescaler, True: Subida, False: bajada )
timerAttachInterrupt(timer, &handlerTimerISR, true); //(timer, función de ISR, True: flanco, False: nivel )
timerAlarmWrite(timer, 250000, true); //(timer, valor de alarma, True: autoreload)
timerAlarmEnable(timer);
//Inicalizar variables
ledState = HIGH;
contadorB = 0;
Serial.begin(115200);
}
//****************************************************************
// Loop Principal
//****************************************************************
void loop() {
Serial.printf("Timer: %d - ", contadorT);
Serial.printf("Boton %d\n", contadorB);
if (interruptCounter > 0) {
portENTER_CRITICAL(&timerMux);
interruptCounter--;
portEXIT_CRITICAL(&timerMux);
contadorT++;
actualizarLEDT();
}
portENTER_CRITICAL_ISR(&mux);
if (btnI.pressed) {
contadorB++;
actualizarLEDB();
btnI.pressed = false;
}
portEXIT_CRITICAL_ISR(&mux);
portENTER_CRITICAL_ISR(&mux);
if (btnD.pressed) {
contadorB--;
actualizarLEDB();
btnD.pressed = false;
}
portEXIT_CRITICAL_ISR(&mux);
portENTER_CRITICAL_ISR(&mux);
if (btnT.pressed) {
contadorT = 0;
btnT.pressed = false;
}
portEXIT_CRITICAL_ISR(&mux);
if (contadorT > 15){
contadorT = 0;
}
if (contadorB > 15){
contadorB = 0;
}
if (contadorB < 0){
contadorB = 15;
}
if (contadorB == contadorT){
Serial.println("Son Iguales");
actualizarLedA();
}
}
//****************************************************************
//Funciones
//****************************************************************
//Función para actualizar Leds de Contador con Boton
void actualizarLEDB() {
digitalWrite(LED_1B_PIN, contadorB & 0x01);
digitalWrite(LED_2B_PIN, (contadorB >> 1) & 0x01);
digitalWrite(LED_3B_PIN, (contadorB >> 2) & 0x01);
digitalWrite(LED_4B_PIN, (contadorB >> 3) & 0x01);
}
//Función para actualizar Leds de Contador con Timer
void actualizarLEDT() {
digitalWrite(LED_1T_PIN, contadorT & 0x01);
digitalWrite(LED_2T_PIN, (contadorT >> 1) & 0x01);
digitalWrite(LED_3T_PIN, (contadorT >> 2) & 0x01);
digitalWrite(LED_4T_PIN, (contadorT >> 3) & 0x01);
}
//Función para actualizar Led de Alerta
void actualizarLedA(){
ledState = !ledState; // Invierte el estado actual del LED
digitalWrite(LED_A_PIN, ledState); // Aplica el nuevo estado al LED
contadorT = 0; // Reinicia el contador para empezar de nuevo
}