#define seta_emergencia 19 //?¿?¿¿??¿Se pueden usar estos pines???¿?¿?¿¿
#define LED2 18
int emergencia=0;
int seta_pulsada=0;
//Condiciones para salir del estado de emergencia
int condicion1=0; //Que la seta esté pulsada 3 segundos seguidos
int condicion2=0;//Cuando condicion2 vale 1, significa que se cumplen los requisitos para volver al modo normal
int salir=0; //Me indica que estoy intentando salir del modo de emergencia
int tic=0;
int tac=0;
int tiemposalida=0;
int toc=0;
int tuc=0;
hw_timer_t *timer4 = NULL;
//Hago que alarma TIMER se ejecute cada 1ms y que pueda contar 3 s ( como funcion millis())
void modo_emergencia()
{
salir=1; //Indica que estoy intentando salir del modo de emergencia (segunda vez que pulso la seta)
//Implemento la condicion1 --> Seta pulsada al menos 3 segundos seguidos
//3 segundos equivale con 3000 interrupciones
if(seta_pulsada==1)
tic++;
if(tic>3000+tac)
{
tac=tic;
condicion1=1; //se cumple que se ha estado pulsando 3 segundos seguidos el pulsador
}
//Cuando ya se ha cumplido la condicion1 (seta pulsada al menos 3 segundos) y suelto la seta --> Espero 3 segundos y se desactiva el estado de emergencia
if(tiemposalida==1)
toc++;
if(toc>3000+tuc)
{
tuc=toc;
condicion2=1; //se cumple que se ha estado pulsando 3 segundos seguidos el pulsador
}
//Condicion de salida del estado de emergencia
//Puedo dejar solo que la condicion2 sea igual a 1 (solo puede ser 1 si la condicion1 también es 1)
if(condicion1==1 && condicion2==1) //Entra por la cara a esta condición aunque NO se cumpla
//condicion2 NO es igual a 2 en NINGÚN momento y aún así entra
{
emergencia=0; //Cuando salimos de emergencia, se resetean todos los valores
digitalWrite(LED2,LOW);
condicion1=0;
condicion2=0;
toc=0;
tuc=0;
tic=0;
tac=0;
salir=0;
tiemposalida=0;
seta_pulsada=0;
}
}
void entrada_emergencia()
{
detachInterrupt(digitalPinToInterrupt(seta_emergencia));
//Queremos que empiece el Timer una vez que estoy en emergencia (para salir del estado de emergencia)
if(emergencia==1)
{
timerAlarm(timer4,1000, true, 0); //Alarma cada 1 ms (solo se ejecuta 1 vez cuando presiono el pulsador "false")
tic=0; //Si estoy intentando salir de emergencia y se vuelve a pulsar, empiezo la cuenta de los 3 segundos de nuevo
seta_pulsada=1;
}
emergencia=1; //Entro en el modo emergencia
digitalWrite(LED2,HIGH);
//digitalWrite(LED1,LOW);
}
void salida_emergencia()
{
detachInterrupt(digitalPinToInterrupt(seta_emergencia));
if(condicion1==0 && salir==1) //Si estamos saliendo de emergencia y suelto pulsador antes de que hayan pasado 3 segundos
{
tic=0;
seta_pulsada=0;
}
if(condicion1==1) //Una vez que se ha cumplido la condicion1 y suelto el pulsador, me da igual lo que pase, cuando pasen 3 segundos se desactiva el modo de emergencia
{
tiemposalida=1;
seta_pulsada=0; //No hace falta
}
}
void setup()
{
Serial.begin(115200);
pinMode(seta_emergencia, INPUT);
pinMode(LED2, OUTPUT);
//TIMER
timer4 = timerBegin(10e5); //Configuramos la frecuencia a 1 millón
timerAttachInterrupt(timer4, &modo_emergencia);
}
void loop()
{
//No se pueden poner dos interrupciones en un mismo pulsador a la vez, no funciona bien --> Pongo condiciones para que solo haya una única interrupción al mismo tiempo
if(digitalRead(seta_emergencia)==0)
attachInterrupt(digitalPinToInterrupt(seta_emergencia),entrada_emergencia,RISING); //Lo pongo en loop ya que elimino los rebotes (desactivo la interrupción en la propia ISR --> tengo que volver a activarla)
if(digitalRead(seta_emergencia)==1)
attachInterrupt(digitalPinToInterrupt(seta_emergencia),salida_emergencia,FALLING);
Serial.printf("emergencia %d \n", emergencia);
Serial.printf("condicion1 %d \n", condicion1);
Serial.printf("condicion2 %d \n", condicion2);
Serial.printf("setapulsada %d \n", seta_pulsada);
delay(10); //delay para que el programa vaya mejor
}