Hola
Tengo un proyecto en desarrollo.
El montaje consiste en:
• Un Arduino pro mini
• Un mando a distancia de RF
• Una pantalla LCD 16x2 I2C
• Un modulo de relé que activa una cerradura eléctrica
La pantalla LCD va mostrando mensajes en modo cíclico y cada ciclo dura unos minutos, hasta que se pulsa el mando para abrir la puerta y muestra en mensaje “PUERTA ABIERTA” durante unos segundos.
La patilla común (se pone a 5V cuando se pulsa cualquier botón del mando) del RF está conectada al pin 2 para que active una interrupción al ponerse en HIGH.
El código básicamente es:
#define PIN_MANDO 2
#define PIN_RELE 10
#define screenDir 0x27 // Dirección I2C de la pantalla
LiquidCrystal_I2C lcd(screenDir, 16, 2); // Inicia la pantalla
volatile boolean Puerta_Abierta = false; // Variable para indicar el estado del relé
void setup()
{
lcd.init(); //Inicializa el LCD
lcd.setBacklight(HIGH); //Enciende la pantalla
attachInterrupt(digitalPinToInterrupt(PIN_MANDO), interrupccion,RISING); // debe cambiar el estado de la variable del estado de la puerta
}
void loop()
{
//Aquí van las llamadas a las funciones en el modo demo
if (Puerta_Abierta) abrePuerta(); // Si hay que abrir la puerta, salta a la función de activación del relé
void LCDanimateText(“EJEMPLO”,”TEXTO”);
}
//Ejemplo de una función de texto animado
void LCDanimateText(String texto1, String texto2)
{
boolean sale = random(2); //Elige aleatoriamente si sale el texto por la derecha de la pantalla o se queda parado en el centro
String textop;
lcd.clear();
textop = " " + texto1;
lcd.home();
lcd.print(textop);
textop = " " + texto2;
lcd.setCursor(0, 1);
lcd.print(textop);
for (byte n = 0; n < 24 + sale * 12; n++)
{
lcd.scrollDisplayRight();
if (n == 23) waitBreak(1500);
if (Puerta_Abierta) return;
waitBreak(100);
}
if (sale) lcd.clear();
}
//Función de espera sin dealys
void waitBreak(unsigned long milisegundos)
{
// Retarda los milisegundos que se envían hasta que se pulse un botón
// Mantiene un tiempo inactivo el programa sin interferir en las interrupciones
unsigned long tempIni = millis(); // Lee el tiempo a la entrada de la función
while ((millis() - tempIni) < milisegundos)
{
if (Puerta_Abierta)
break; // sale si hay un botón pulsado
}
}
//La función que debe tratar la interrupción
void interrupcion()
{
//Filosofía de esta función de interrupción: Entra, haz lo mínimo posible y sal pitando
Puerta_Abierta=true;
}
//Función para abrir la puerta. No me importa usar delay en esta función.
void abrePuerta()
{
Lcd.clear();
LCDanimateText(“PUERTA ABIERTA”, “”);
digitalWrite(PIN_RELE,LOW);
delay (1000); //Mantiene activo el relé durante 1 segundo
digitalWrite (PIN_RELE,HIGH); // desactiva el relé
Puerta_Abierta = false; // cambia el flag de puerta abierta a falso
delay (5000); // Mantiene el texto durante 5 segundos
}
Esto funciona perfectamente. Pero, como se puede ver en el ejemplo, hay que ir comprobando periódicamente el estado de la variable Puerta_Abierta para salir del modo demo y no se me ocurre otra forma mejor de hacerlo, seguro que es una tontería, pero no se me ocurre otra manera y no he encontrado (o he sabido buscar) algo que me pueda ayudar. Hay que tener en cuenta que en el loop hay muchas más funciones de animaciones de texto e iconos que aún no tengo terminadas.
No me parece una forma “elegante” ya que no es lo que se pretende con las interrupciones, y ya es sólo por optimizar y aprender más. Si alguien me puede dar una pista o echar un cable.
El proyecto tengo en mente mejorarlo con un mp3 para dar efectos sonoros o voces.
Muchas gracias y espero que también el código le pueda servir a alguien.