#include <Wire.h>
#define trig 22
#define echo 23
bool rw=0; //lcd
bool rs;//lcd
bool LED=1;//lcd
char conf []={3, 3, 3, 2, 2, 8, 0, 14, 0, 1, 0, 6}; //configuración para la lcd
char tiempos []={15, 5, 1, 1, 1, 1, 1, 1};
char msj1[] = {"Distancia "}; //para la lcd
char msj2[] = {"(Medida en Cm) "}; //para lcd
volatile unsigned long tiempoDoble;  // Variable para almacenar el tiempo de vuelo
volatile bool medidaCompletada = false;
byte PCF_addr=0x27; //direccion para la lcd 



void ICACHE_RAM_ATTR echoInterrupt() {
  if (digitalRead(echo) == HIGH) {
    tiempoDoble = micros();  // Almacena el tiempo actual cuando el pin ECHO se vuelve HIGH
  } else {
    tiempoDoble = micros() - tiempoDoble;  // Calcula el tiempo de vuelo
    medidaCompletada = true;
  }
}
//funcion para enviar los nibbles para lcd
  void send_byte(char N){
   byte carac= N >> 4;
   send_Nibble(carac, LED, rw, rs);
   send_Nibble(N, LED, rw, rs);
}
//para la lcd 
  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() {
  Wire.begin(19,18);
  rs=0;
  for(byte i=0; i<=11; i++){   
    delay(tiempos[i]);
    send_Nibble(conf[i],LED,rs,rw);
  }
  //Configuración de mensaje 1 PARA LA LCD
  rs=1;
  for(byte i=0; i<=9; i++){
  send_byte(msj1[i]);
  }
   
   //Configuración de mensaje 2 y posicionar LCD en segunda linea
   rs=0;
  send_byte(0xc0);
  rs=1;
  for(byte i=0; i<=13; i++){
  send_byte(msj2[i]);
  }
  Serial.begin(115200);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  
  attachInterrupt(digitalPinToInterrupt(echo), echoInterrupt, CHANGE);
}

void loop() {
  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);

  medidaCompletada = false;  // Reinicia la bandera de medida

  while (!medidaCompletada) {
    // Espera a que la medida se complete (flag se establezca en la interrupción)
  }

  // Ahora puedes usar 'tiempoDoble' para calcular la distancia
  // ... (resto del código)
  long dist = tiempoDoble / 58.3;
  
  Serial.print("Distancia: ");
  Serial.println(dist);

 char buffer[5];  // Buffer para almacenar la cadena de caracteres
sprintf(buffer, "%ld", dist);  // Convierte el valor de distancia a una cadena de caracteres
rs = 0;
send_byte(0x8A);
rs = 1;
for (byte i = 0; i < 5; i++) {
  send_byte(buffer[i]);
}
  delay(10);
}