#include <EEPROM.h>
#include <Wire.h>
const int EEPROM_SIZE = 5; // Tamaño de la memoria EEPROM para almacenar la contraseña (incluyendo el carácter nulo al final)
char dataToWrite[EEPROM_SIZE]= "1234";
bool passwordChanged = false; //mi banderota
int minumero, attempts=0;
int numerosecreto = 1234;
String datos;
#define ledexterno 19
int contador=0;
int contador1=0;
#define cerradura 2
int tecla2=0; 
int blocked = 5;
int puntis = 1;
int ren[] = {27, 14, 12, 13}; // Pines para los renglones
int colum[] = {32, 33, 25, 26}; // Pines para las columnas
 
byte johnson;
byte tecla;
byte col = 0x0F;
byte PCF_addr = 0x27; // Dirección para la LCD
byte uni = 0;
byte dec = 0;
byte cen = 0;
byte miles= 0;
int boton;
bool teclaActiva = 0;
bool rw = 0; // LCD
bool rs;      // LCD
bool LED = 1; // LCD
char conf[] = {3, 3, 3, 2, 2, 8, 0, 14, 0, 0x0F, 1, 0, 6}; // Configuración para la LCD
char tiempos[] = {15, 5, 1, 1, 1, 1, 1, 1};
char msj1[] = {"clave: "}; // Para la LCD
char msj2[] = {"BIENVENIDO "}; // Para LCD
char msj3[] = {"Ingrese su "};
char msj4[]= {"Puerta abierta "};
char msj5[]= {"codigo erroneo "};
char msj6[]={"BLOQUEADO " };
char msj7[]={"Entre "};
char msj8[]={"Cerrando puerta "};
char msj10[]={"Ingresa la "};
char msj11[]={"nueva clave "};
char msj12[]={"Actualizada "};
//nuevo
char msj13[]={"Pulse * para "};
char msj14[]={"Instrucciones "};
char msj15[]={"Tecla A para "};
char msj16[]={"Abrir puerta"};
char msj17[]={"Tecla B para "};
char msj18[]={"Cambiar Clave "};
char msj19[]={"Tecla C para "};
char msj20[]={"Borrar "};
char msj21[]={"Tecla D para "};
char msj22[]={"Cerrar puerta "};
char msj23[]= {"Codigo Erroneo "};

 hw_timer_t *timer = NULL; // Inicializador del timer para el contador Johnson

void cnt_johnson() {
  col = (digitalRead(colum[3]) << 3) | (digitalRead(colum[2]) << 2) | (digitalRead(colum[1]) << 1) | digitalRead(colum[0]);

  if (col == 0x0F) {
    byte m, j, i;
    teclaActiva = 0;
    johnson = (johnson << 1) | 0x01;
    // Regresar el contador Johnson a su valor inicial
    if (johnson == 0xEF)
      johnson = 0xFE;
    m = 3;
    for (i = 0; i <= 3; i++) {
      j = pow(2, m);
      digitalWrite(ren[i], (johnson & j));
      m--;
    }
  }
}

void send_byte(char N) {
  byte carac = N >> 4;
  send_Nibble(carac, LED, rw, rs);
  send_Nibble(N, LED, rw, rs);
}

void send_Nibble(byte N, byte L, byte W, byte S) {
  byte dato = (N << 4) | (L << 3) | 0x04 | (W << 2) | S;
  Wire.beginTransmission(PCF_addr);
  Wire.write(dato);
  Wire.endTransmission();
  delay(10);

  dato = dato & 0xFB;
  Wire.beginTransmission(PCF_addr);
  Wire.write(dato);
  Wire.endTransmission();
}

void setup() {
  Serial.begin(9600);
   pinMode(cerradura, OUTPUT); // Configura el pin del LED como salida
    pinMode(ledexterno, OUTPUT); // Configura el pin del LED como salida
     
  for (byte i = 0; i <= 3; i++) {
    pinMode(ren[i], OUTPUT);
    pinMode(colum[i], INPUT_PULLUP);
  }

  johnson = 0xFE;
  timer = timerBegin(0, 80, true);
  timerAttachInterrupt(timer, cnt_johnson, true);
  timerAlarmWrite(timer, 20000, true);
  timerAlarmEnable(timer);

  Wire.begin();
  rs = 0;
  for (byte i = 0; i <= 11; i++) {
    delay(tiempos[i]);
    send_Nibble(conf[i], LED, rs, rw);
  }
  //incializar la memoria flash 
  EEPROM.begin(EEPROM_SIZE);
  //escribir en la memoria flash-----------------
  Serial.println("escribiendo en la memoria flash");
  
  for (int i = 0; i < EEPROM_SIZE; ++i) {
    EEPROM.write(i, dataToWrite[i]);
  }
  EEPROM.commit(); // Guardar los datos en la EEPROM

  Serial.println("Datos escritos en la EEPROM.");
  Serial.println("la contrasena predefinida es:");
   for (int i = 0; i < EEPROM_SIZE; ++i) {
    dataToWrite[i] = EEPROM.read(i);
    Serial.print(dataToWrite[i]);
  }
  //----------------------------------------------
send_byte (0x01);
send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 10; i++) {
    send_byte(msj2[i]);
  }
  rs=0;
send_byte(0xc0);
  points(puntis);
  rs = 0;
  send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 11; i++) {
    send_byte(msj13[i]);
  }
  rs=0;
  send_byte(0xc0);
  rs = 1;
  for (byte i = 0; i <= 12; i++) {
    send_byte(msj14[i]);
  }
delay(1000); 
rs=0;
  send_byte(0xc0);
  rs = 1;
  for (byte i = 0; i <= 15; i++) {
    send_byte(0x20);
  }
  rs=0;
              send_byte(0x80);
              rs=1;
                for (byte i = 0; i <= 10; i++) {
                send_byte(msj3[i]);
                                 }

                            rs = 1;
                   for (byte i = 0; i <= 6; i++) {
                   send_byte(msj1[i]);
                     }
  rs=0;
  send_byte(0xc0);
}
 // Funcion para mostrar caracteres en vez de delays feos...
void points(int cantidad) {
  char punticos[] = {". . . "};
  char renglones[]= {"- - -"};
  for (int i = 0; i < cantidad; i++) {
    rs = 1;
    for (byte j = 0; j <= 5; j++) {
      send_byte(punticos[j]);
      delay(400);
    }
    delay(10);
    rs = 0;
    //send_byte(0x01);//borrar todo
    delay(1);
    send_byte(0xc0);//primera linea 
    rs=1;
    for (byte j = 0; j <= 4; j++) {
      send_byte(renglones[j]);
      delay(400);
    }
    rs=0;
    send_byte(0x01); //borrar todo.
  }
}

void loop() {
  if (col != 0x0f) {// Verifica si la variable col no es igual a 0x0f (15 en decimal). 
    if (teclaActiva == 0) { //Verifica si la variable teclaActiva es igual a 0.
      teclaActiva = 1;
      byte rengcol = (johnson << 4) | col;
      switch (rengcol) { //inicializar los casos
    
        case 0b11101110: // La letra A funciona como nuestro botón de enter
        char buffer[5];//almacenar en buffer
          boton= (miles*1000)+(cen*100)+(dec*10)+uni; //alamcenar en boton los valores en el teclado
          itoa(boton,buffer,10); //convertir de entero a caracteres...
              Serial.print("La contrasena escrita es:");
              Serial.println(boton);
            if (strcmp(buffer,dataToWrite) ==0 ) { // si la contrasena es igual a la ya registrada entonces iniciar el proceso
              attempts = 0; //reiniciar el contador del bloqueo
    
              rs = 0;
              send_byte(0x01); // Borrar todo
              send_byte(0x80); // Posicionarse en el primer renglón, primera línea
              rs = 1;
              //mostrar mensajesss
              for (byte i = 0; i <= 14; i++) {
                send_byte(msj4[i]);
                delay(10);
              }
              delay(3000);
              rs = 0;
              send_byte(0x01); // Borrar todo
              send_byte(0x80); // Posicionarse en el primer renglón, primera línea
              rs=1;
                for (byte i = 0; i <= 5; i++) {
                send_byte(msj7[i]);
                delay(1);
              }
               delay(3000);
                
              
              digitalWrite(cerradura, LOW);
             
                    rs = 0;
              send_byte(0x80);
                rs = 1;
                for (byte i = 0; i <= 10; i++) {
                send_byte(msj3[i]);
                                 }
                    rs = 0;
              send_byte(0xc6);
                            rs = 1;
                   for (byte i = 0; i <= 6; i++) {
                   send_byte(msj1[i]);
                     }
                  rs=0;
                 send_byte(0xc0);
                 rs = 1;
                for (byte i = 0; i <= 15; i++) {
                  send_byte(0x20);
                  delay(10);
                  
                }
                
                rs = 0;
              send_byte(0xc6);
               rs = 1;
                   for (byte i = 0; i <= 6; i++) {
                   send_byte(msj1[i]);
                     }
                     rs = 0;
                 send_byte(0xc0); //enviar cursor al segundo renglon...
                 //reinciar valores en el teclado....
                 miles=0;
                 cen=0;
                 dec=0;
                 uni=0;
               
            }
            // si la contrasena no coincide con la actual, entonces se inicia 
             else {
              Serial.println("ADVERTENCIA, ATTEMPT HA AUMENTADO");
              Serial.println(attempts);
              digitalWrite(ledexterno,HIGH);
              delay(100);
              digitalWrite(ledexterno,LOW);
              
              attempts++; // aumentar contador de bloqueos
              if (attempts == 3) { // si el contador de bloqueos llega a 3, incia el proceso de bloqueo...
              Serial.println("FUISTE BLOCKEADO POR 10 SEG...");
                rs = 0;
                send_byte(0xC0);
                //mostrando mensjaes y moviendo cursor...
                rs = 0;
                send_byte(0x80);
                rs = 1;
                for (byte i = 0; i <= 15; i++) {
                  send_byte(0x20);
                  delay(70);
                }
                rs=0;
                 send_byte(0xC0);
                 rs=1;
                 for (byte i = 0; i <= 15; i++) {
                  send_byte(0x20);
                  delay(60);
                }
                rs = 0;
                send_byte(0x80);
                rs=1;
                for (byte i = 0; i <= 9; i++) {
                  send_byte(msj6[i]);
                }
                delay(1000);
                  rs=0;
                  send_byte(0x01);
                 send_byte(0x80);
                  points(blocked); // Llama a la función de animación con los caracteres y una duración de 10 segundos
                attempts = 0;
                        rs = 0;
              send_byte(0x80);
                rs = 1;
                for (byte i = 0; i <= 10; i++) {
                send_byte(msj3[i]);
                                 }
                rs = 0;
              send_byte(0xc6);
                            rs = 1;
                   for (byte i = 0; i <= 6; i++) {
                   send_byte(msj1[i]);
                     }
                  rs=0;
                 send_byte(0xc0);
                 //reinciciar los valores 
                 miles=0;
                 cen=0;
                 dec=0;
                 uni=0;
                
              } else {rs = 0;
               digitalWrite(ledexterno,HIGH);
              delay(100);
              digitalWrite(ledexterno,LOW);
              // realizar barrido para que se vea cool...
                send_byte(0xC0);
                rs = 1;
                for (byte i = 0; i <= 15; i++) {
                  send_byte(0x20);
                  delay(10);
                  
                }
                //reposicionar y mostrar mensajes...
                rs=0;
                send_byte(0xC0);
                rs=1;
                for (byte i = 0; i <= 14; i++) {
                  send_byte(msj5[i]);
                  delay(350);
                }
                 rs = 0;
                 
                send_byte(0x80);
                rs=1;
                for (byte i = 0; i <= 15; i++) {
                  send_byte(0x20);
                  delay(10);
                  
                }
                rs = 0;
                 
                send_byte(0xC0);
                rs = 1;
                for (byte i = 0; i <= 15; i++) {
                  send_byte(0x20);
                  delay(10);
                  
                }
                         rs = 0;
              rs = 0;  
              send_byte(0x80);
              rs=1;
                for (byte i = 0; i <= 10; i++) {
                send_byte(msj3[i]);
                                 }

                            rs = 1;
                   for (byte i = 0; i <= 6; i++) {
                   send_byte(msj1[i]);
                     }
             //reinciar los valores.
                   
                miles=0;
                 cen=0;
                 dec=0;
                 uni=0;
                 //reposicionar cursor en la seg. linea
                rs = 0;
                send_byte(0xC0);
                
              }
            }
          
          break;

        case 0b11101101: // Número 3
          miles= cen;
          cen = dec;
          dec = uni;
          uni = 0x03;
          break;

        case 0b11101011: // Número 2
        miles = cen;
          cen = dec;
          dec = uni;
          uni = 0x02;
          break;

        case 0b11100111: // Número 1
         miles = cen;
          cen = dec;
          dec = uni;
          uni = 0x01;
          break;

        case 0b11011110: // Letra B
          tecla2  = tecla2 +1; //aumentar contador de eventos en 1 si la tecla B es presionada
           char buffer2[5]; // declarar arreglo de caracteres ....
          boton= (miles*1000)+(cen*100)+(dec*10)+uni; // volver a adquirir las variables en un solo integer.//
          itoa(boton,buffer2,10); //convertir de integer a caracteres y almacenarlos en buffer
              Serial.print("La contrasena escrita es:");
              Serial.println(boton);
            if (strcmp(buffer2,dataToWrite) ==0 ) { // si la buffer es igual a la contrasena actual, se inicia el evento de cambio de contrasena
               passwordChanged = true;// bandera 
               digitalWrite(cerradura, HIGH);
              delay(500);
              digitalWrite(cerradura, LOW);
              rs = 0;
              send_byte(0x01); // Borrar todo
              send_byte(0x80); // Posicionarse en el primer renglón, primera línea
              rs=1;
                for (byte i = 0; i <= 10; i++) {
                send_byte(msj10[i]);
                delay(1);
              }
              rs = 0;
              send_byte(0xc0);
              rs=1;
                for (byte i = 0; i <= 11; i++) {
                send_byte(msj11[i]);
                delay(1);
              }
              delay(3000);
               
              rs = 0;
              send_byte(0x01); // Borrar todo
              send_byte(0x80); // Posicionarse en el primer renglón, primera línea
              rs=1;
              for (byte i = 0; i <= 11; i++) {
                send_byte(msj11[i]);
                delay(1);}
               
            }
             
       
       Serial.println(passwordChanged);
       
         Serial.println(tecla2);
        

if ( tecla2 >= 3 && passwordChanged == true) { //verificar que los eventos hayan ocurrido para empezar con el cambio de contreasena
  Serial.println(contador);
         Serial.println(passwordChanged);
       tecla2 =0;
       passwordChanged = false;
 //reiniciar contador de eventos
  
  char buffer3[6]; // Tamaño 6 para incluir el carácter nulo '\0'
  
  itoa(boton, buffer3, 10);

  // Copiar cada carácter del buffer3 a dataToWrite
  for (int i = 0; i < EEPROM_SIZE; ++i) {
    dataToWrite[i] = buffer3[i];
  }
  
  // Escribir los datos en la EEPROM
  for (int i = 0; i < EEPROM_SIZE; ++i) {
    EEPROM.write(i, dataToWrite[i]);
  }

  EEPROM.write(EEPROM_SIZE, '\0'); // Escribir el carácter nulo al final de la cadena
  EEPROM.commit();

  Serial.print("Tu nueva contrasena es: ");
  for (int i = 0; i < EEPROM_SIZE; ++i) {
    dataToWrite[i] = EEPROM.read(i); // leer de localidad a localidad de memoria el contenido de esta
    Serial.print(dataToWrite[i]); // imprimir en serial la nueva contrasena
  }
  //reposcicionar cursor y enviar mensajes...
  rs=0;
  send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 6; i++) {
    send_byte(msj1[i]);
  }
  rs=0;
  send_byte(0x85);
  rs = 1;
  for (byte i = 0; i <= 12; i++) {
    send_byte(msj12[i]);
  }      rs = 0;
   
    send_byte(0x80);
     rs = 1;
     for (byte i = 0; i <= 15; i++) {
      send_byte(0x20);  }
             rs = 0;  
              send_byte(0x80);
              rs=1;
                for (byte i = 0; i <= 10; i++) {
                send_byte(msj3[i]);
                                 }

                            rs = 1;
                   for (byte i = 0; i <= 6; i++) {
                   send_byte(msj1[i]);
                     }
  rs=0;
  send_byte(0xc0);
  passwordChanged = false;
  attempts=0;
} 
if (strcmp(buffer2, dataToWrite) != 0) { // si el buffer es dif a la contrasena actual entonces inciar con los eventos..

              attempts++;
              tecla2=0;
              Serial.println("ADVERTENCIA, ATTEMPT A AUMENTADO");
              digitalWrite(ledexterno,HIGH);
              delay(100);
             digitalWrite(ledexterno,LOW);
              
              if (attempts == 3) {
                Serial.println("FUISTE BLOCKEADO POR 10 SEG...");
                rs = 0;
                send_byte(0xC0);
                rs = 1;
                for (byte i = 0; i <= 9; i++) {
                  send_byte(msj6[i]);
                }
                delay(1000);
                  rs=0;
                  send_byte(0x01);
                 send_byte(0x80);
                  points(blocked); // Llama a la función de animación con los caracteres y una duración de 10 segundos
                attempts = 0;
                        rs = 0;
              send_byte(0x80);
                rs = 1;
                for (byte i = 0; i <= 10; i++) {
                send_byte(msj3[i]);
                                 }

                            rs = 1;
                   for (byte i = 0; i <= 6; i++) {
                   send_byte(msj1[i]);
                     }
                  rs=0;
                 send_byte(0xc0);
                 miles=0;
                 cen=0;
                 dec=0;
                 uni=0;
                
              } else {
                 digitalWrite(ledexterno,HIGH);
              delay(100);
              digitalWrite(ledexterno,LOW);
              rs = 0;
                send_byte(0xC0);
                rs = 1;
                for (byte i = 0; i <= 15; i++) {
                  send_byte(0x20);
                  delay(10);
                  
                }
                rs=0;
                send_byte(0xC0);
                rs=1;
                for (byte i = 0; i <= 14; i++) {
                  send_byte(msj5[i]);
                  delay(350);
                }
                 rs = 0;  
              send_byte(0x80);
              rs=1;
                for (byte i = 0; i <= 10; i++) {
                send_byte(msj3[i]);
                                 }

                            rs = 1;
                   for (byte i = 0; i <= 6; i++) {
                   send_byte(msj1[i]);
                     }
                     rs = 0;
                send_byte(0xC0);
                rs = 1;
                for (byte i = 0; i <= 15; i++) {
                  send_byte(0x20);
                  delay(1);
                  
                }
                miles=0;
                 cen=0;
                 dec=0;
                 uni=0;
                rs = 0;
                send_byte(0xC0);
                
              }
            }
          tecla2 = tecla2+1;

 
          break;

        case 0b11011101: // Número 6
         miles = cen;
          cen = dec;
          dec = uni;
          uni = 0x06;
          break;

        case 0b11011011: // Número 5
         miles = cen;
          cen = dec;
          dec = uni;
          uni = 0x05;
          break;

        case 0b11010111: // Número 4
         miles = cen;
          cen = dec;
          dec = uni;
          uni = 0x04;
          break;

        case 0b10111110: // Tecla C para borrar datos
         miles = 0;
          cen = 0;
          dec = 0;
          uni = 0;
          break;

        case 0b10111101: // Número 9
         miles = cen;
          cen = dec;
          dec = uni;
          uni = 0x09;
          break;

        case 0b10111011: // Número 8
         miles = cen;
          cen = dec;
          dec = uni;
          uni = 0x08;
          break;

        case 0b10110111: // Número 7
         miles = cen;
          cen = dec;
          dec = uni;
          uni = 0x07;
          break;

        case 0b01111110: // Letra D
          tecla = 0x0D;
          char buffer4[5]; // declarar arreglo de caracteres ....
          boton= (miles*1000)+(cen*100)+(dec*10)+uni; // volver a adquirir las variables en un solo integer.//
          Serial.println(boton);
          itoa(boton,buffer4,10); //convertir de integer a caracteres y almacenarlos en buffer
              Serial.print("La contrasena escrita es:");
              Serial.println(boton);
            if (strcmp(buffer4,dataToWrite) ==0 ) { // si la
          rs = 0;
              send_byte(0xc0);
              rs=1;
                for (byte i = 0; i <= 15; i++) {
                send_byte(msj8[i]);
                delay(200);
              }
               rs = 0;
              send_byte(0xc0);
              rs=1;
                for (byte i = 0; i <= 15; i++) {
                send_byte(0x20);
                delay(200);}
                rs = 0;  
              send_byte(0x80);
              rs=1;
                for (byte i = 0; i <= 10; i++) {
                send_byte(msj3[i]);
                                 }

                            rs = 1;
                   for (byte i = 0; i <= 6; i++) {
                   send_byte(msj1[i]);
                     }
                     delay(1000);
                      rs = 0;
              send_byte(0xc0);
             
              }
            
            else{
               rs = 0;
              send_byte(0xc0);
              rs=1;
                for (byte i = 0; i <= 13; i++) {
                send_byte(msj23[i]);
                delay(200);
            }
             rs = 0;
              send_byte(0xc0);
              rs=1;
                for (byte i = 0; i <= 14; i++) {
                send_byte(0x20);
                delay(200);
                 }
                 rs = 0;  
              send_byte(0x80);
              rs=1;
                for (byte i = 0; i <= 10; i++) {
                send_byte(msj3[i]);
                                 }

                            rs = 1;
                   for (byte i = 0; i <= 6; i++) {
                   send_byte(msj1[i]);
                     }
                     miles=0;
                     cen=0;
                     dec=0;
                     uni=0;
            }
          break;

        case 0b01111101: // Símbolo #
          tecla = 0x0F;
          break;

        case 0b01111011: // Número 0
         miles = cen;
          cen = dec;
          dec = uni;
          uni = 0x00;
          break;

        case 0b01110111: // Símbolo *
          tecla = 0x0E;
          rs=0;
send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 15; i++) {
    send_byte(0x20);
  }
   
  rs = 0;
  send_byte(0xc0);
  rs = 1;
  for (byte i = 0; i <= 15; i++) {
    send_byte(0x20);
  }
   
          rs=0;
send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 12; i++) {
    send_byte(msj15[i]);
  }
   
  rs = 0;
  send_byte(0xc0);
  rs = 1;
  for (byte i = 0; i <= 11; i++) {
    send_byte(msj16[i]);
  }
  delay(1000);
       rs=0;
send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 15; i++) {
    send_byte(0x20);
  }
   
  rs = 0;
  send_byte(0xc0);
  rs = 1;
  for (byte i = 0; i <= 15; i++) {
    send_byte(0x20);
  }
   
  rs=0;
  send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 12; i++) {
    send_byte(msj17[i]);
  }

rs=0;
  send_byte(0xc0);
  rs = 1;
  for (byte i = 0; i <= 13; i++) {
    send_byte(msj18[i]);
  }
  delay(1000);
       rs=0;
send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 15; i++) {
    send_byte(0x20);
  }
   
  rs = 0;
  send_byte(0xc0);
  rs = 1;
  for (byte i = 0; i <= 15; i++) {
    send_byte(0x20);
  }
   
   rs=0;
send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 12; i++) {
    send_byte(msj19[i]);
  }
   
  rs = 0;
  send_byte(0xc0);
  rs = 1;
  for (byte i = 0; i <= 6; i++) {
    send_byte(msj20[i]);
  }
  delay(1000);
       rs=0;
send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 15; i++) {
    send_byte(0x20);
  }
   
  rs = 0;
  send_byte(0xc0);
  rs = 1;
  for (byte i = 0; i <= 15; i++) {
    send_byte(0x20);
  }
   
  rs=0;
send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 12; i++) {
    send_byte(msj21[i]);
  }
   
  rs = 0;
  send_byte(0xc0);
  rs = 1;
  for (byte i = 0; i <= 13; i++) {
    send_byte(msj22[i]);
  }
  delay(1000);
       rs=0;
send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 15; i++) {
    send_byte(0x20);
  }
   
  rs = 0;
  send_byte(0xc0);
  rs = 1;
  for (byte i = 0; i <= 15; i++) {
    send_byte(0x20);
  }
   rs=0;
  send_byte(0xc0);
  rs = 1;
  for (byte i = 0; i <= 15; i++) {
    send_byte(0x20);
  }
  rs = 0;
  send_byte(0x80);
  rs = 1;
  for (byte i = 0; i <= 10; i++) {
    send_byte(msj3[i]);
  }

  rs = 1;
  for (byte i = 0; i <= 6; i++) {
    send_byte(msj1[i]);
  }
          break;
      }
    }
  }
  rs = 0; // para enviar codigos de instrucciones.
  send_byte(0xc0);  // enviar cursor al primer rengflon
  rs = 1; // para enviar mensajes
  if (miles == 0) {
  send_byte(0x20); // Si el valor de miles es 0, enviar un espacio en blanco
} else {
  send_byte(0x30 | miles); // Si miles no es 0, enviar el valor de miles como un carácter ASCII
}
if(miles==0 & cen==0){
  send_byte(0x20);

}
else{
  send_byte(0x30|cen);
}
if (cen == 0 && dec == 0) {
  send_byte(0x20); // Si centenas y decenas son 0, enviar un espacio en blanco
} else {
 
  send_byte(0x30 | dec); // Enviar el valor de decenas como un carácter ASCII
}

send_byte(0x30 | uni); // Enviar el valor de unidades como un carácter ASCII
 
  
}
 



void animacionLCD(const char* caracteres, int duracionSegundos) {
  unsigned long tiempoInicio = millis(); // Obtiene el tiempo actual en milisegundos
  unsigned long duracionMillis = duracionSegundos * 1000; // Convierte la duración de segundos a milisegundos
  int numCaracteres = strlen(caracteres); // Obtiene la longitud de la cadena de caracteres

  while (millis() - tiempoInicio < duracionMillis) {
    for (int i = 0; i < numCaracteres; ++i) {
      rs = 0;
      send_byte(0x01); // Limpiar la pantalla LCD
      send_byte(0x80); // Establecer la posición del cursor en la primera fila
      rs = 1;
      send_byte(caracteres[i]); // Imprimir el carácter en la LCD
      delay(500); // Pausa de 0.5 segundos entre cada carácter
    }
  }
}