//#include <ESP8266WiFi.h>

//#include <ESP8266WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Definindo os pinos do sensor de ultrassom
const int TRIGGER_PIN = 16; // Pino de trigger do sensor AJ-SR04M esp8266 (D3)
const int ECHO_PIN = 17;    // Pino de echo do sensor AJ-SR04M esp8266 (D4)
const int REGISTRO = 4;     // Pino de acionamento Relé esp8266 (D5)

char* LargeText = "Deus seja louvado                 "; // Texto a ser exibido no LCD
int iLineNumber = 0;    // Delay entre rolagens, em milissegundos
int iCursor = 0;        // Largura do display LCD

// Inicializando o display LCD 16x2 com o endereço I2C 0x27
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  Serial.begin(115200);
  pinMode(TRIGGER_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(REGISTRO, OUTPUT);
  Wire.begin(21, 22);

  // Inicializa o LCD
  lcd.init();
  lcd.backlight();
  lcd.clear();

  // Executa a função UpdateLCDDisplay repetidamente no setup para simular a rolagem do texto
  for (int i = 0; i < strlen(LargeText); i++) {
    UpdateLCDDisplay(i);
    delay(300);
  }

  // Mensagem de inicialização
  lcd.setCursor(0, 0);
  lcd.print(" Inicializando.. ");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Nivel de agua: ");
}

void UpdateLCDDisplay(int startIndex) {
  // Limpa o display
  lcd.clear();

  // Define o cursor na primeira linha do LCD
  lcd.setCursor(0, iLineNumber);

  // Exibe o texto a partir do índice inicial
  for (int iChar = startIndex; iChar < startIndex + 16; iChar++) {
    lcd.print(LargeText[iChar % strlen(LargeText)]);
  }
}

void loop() {
  long duration, distance;

  // Gera um pulso no pino TRIGGER
  digitalWrite(TRIGGER_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGER_PIN, LOW);

  // Calcula o tempo de duração do eco
  duration = pulseIn(ECHO_PIN, HIGH);
  distance = duration * 0.034 / 2;

  // Ajuste a altura do recipiente onde o sensor está instalado
  // e o intervalo de leitura (máximo e mínimo) para o cálculo do nível de água
  int maxDistance = 72; // Distância máxima (em cm) do sensor até a superfície da água
  int minDistance = 22; // Distância mínima (em cm) do sensor até a superfície da água

  // Mapeia a distância medida para um valor percentual do nível de água
  int waterLevelPercent = map(distance, maxDistance, minDistance, 0, 100);
  waterLevelPercent = constrain(waterLevelPercent, 0, 100); // Garante que o valor percentual esteja dentro do intervalo de 0 a 100

  // Limpa o display e exibe o nível de água
  lcd.setCursor(6, 1);
  lcd.print(waterLevelPercent);
  lcd.print("%");
  lcd.print("  ");
  
  Serial.print("Nivel de agua: ");
  Serial.print(waterLevelPercent);
  Serial.println("%");

  // Controle do registro
  if (waterLevelPercent <= 15) {
    digitalWrite(REGISTRO, HIGH); // Liga o registro
  } else if (waterLevelPercent >= 100) {
    digitalWrite(REGISTRO, LOW); // Desliga o registro
  }

  delay(1000);
}