#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <SoftwareSerial.h>

float MINph=100.,MAXph=200.;
float MINtds=100.,MAXtds=200.;
float MINturb=100.,MAXturb=200.;
float MINlvl=200.,MAXlvl=150.;
int MAXwtr=100,lvl0=300;

//========================================================================================
//||                          CONFIGURATION FOR ULTRASONIC                              ||
//========================================================================================



const int trigpin= 8;
const int echopin= 7;
const int Buzzer= 12;
const int WtrLvlLED=3;
const int TdsLED=4;
const int TurbLED=5;
const int phLED=6;





//========================================================================================
//||                                UART DATA TRANSMISSION                              ||
//========================================================================================

#define rxPin 10
#define txPin 11
SoftwareSerial Arduino_SoftSerial(10,11);//RX TX
int data1,data2,data3,data4;
float data5,data6,data7,data8;
String data9,data10,data11,data12;



long duration;
int distance;
float Percentage;
int del[]={10,50,100,250,500,1000,2000,3000};//Delay array
int i;

//temp variables
float ph=153.78;
float TDS=45.89;
float TURB=134.32;
LiquidCrystal_I2C lcd(0x27, 20, 4);//Declaring LCD address and config
 


//Custom test character
byte test[8] = {
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b11111
  };
//Custom blank character
 byte blank[8] = {
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000
 };



 //========================================================================================
 //||                                    VOID SETUP                                     ||
 //=======================================================================================
void setup() 
{
  Serial.begin(9600);
  pinMode(phLED,OUTPUT);//configuring pin 13
 lcd.backlight();//Turning on backlight
 lcd.init();//Initializing LCD
 
 lcd.createChar(0, test);//Character for test
 lcd.createChar(1, blank);//Character for blanks 
 pinMode(trigpin,OUTPUT);

 pinMode(echopin,INPUT);

 pinMode(Buzzer,OUTPUT);
  
 pinMode(WtrLvlLED,OUTPUT);  

 pinMode(TdsLED,OUTPUT); 

 pinMode(phLED,OUTPUT); 

 pinMode(TurbLED,OUTPUT); 

 pinMode(10, INPUT);

 pinMode(11, OUTPUT);
  
 Arduino_SoftSerial.begin(9600);//Communication with Arduino-NodeMcu
 

  
 //=======================================================================================
 //||                                    TESTING SEQUENCE                               ||
 //=======================================================================================
  lcd.setCursor(0,0);
  lcd.print(F("******WELCOME!******"));
  lcd.setCursor(0,1);
  lcd.print(F("Initialinzing."));
  lcd.setCursor(0,1);
  delay(del[3]);
  lcd.print(F("Initialinzing.."));
  lcd.setCursor(0,1);
  delay(del[3]);
  lcd.setCursor(0,1);
  lcd.print(F("Initialinzing..."));
  delay(del[3]);
  lcd.setCursor(0,1);
  lcd.print(F("Initialinzing...."));
  delay(del[3]);
  lcd.setCursor(0,1);
  lcd.print(F("Initialinzing....."));
  delay(del[3]);
  lcd.setCursor(0,1);
  lcd.print(F("Initialinzing......"));
  delay(del[3]);
  lcd.setCursor(0,1);
  lcd.print(F("Initialinzing......."));
  delay(del[3]);
 
 
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(F("System.Ver1.0"));
  delay(del[5]);
  lcd.clear();
 for(i=0;i<=19;i++)//For loop for LED check
  { lcd.setCursor(0+i, 0);  
    lcd.write(0);
    lcd.setCursor(0+i, 1);
    lcd.write(0);
    lcd.setCursor(0+i, 2);
    lcd.write(0);
    lcd.setCursor(0+i, 3);
    lcd.write(0);
    delay(del[2]);          
  }
  lcd.clear();
  lcd.print(F("LCD OK!"));
  delay(del[4]);
  lcd.clear();
}
 //=======================================================================================
 //||                                    VOID LOOP                                      ||
 //=======================================================================================
void loop()
{
 //=======================================================================================
 //||                                    VOID LOOP                                      ||
 //=======================================================================================

 //=======================================================================================
 //||                                    BUZZER                                         ||
 //=======================================================================================



 if(ph>MAXph||ph<MINph||TDS>MAXtds||TDS<MINtds||TURB>MAXturb||TURB<MINturb||Percentage>99||Percentage<0)
  {
    tone(Buzzer,120);
    delay(del[4]);
    tone(Buzzer,130);
    delay(del[4]);
    tone(Buzzer,210);
    delay(del[4]);
    tone(Buzzer,20000);
    
  }
 




 //=======================================================================================
 //||                         ULTRASONIC CALCULATIONS                                   ||
 //=======================================================================================



 digitalWrite(trigpin,HIGH);

 delayMicroseconds(10);

 digitalWrite(trigpin,LOW);

 duration=pulseIn(echopin,HIGH);

 distance = duration*0.034/2;

 distance=distance+2;//Correction

 int lvl=Percentage;
  
 //=======================================================================================
 //||                                   UART PACKAGES                                   ||
 //=======================================================================================


  data1=45;
  data2=98;
  data3=46;
  data4=67;
  
  data5=12.76544;
  data6=123.1356; 
  data7=1786.154;
  data8=analogRead(A0);
  
  data9="AlfaRomeo8";
  data10="google123";
  data11="youtube456";
  data12="hello r2d2";
  //Making data packets
  Arduino_SoftSerial.print(data1);     Arduino_SoftSerial.print("A");
  Arduino_SoftSerial.print(data2);     Arduino_SoftSerial.print("B");
  Arduino_SoftSerial.print(data3);     Arduino_SoftSerial.print("C");
  Arduino_SoftSerial.print(data4);     Arduino_SoftSerial.print("D");
  Arduino_SoftSerial.print(data5,5);   Arduino_SoftSerial.print("E");
  Arduino_SoftSerial.print(data6,4);   Arduino_SoftSerial.print("F");
  Arduino_SoftSerial.print(data7,3);   Arduino_SoftSerial.print("G");
  Arduino_SoftSerial.print(data8,2);   Arduino_SoftSerial.print("H");
  Arduino_SoftSerial.print(data9);     Arduino_SoftSerial.print("I");
  Arduino_SoftSerial.print(data10);    Arduino_SoftSerial.print("J");
  Arduino_SoftSerial.print(data11);    Arduino_SoftSerial.print("K");
  Arduino_SoftSerial.print(data12);    Arduino_SoftSerial.print("L");
  Arduino_SoftSerial.print("\n");
  delay(del[2]);

 Percentage=distance-MAXwtr;
 Percentage=Percentage/(lvl0-MAXwtr);
 Percentage=Percentage*100;
 Percentage=100-Percentage;
 Serial.println(Percentage);


 //========================================================================================
 //||                                    PH CALCULATIONS                                 ||
 //========================================================================================

  lcd.setCursor(0,0);
  lcd.print(F("pH="));
 
  if (ph<=MAXph&&ph>=MINph)
  {
    lcd.print(ph);
    lcd.setCursor(17,0);
    lcd.print("OK!");
  }
  if (ph>MAXph)
  {
    lcd.setCursor(3,0);
    lcd.print(ph);
    lcd.setCursor(15,0);
    lcd.print(F("HIGH!"));
    digitalWrite(phLED,HIGH);
    delay(del[5]);
    lcd.setCursor(15,0);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    digitalWrite(phLED,LOW);
    delay(del[5]);
  }
  if (ph<MINph)
  {
    lcd.setCursor(3,0);
    lcd.print(ph);
    lcd.setCursor(16,0);
    lcd.print(F("LOW!"));
    digitalWrite(phLED,HIGH);
    delay(del[5]);
    lcd.setCursor(16,0);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    digitalWrite(phLED,LOW);
    delay(del[5]);
  } 
 //=======================================================================================
 //||                                    TDS CALCULATIONS                               ||
 //=======================================================================================
  lcd.setCursor(0,1);
  lcd.print(F("TDS="));
  if (TDS<=MAXtds&&TDS>=MINtds)
  {
    lcd.print(TDS);
    lcd.print(F("mg/L"));
    lcd.setCursor(17,1);
    lcd.print("OK!");
  }
  if (TDS>MAXtds)
  {
    lcd.setCursor(4,1);
    lcd.print(TDS);
    lcd.print(F("mg/L"));
    lcd.setCursor(15,1);
    lcd.print(F("HIGH!"));
    digitalWrite(TdsLED,HIGH);
    delay(del[5]);
    lcd.setCursor(15,1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    digitalWrite(TdsLED,LOW);
    
  }
  if (TDS<MINtds)
  {
    lcd.setCursor(4,1);
    lcd.print(TDS);
    lcd.print(F("mg/L"));
    lcd.setCursor(16,1);
    lcd.print(F("LOW!"));
    digitalWrite(TdsLED,HIGH);
    delay(del[5]);
    lcd.setCursor(16,1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    digitalWrite(TdsLED,LOW);
    delay(del[5]);
    
  } 
 //=========================================================================================
 //||                                  TURBIDITY CALCULATIONS                             ||
 //=========================================================================================
 lcd.setCursor(0,2);
  lcd.print(F("Turb="));
  if (TURB<=MAXturb&&TURB>=MINturb)
  {
    lcd.print(TURB);
    lcd.print(F("NTU"));
    lcd.setCursor(17,2);
    lcd.print("OK!");
  }
  if (TURB>MAXturb)
  {
    lcd.setCursor(5,2);
    lcd.print(TURB);
    lcd.print(F("NTU"));
    lcd.setCursor(15,2);
    lcd.print(F("HIGH!"));
    digitalWrite(TurbLED,HIGH);
    delay(del[5]);
    lcd.setCursor(15,2);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    digitalWrite(TurbLED,LOW);
    delay(del[5]);
  }
  if (TURB<MINturb)
  {
    lcd.setCursor(5,2);
    lcd.print(TURB);
    lcd.print(F("NTU"));
    lcd.setCursor(16,2);
    lcd.print(F("LOW!"));
    digitalWrite(TurbLED,HIGH);
    delay(del[5]);
    lcd.setCursor(16,2);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    digitalWrite(TurbLED,LOW);
    delay(del[5]);
  } 
 //========================================================================================
 //||                                  WTR>LVL CALCULATIONS                               ||
 //=========================================================================================
 
 
  lcd.setCursor(0,3);
  lcd.print(F("Wtr.Lvl="));
  if (lvl<=99&&lvl>=0)
  {
    lcd.print(lvl);
    lcd.print(F("%"));
    lcd.setCursor(17,3);
  }
  if (Percentage>99)
  {
    lcd.setCursor(8,3);
    lcd.print("--");
    lcd.setCursor(14,3);
    lcd.print(F("OvrFlo"));
    digitalWrite(WtrLvlLED,HIGH);
    delay(del[5]);
    lcd.setCursor(14,3);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    digitalWrite(WtrLvlLED,LOW);
    delay(del[5]);
  }
  if (Percentage<0)
  {
    lcd.setCursor(8,3);
    lcd.print("--");
    lcd.setCursor(15,3);
    lcd.print(F("Empty"));
    digitalWrite(WtrLvlLED,HIGH);
    delay(del[5]);
    lcd.setCursor(14,3);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    digitalWrite(WtrLvlLED,LOW);
    delay(del[5]);
  }

  




}