/**

HC-SR04 ****************************
●Power Supply: +5V DC
●Quiescent Current: <2mA
●Working current: 15mA
●Effectual Angle: <15º
●Ranging Distance: 24000 cm
●Resolution: 0.3 cm
●Measuring Angle: 30º
●Trigger Input Pulse width: 10uS
●Dimension: 45mm x 20mm x 15mm
●Weight: approx. 10 g
************************************
Referencias: 
https://www.youtube.com/watch?v=4xFY8IEUw9A
https://www.youtube.com/watch?v=2CmdKsf9AUA
https://puntoflotante.net/NODEMCU-ESP8266-ESP-12E-HC-SR04-MEDION-DISTANCIAS-SENSOR-ULTRASONICO.htm
https://pdf1.alldatasheet.com/datasheet-pdf/view/1132203/ETC2/HC-SR04.html
https://www.fvml.com.br/2022/09/sensor-ultrassonico-hc-sr04-esp8266-wemos-d1.html

**/

//Programa: Monitoramento de nivel de reservatorio e estima de volume
//Autor: FRANCISCO RICARDO DOS SANTOS SILVA

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

      /** ------- id e local do dispositivo ------ **/

#define id 123456         // id: para identificação do dispositivo
#define local "-3.717796399281324, -38.518914415736575"  // Ppara identificação do dispositivo

      /** ------- id e local do dispositivo ------ **/

#define SCREEN_WIDTH 128 // OLED display largura, em pixels
#define SCREEN_HEIGHT 64 // OLED display altura, em pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Variaveis do wifi
char nomeWifi[15] = "MeuESP";
char senhaWifi[15] = "123456";

// Definindo os pinos do HC-SR04
#define pin_trig 5
#define pin_echo 4

// Iniciando pinos e porta serial
void setup() {

  pinMode(PIN_AP, INPUT_PULLUP);
  
  Serial.begin(115200);
  pinMode(pin_trig, OUTPUT);
  pinMode(pin_echo, INPUT);
  digitalWrite(pin_trig, LOW);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  /**delay(2000);
  display.clearDisplay();

  //display.setTextSize(1);
  display.setTextColor(WHITE);
  **/
  display.setTextSize(2);
  display.setTextColor(SH110X_WHITE);
  display.setCursor(0, 0);
  display.print("Iniciando ...");
  display.display();

  //WiFiManager, Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wm;

  // reset settings - wipe stored credentials for testing
  // these are stored by the esp library
  // wm.resetSettings();

  // Automatically connect using saved credentials,
  // if connection fails, it starts an access point with the specified name ( "AutoConnectAP"),
  // if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect())
  // then goes into a blocking loop awaiting configuration and will return success result

  if (digitalRead(PIN_AP) == APERTADO) {
    display.clearDisplay();
    display.setTextSize(2);
    display.setCursor(0, 0);
    display.print("Resetando ...");
    display.display();

    wm.resetSettings();
  }
  bool res;
  // res = wm.autoConnect(); // auto generated AP name from chipid
  // res = wm.autoConnect("AutoConnectAP"); // anonymous ap
  wm.setConfigPortalBlocking(false);
  res = wm.autoConnect(nomeWifi, senhaWifi); // password protected ap


  if (!res) {
    Serial.println("Failed to connect");
    // ESP.restart();

    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(SH110X_WHITE);
    display.setCursor(0, 0);
    display.print("FEITO!");
    display.display();
    delay(2000);

    display.clearDisplay();
    display.setCursor(0, 0);
    display.setTextSize(1);
    display.print("WiFi:  ");
    display.println(nomeWifi);
    display.print("Senha: ");
    display.println(senhaWifi);
    display.print("IP:    ");
    display.println(WiFi.softAPIP());
    display.display();
    while (true) {
      wm.process();
    }
  }
  else {
    //if you get here you have connected to the WiFi
    Serial.println("connected...yeey :)");

    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(SH110X_WHITE);
    display.setCursor(0, 0);
    display.println("CONECTADO!");
    display.setTextSize(1);
    display.print("IP: ");
    display.println(WiFi.localIP());
    display.display();
  }

}

// definindo variaves globais
long tempo;
float profun, aux, capTotal, vol, litros, alt, larg, comp;


// funcao de repeticao para coleta de medidas
void loop() {
  Serial.print("id: ");
  Serial.println(id);
  Serial.print("Cordenadas (LT/LG): ");
  Serial.println(local);

  /** --- substituida pela funcao acima usando variaveis ---**/
  // Serial.println("id: 123456"); //id do dispositivo.
  // cordenadas de localização.
  // Serial.println("Cordenadas: -3.717796399281324, -38.518914415736575");

  // medidadas do reservatorio para calculo
  comp = 200.0; //comprimento em cm
  larg = 100.0; //lagura cm
  alt = 400.0;  //profundidade cm

  // calculo da capacidade total 
  capTotal = (comp * larg * alt)/1000; //devemos dividir por mil pois cada litro tem 10x10cm

  /**--------------- Inicio do programa --------------------**/
  digitalWrite(pin_trig, HIGH); // criando o pulso no trig
  delayMicroseconds(10);
  digitalWrite(pin_trig, LOW);

  // Calculo do tempo
  tempo = pulseIn(pin_echo, HIGH ,1000000);
  aux = tempo;
  profun = (aux*340/10000)/2;
  litros = (comp * larg * profun)/1000;

  // Calculo de volume disponivel
  vol = (capTotal - litros);

  //informacoes para serem mostradas.
  Serial.print("Profundidade: ");
  Serial.print(profun/100);
  Serial.println(" metros");

  Serial.print("Capacidade: ");
  Serial.print(capTotal);
  Serial.println(" litros");
  
  Serial.print("Vol. disponivel: ");
  Serial.print(vol);
  Serial.println(" litros");
  Serial.println("****************************" );

  // Informacoes de exibicao do display
  display.clearDisplay();
  display.setCursor(0, 4);
  display.setTextSize(2);
  display.println("Capacidade");
  display.setTextSize(1);
  display.println("--------------");
  display.setTextSize(2);
  display.println(capTotal);
  display.setTextSize(1);
  display.println("Litros");
  display.println("--------------");
  delay(5000);
  display.display();

  display.clearDisplay();
  display.setCursor(0, 4);
  display.setTextSize(2);
  display.println("Disponivel");
  display.setTextSize(1);
  display.println("--------------");
  display.setTextSize(2);
  display.println(vol);
  display.setTextSize(1);
  display.println("Litros");
  display.println("--------------");
  delay(3000);
  display.display();

  //delay(4000);
}