#include <LiquidCrystal_I2C.h>
#define I2C_addr 0x27
#define columnsLCD 20
#define rowsLCD 4
LiquidCrystal_I2C lcd(I2C_addr, columnsLCD, rowsLCD);
#define ledEspera 19
#define ledArmada 17
#define ledFuncionar 16
#define ledWarning 2
#define buttonArmar 34
#define buttonFuncionar 35
#define buttonParar 32
#define buttonDesarmar 33
#define buttonSeguridad 4
#define buttonWarning 18
#define pinBuzzer 14
#define note 1000
#define ESTADO_0 0
#define ESTADO_1 1
#define ESTADO_2 2
#define ESTADO_3 3
#define ESTADO_4 4
volatile bool buttonArmarInterrupted = false;
volatile bool buttonFuncionarInterrupted = false;
volatile bool buttonPararInterrupted = false;
volatile bool buttonDesarmarInterrupted = false;
volatile bool buttonSeguridadInterrupted = false;
volatile bool buttonSeguridadPressed = false;
volatile bool buttonWarningInterrupted = false;
volatile bool timer0_interrupted = false;
volatile bool timer1_interrupted = false;
volatile bool long_pressed = false;
volatile bool ok = false; //Variable de fin de cuenta del parpadeo
volatile int state = ESTADO_0;
volatile int n = 0;
hw_timer_t *timer0 = NULL;
hw_timer_t *timer1 = NULL;
void IRAM_ATTR buttonArmar_ISR() {
buttonArmarInterrupted = true;
}
void IRAM_ATTR buttonFuncionar_ISR() {
buttonFuncionarInterrupted = true;
}
void IRAM_ATTR buttonParar_ISR() {
buttonPararInterrupted = true;
}
void IRAM_ATTR buttonDesarmar_ISR() {
buttonDesarmarInterrupted = true;
}
void IRAM_ATTR buttonSeguridad_ISR() {
buttonSeguridadInterrupted = true;
buttonSeguridadPressed = !buttonSeguridadPressed;
}
void IRAM_ATTR buttonWarning_ISR() {
buttonWarningInterrupted = true;
}
void IRAM_ATTR timer_count() {
timer0_interrupted = true;
}
void IRAM_ATTR timer_blink() {
timer1_interrupted = true;
}
void FineStateMachine() {
switch (state) {
case ESTADO_0:
if (n == 0) {
n++;
Serial.println("Espera. Pulse Armar");
Serial.print("Estado:");
Serial.println(state);
lcd.clear();
lcd.print("Estado:" + String(state) + " Desarmada");
}
if (buttonArmarInterrupted) {
//Serial.println("entreaaaaaa");
buttonArmarInterrupted = false;
state = ESTADO_1;
digitalWrite(ledEspera, LOW);
digitalWrite(ledArmada, HIGH);
n = 0;
}
if (buttonWarningInterrupted) {
Serial.println("Boton atascada pulsado");
buttonWarningInterrupted = false;
state = ESTADO_3;
digitalWrite(ledEspera, LOW);
digitalWrite(ledArmada, LOW);
digitalWrite(ledFuncionar, LOW);
digitalWrite(ledWarning, HIGH);
timerRestart(timer1);
timerAlarmEnable(timer1);
n = 0;
}
if (buttonFuncionarInterrupted) {
buttonFuncionarInterrupted = false;
}
break;
case ESTADO_1:
if (n == 0) {
n++;
Serial.println("Armada. Pulse Funcionar");
Serial.print("Estado:");
Serial.println(state);
lcd.clear();
lcd.print("Estado:" + String(state) + " Armada");
}
if (buttonFuncionarInterrupted) {
buttonFuncionarInterrupted = false;
state = ESTADO_2;
digitalWrite(ledEspera, LOW);
digitalWrite(ledArmada, LOW);
digitalWrite(ledFuncionar, HIGH);
n = 0;
}
if (buttonDesarmarInterrupted) {
buttonDesarmarInterrupted = false;
state = ESTADO_0;
digitalWrite(ledEspera, HIGH);
digitalWrite(ledArmada, LOW);
digitalWrite(ledFuncionar, LOW);
n = 0;
}
if (buttonWarningInterrupted) {
Serial.println("Boton atascada pulsado");
buttonWarningInterrupted = false;
state = ESTADO_3;
digitalWrite(ledEspera, LOW);
digitalWrite(ledArmada, LOW);
digitalWrite(ledFuncionar, LOW);
digitalWrite(ledWarning, HIGH);
timerRestart(timer1);
timerAlarmEnable(timer1);
n = 0;
}
break;
case ESTADO_2:
if (n == 0) {
n++;
Serial.println("Funcionando");
Serial.print("Estado:");
Serial.println(state);
lcd.clear();
lcd.print("Estado:" + String(state) + " Funcionando");
}
if (buttonPararInterrupted) {
buttonPararInterrupted = false;
state = ESTADO_1;
digitalWrite(ledEspera, LOW);
digitalWrite(ledArmada, HIGH);
digitalWrite(ledFuncionar, LOW);
n = 0;
}
if (buttonWarningInterrupted) {
buttonWarningInterrupted = false;
state = ESTADO_3;
Serial.println("Boton atascada pulsado");
digitalWrite(ledEspera, LOW);
digitalWrite(ledArmada, LOW);
digitalWrite(ledFuncionar, LOW);
digitalWrite(ledWarning, HIGH);
timerRestart(timer0);
timerAlarmEnable(timer0);
n = 0;
}
if (buttonDesarmarInterrupted) {
buttonDesarmarInterrupted = false;
}
if (buttonPararInterrupted) {
buttonPararInterrupted = false;
}
break;
case ESTADO_3:
if (n == 0) {
n++;
Serial.println("¡PIEZA ATASCADA. Es necesario un rearme!. Para ello pulsación larga (>1s)");
Serial.print("Estado:");
Serial.println(state);
lcd.clear();
lcd.print("PIEZA ATASCADA->REARMAR");
// Activamos el buzzer
tone(pinBuzzer, note); // Nota, para hacer sonar el buzzer
}
// Parpadeo del LED sin interferir con el buzzer
if (timer1_interrupted) {
digitalWrite(ledWarning, !digitalRead(ledWarning)); // Parpadeo del LED
timer1_interrupted = false;
}
if (buttonSeguridadInterrupted) {
buttonSeguridadInterrupted = false;
if (buttonSeguridadPressed) {
Serial.println("Boton seguridad pulsado, timer arrancado, estado 3");
timerRestart(timer0);
timerAlarmEnable(timer0);
}
else {
Serial.println("Boton seguridad soltado, timer parado, estado 3");
timerAlarmDisable(timer0);
if (long_pressed) {
Serial.println("Pulsacion larga correcta.");
long_pressed = false;
state = ESTADO_4;
digitalWrite(ledWarning, HIGH); // Aseguramos que el LED esté en estado encendido
n = 0;
noTone(pinBuzzer); // Detener el buzzer cuando se hace la transición
}
}
}
if (timer0_interrupted) {
long_pressed = true;
timer0_interrupted = false;
}
break;
case ESTADO_4:
if (n == 0) {
n++;
Serial.println("Estado de Alerta Conocida. Pulsacion corta para ir a Desarmada");
Serial.print("Estado:");
Serial.println(state);
lcd.clear();
lcd.print("ESTADO DE SEGURIDAD");
}
if (buttonSeguridadInterrupted) {
if (buttonSeguridadPressed) {
timerRestart(timer0);
timerAlarmEnable(timer0);
}
else {
timerAlarmDisable(timer0);
if (!long_pressed) {
Serial.println("Pulsacion corta Estado de Desarmada");
digitalWrite(ledEspera, HIGH);
digitalWrite(ledArmada, LOW);
digitalWrite(ledFuncionar, LOW);
digitalWrite(ledWarning, LOW);
timerAlarmDisable(timer0);
state = ESTADO_0;
n = 0;
noTone(pinBuzzer);
}
}
}
if (timer0_interrupted) {
long_pressed = true;
timer0_interrupted = false;
}
break;
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(buttonArmar, INPUT_PULLUP);
pinMode(buttonFuncionar, INPUT_PULLUP);
pinMode(buttonParar, INPUT_PULLUP);
pinMode(buttonDesarmar, INPUT_PULLUP);
pinMode(buttonWarning, INPUT_PULLUP);
pinMode(buttonSeguridad, INPUT_PULLUP);
pinMode(ledEspera, OUTPUT);
pinMode(ledWarning, OUTPUT);
pinMode(ledFuncionar, OUTPUT);
pinMode(ledArmada, OUTPUT);
// pinMode(pinBuzzer, OUTPUT);
// Configurar interrupciones
attachInterrupt(digitalPinToInterrupt(buttonArmar), buttonArmar_ISR, FALLING);
attachInterrupt(digitalPinToInterrupt(buttonFuncionar), buttonFuncionar_ISR, FALLING);
attachInterrupt(digitalPinToInterrupt(buttonParar), buttonParar_ISR, FALLING);
attachInterrupt(digitalPinToInterrupt(buttonDesarmar), buttonDesarmar_ISR, FALLING);
attachInterrupt(digitalPinToInterrupt(buttonWarning), buttonWarning_ISR, FALLING);
attachInterrupt(digitalPinToInterrupt(buttonSeguridad), buttonSeguridad_ISR, CHANGE);
timer0 = timerBegin(0, 80, true);
timerAttachInterrupt(timer0, &timer_count, true);
timerAlarmWrite(timer0, 1000000, true);
timer1 = timerBegin(1, 80, true);
timerAttachInterrupt(timer1, &timer_blink, true);
timerAlarmWrite(timer1, 1000000, true);
digitalWrite(ledEspera, HIGH);
digitalWrite(ledArmada, LOW);
digitalWrite(ledFuncionar, LOW);
digitalWrite(ledWarning, LOW);
lcd.init();
lcd.backlight();
}
void loop() {
// put your main code here, to run repeatedly:
FineStateMachine();
delay(10); // this speeds up the simulation
}