Hola.
Estoy tratando de crear un menú para encendido y apagado de luces y extractores y al mismo tiempo que este funcionando un reloj a tiempo real. Hasta ahora el reloj no "se pierde" y mis sub-menus funcionan correctamente, el problema es que la pantalla LCD 20x4, después de funcionar alrededor de 2 horas, comienza a fallar imprimiendo un par de números que no deberian de estar y despues de unas 12 hr de comienza a mostrara caracteres raros y como que palpita.
El código lo incluire en una respuesta ya que no me deja postearlo porque excedo de caracteres
Este es programa principal sin los sub-menus, lo posteo asi ya que el programa es demasiado extenso
//Me estoy basando en este proyecto http://giltesa.com/?p=11550
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,20,4); //Configuracion de mi LCD e interfaz I2c. SDA en A4 y SCL en A5
int minutos=0; //Defino variables
int segundos=0;
int horas=0;
unsigned long timer1=0; //Bases para segundo.
unsigned long timer2=0;
int ExtractorU=2; //Salidas. en pines 2, 3, 4 y 5
int ExtractorD=3;
int luzu=4;
int luzd=5;
byte arrowDown[8] = {B00000, B01110, B01110, B01110, B11111, B01110, B00100}; // Caracteres personalizados para el LCD
byte cursorLCD[8] = {B00000, B00000, B00110, B01111, B01111, B00110, B00000};
byte ledOn[8] = {B00000, B01110, B10001, B10001, B01010, B01110, B01110};
byte white[8] = {B11111, B11111, B11111, B11111, B11111, B11111, B11111};
void setup()
{
lcd.begin(20, 4); //Indicamos que tipo de pantalla es.
lcd.backlight(); //Iniciamos pantalla
lcd.init();
pinMode(luzu, OUTPUT); //Mis salidas.
pinMode(luzd, OUTPUT);
pinMode(ExtractorU,OUTPUT);
pinMode(ExtractorD,OUTPUT);
lcd.createChar(0, cursorLCD); // Se añaden los caracteres especiales al objeto LCD:
lcd.createChar(1, arrowDown);
lcd.createChar(2, ledOn);
lcd.createChar(3, white);
}
void loop()
{
timer2=(millis()/1000);
if ( timer1 != timer2 ) {
timer1=timer2;
segundos++; // unidades de segundo se incrementa cada segundo
}
if (segundos>59){ //Si segundos pasa de 59, aumento 1 a minutos
minutos++;
segundos=0; //segundos vuelvo a 0
}
if (minutos>59){ //si minutos es mas de 59, aumento 1 a horas
horas++;
minutos=0; //vuelve a 0 los minutos
}
lcd.setCursor(0, 0); //Posicioneamos donde queremos escribir,
if (horas<10){ //Si horas es menor a 10 imprime 0
lcd.print("0");
}
lcd.print(horas); //Imprimimos el valor que tengamos en horas
lcd.print(":"); //Si el valor de horas es mas de 10, se sustituira el 0 creado anteriormente
if (minutos<10){
lcd.print("0");
}
lcd.print(minutos); //igual que con horas
/*Para imprimir los segundo*/
lcd.print(":");
if (segundos<10){
lcd.print("0");
}
lcd.print(segundos);
if (horas>23)
horas=0;
char resultButton[7] = "null";
// Se imprime la pantalla de inicio:
lcd.setCursor(8, 0); lcd.print("Menu MTTO");
lcd.setCursor(0, 1); lcd.print("LUCES Y EXTRACTORES");
lcd.setCursor(7, 3); lcd.print("Pulse "); lcd.write(byte(1));
// Se comprueba si se ha pulsado un botón:
getButtonPush( resultButton, 0, 200);
// Si se pulsa la tecla abajo, se entra en el menú:
if( !strcmp(resultButton,"bottom"))
LCDmenu();
}//Fin del void loop, mas abajo comienzan las subrutinas o submenus
Alguien sabe como subir imagenes? Estoy tratando con todos los servidores pero no se muestran aqui.
Saludos.
Aqui esta solo un submenu, la subrutina que uso para mostrar movimiento de cursor y subrutina que verifica nueva pulsaciones(Uso 4 botones a una entrada analogica)
void LCDmenu0()
{
char resultButton[7];
int posCursor=0, opcMenu=-2;
// Menu
lcd.clear();
lcd.setCursor(2, 0); lcd.print("Hora");
lcd.setCursor(2, 1); lcd.print("Minutos");
lcd.setCursor(2, 2); lcd.print("Salir");
lcd.setCursor(0, 3); //Posicioneamos donde queremos escribir,
if (horas<10){ //Si horas es menor a 10 imprime 0
lcd.print("0");
}
lcd.print(horas); //Imprimimos el valor que tengamos en horas
lcd.print(":"); //Si el valor de horas es mas de 10, se sustituira el 0 creado anteriormente
if (minutos<10){
lcd.print("0");
}
lcd.print(minutos); // Mientras no se pulse sobre salir, no se saldrá al Menú:
do{
strcpy(resultButton,"null");
getButtonPush( resultButton, 0, 200);
// Cursor que indica la opcion seleccioanda:
lcd.setCursor(0, posCursor); lcd.write(byte(0));
// Desplaza el cursor arriba o abajo,:
if(!strcmp(resultButton,"up"))
LCDMueveCursor(&posCursor, 2, 'r'); // Se resta una posición al cursor
else if(!strcmp(resultButton,"bottom")) // Se suma una posición al cursor
LCDMueveCursor(&posCursor, 2, 's');
else if(!strcmp(resultButton,"right") || !strcmp(resultButton,"left"))
opcMenu = posCursor;
// Según la opción elegida del menú, se le cambia el estado a un LED, al otro o se cierra el menú actual:
switch( opcMenu )
{
// Horas
case 0:
if(!strcmp(resultButton,"right")) // Aumenra 1 HR
horas++;
opcMenu = -2;
break;
// Minutos
case 1:
if(!strcmp(resultButton,"right")) //Aumenra 1 min
minutos++;
opcMenu = -2;
break;
// Salir
case 2:
if(!strcmp(resultButton,"right"))
opcMenu = -1;
break;
};
}
while(opcMenu != -1);
// Al salir del Menu1 se imprime el menú anterior:
// Menu
lcd.clear();
lcd.setCursor(2, 0); lcd.print("Reloj"); //Solo hare el menu para modificar reloj
lcd.setCursor(2, 1); lcd.print("Extractores");
lcd.setCursor(2, 2); lcd.print("Salir");
}//Fin del LCDMenu0, control del reloj.
void LCDMueveCursor(int *pos, int max, char ope)//Esto sirve para crear movimiento en la pantalla de movimiento del cursor
{
// Precondición: El parámetro ope debería de ser el carácter 's' o 'r' para sumar o restar una posición.
// El parámetro max indica el numero de opciones a elegir.
// Poscondición: Se devuelve por referencia el nuevo valor del cursor.
if(ope == 's')
if(*pos < max) *pos += 1;
else *pos = 0;
else
if(*pos > 0) *pos -= 1;
else *pos = max;
// Se borran los cursores:
lcd.setCursor(0, 0); lcd.print(" ");
lcd.setCursor(0, 1); lcd.print(" ");
lcd.setCursor(0, 2); lcd.print(" ");
lcd.setCursor(0, 3); lcd.print(" ");
}
// PROCEDIMIENTO QUE COMPRUEBA SI HA HABIDO NUEVAS PULSACIONES CON LOS BOTONES:
void getButtonPush(char *resultButton, int pin, int pause)
{
int data = analogRead(0);
if (data > 10)
{
if (data > 500 && data < 540)
strcpy(resultButton,"up");
else if (data > 330 && data < 370)
strcpy(resultButton,"left");
else if (data > 240 && data < 280)
strcpy(resultButton,"bottom");
else if (data > 190 && data < 230)
strcpy(resultButton,"right");
delay(pause);
}
}
Esta imagen muestra el funcionamiento correcto de LCD: