#define L1_PIN 18
#define L2_PIN 17
#define L3_PIN 16
#define B1_PIN 25
#define B2_PIN 26
#define B3_PIN 27
#define R_PIN 14
volatile bool boton1Pulsa = 0;
volatile bool boton1Suelta = 0;
volatile bool boton2Pulsa = 0;
volatile bool boton2Suelta = 0;
volatile bool boton3Pulsa = 0;
volatile bool boton3Suelta = 0;
volatile bool parpadeo_activated = false;
volatile int interrupt_counter = 0;
volatile int parpadeo_counter = 0;
volatile int estado = 0;
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;
hw_timer_t *tparpadeo = NULL;
int timer_frequency = 1000000; // Frecuencia del timer en Hz (como de rápido cuenta el timer)
int timer_parpadeo = 1000000;
// Callback ISR interrupción de los botones
void IRAM_ATTR b1()
{
if (digitalRead(B1_PIN) == LOW)
{
timerStart(timer); // Habilitar timer
boton1Pulsa = true;
interrupt_counter = 0;
}
else
{
boton1Suelta = true;
timerStop(timer);
}
}
void IRAM_ATTR b2()
{
if (digitalRead(B2_PIN) == LOW)
{
timerStart(timer); // Habilitar timer
boton2Pulsa = true;
interrupt_counter = 0;
}
else
{
boton2Suelta = true;
timerStop(timer);
}
}
void IRAM_ATTR b3()
{
if (digitalRead(B3_PIN) == LOW)
{
timerStart(timer); // Habilitar timer
boton3Pulsa = true;
interrupt_counter = 0;
}
else
{
boton3Suelta = true;
timerStop(timer);
}
}
void IRAM_ATTR reset()
{
estado = 0;
Serial.println("RESET");
Serial.println("estoy en el estado 0");
boton1Pulsa = 0;
boton1Suelta = 0;
boton2Pulsa = 0;
boton2Suelta = 0;
boton3Pulsa = 0;
boton3Suelta = 0;
digitalWrite(L1_PIN, LOW);
digitalWrite(L2_PIN, LOW);
digitalWrite(L3_PIN, LOW);
}
// Callback ISR interrupción del timer
void IRAM_ATTR timerInterrupt()
{
interrupt_counter++; // Se incrementa el contador de interrupciones del timer
}
// Callback ISR temporizador para parpadeo LED
void IRAM_ATTR parpadeo()
{
parpadeo_activated = !parpadeo_activated;
parpadeo_counter++;
}
// Funcion de 3 parpadeos
void parpadeo3(int LED)
{
timerStart(tparpadeo);
while (parpadeo_counter < 6)
{
digitalWrite(LED, parpadeo_activated);
}
timerStop(tparpadeo);
parpadeo_counter = 0;
}
void incorrecto()
{
estado = 0;
boton1Pulsa = 0;
boton1Suelta = 0;
boton2Pulsa = 0;
boton2Suelta = 0;
boton3Pulsa = 0;
boton3Suelta = 0;
digitalWrite(L1_PIN, LOW);
digitalWrite(L2_PIN, LOW);
digitalWrite(L3_PIN, LOW);
Serial.println("INCORRECTO : estoy en el estado 0");
}
void setup()
{
Serial.begin(115200);
//Config. puertos
pinMode(L1_PIN, OUTPUT);
pinMode(L2_PIN, OUTPUT);
pinMode(L3_PIN, OUTPUT);
pinMode(B1_PIN, INPUT_PULLUP);
pinMode(B2_PIN, INPUT_PULLUP);
pinMode(B3_PIN, INPUT_PULLUP);
pinMode(R_PIN, INPUT_PULLUP);
//Config. interrupciones
attachInterrupt(digitalPinToInterrupt(B1_PIN), &b1, CHANGE);
attachInterrupt(digitalPinToInterrupt(B2_PIN), &b2, CHANGE);
attachInterrupt(digitalPinToInterrupt(B3_PIN), &b3, CHANGE);
attachInterrupt(digitalPinToInterrupt(R_PIN), &reset, RISING);
estado = 0;
//Config. timer botones
timer = timerBegin(timer_frequency);
timerAttachInterrupt(timer, &timerInterrupt);
timerAlarm(timer, 500000, true, 0); // LARGO MÁS DE 0.5 S
timerStop(timer);
//Config. timer parpadeo LED
tparpadeo = timerBegin(timer_parpadeo);
timerAttachInterrupt(tparpadeo, &parpadeo);
timerAlarm(tparpadeo, 500000, true, 0); // PARPADEO CADA 0.5 S
timerStop(tparpadeo);
Serial.println("estoy en el estado 0");
digitalWrite(L1_PIN, LOW);
digitalWrite(L2_PIN, LOW);
digitalWrite(L3_PIN, LOW);
}
void loop()
{
switch (estado)
{
case 0: // CORRECTO B1 CORTO
if (boton1Pulsa && boton1Suelta && interrupt_counter < 1)
{
boton1Suelta = false;
boton1Pulsa = false;
parpadeo3(L1_PIN);
digitalWrite(L1_PIN, HIGH);
Serial.println("Correcto: estoy en el estado 1");
estado = 1;
}
else if (boton2Suelta or boton3Suelta or (boton1Suelta && interrupt_counter > 1))
{
parpadeo3(L1_PIN);
incorrecto();
}
break;
case 1: // CORRECTO B3 LARGO
if (boton3Pulsa && boton3Suelta && interrupt_counter > 1)
{
parpadeo3(L2_PIN);
digitalWrite(L2_PIN, HIGH);
boton3Pulsa = false;
boton3Suelta = false;
Serial.println("Correcto: estoy en el estado 2");
estado = 2;
}
else if (boton1Suelta or boton2Suelta or (boton3Suelta && interrupt_counter < 1))
{
parpadeo3(L2_PIN);
incorrecto();
}
break;
case 2: // CORRECTO B1 LARGO
if (boton1Pulsa && boton1Suelta && interrupt_counter > 1)
{
parpadeo3(L3_PIN);
boton1Suelta = false;
boton1Pulsa = false;
Serial.println("*****CODIGO DESCIFRADO*****");
Serial.println("Pulsa RESET para vovler a empezar");
timerStart(tparpadeo);
estado = 3;
}
else if (boton2Suelta or boton3Suelta or (boton1Suelta && interrupt_counter < 1))
{
parpadeo3(L3_PIN);
incorrecto();
}
break;
case 3: // ABIERTO
digitalWrite(L1_PIN, parpadeo_activated);
digitalWrite(L2_PIN, parpadeo_activated);
digitalWrite(L3_PIN, parpadeo_activated);
break;
}
delay(10); // this speeds up the simulation
}