Pantalla LCD e interfaz I2C se vuelven locas.

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:

Y en esta comienza a fallar:

Imgur