/* CONNECTION INSTRUCTION
  email:[email protected] pass:kist@2024
  V3:NOTIFICATION
  V0:temperature
  V1:flowrate
  V2:VOLUME
  V4:BUTTON
*/


#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "TMPL2NmjFNSZ4"
#define BLYNK_TEMPLATE_NAME "OIL FLOW SYSTEM"
#define BLYNK_AUTH_TOKEN "n3Ou_F5-cb5hien0X39Ws5XycqloEyED"

#define buzzer     13
#define pump       17
#define valve      5
#define trigger    18
#define echoPin       19
#define fr         23

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <HCSR04.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const int oneWireBus = 4; 

char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "TEST";
char pass[] = "test@test";

HCSR04 hc(trigger,echoPin);
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C lcd(0x27, 20, 4);

String notification;
float volume,rate,temperature;
bool State;

long previousMillis = 0;
long pretime=0;
int  interval = 1000;
boolean ledState = LOW;
float calibrationFactor = 4.5;
volatile byte pulseCount;
byte pulse1Sec = 0;
float flowRate;
unsigned long flowMilliLitres;
unsigned int totalMilliLitres;
float flowLitres;
float totalLitres;

void IRAM_ATTR pulseCounter()
{pulseCount++;}

void setup()
{
  lcd.init();
 lcd.backlight();
  loadingdisplay();
  Serial.begin(115200);
  delay(100);
  pinMode(pump,OUTPUT);
  pinMode(valve,OUTPUT);
  pinMode(buzzer,OUTPUT);
  pinMode(fr,INPUT_PULLUP);
  digitalWrite(buzzer,LOW);
  digitalWrite(pump,HIGH);
  digitalWrite(valve,HIGH);
  sensors.begin();
  Blynk.begin(auth, ssid, pass);
  attachInterrupt(digitalPinToInterrupt(fr), pulseCounter, FALLING);
}

void loop()
{
 homedisplay();
 Blynk.run();
 get_data();
 send_update();
 
 if(State)
 {
  if(volume<=75)
  {
   Blynk.virtualWrite(V3,"REFILL STARTED");
   digitalWrite(valve,LOW);
   delay(3000);
   digitalWrite(pump,LOW);
  }
  else
  {
    Blynk.virtualWrite(V3,"THE TANK IS ALMOST FULL");
    digitalWrite(valve,HIGH);
    digitalWrite(pump,HIGH);
  }
 }
 else
 {
    digitalWrite(valve,HIGH);
    digitalWrite(pump,HIGH);
 }
}

BLYNK_WRITE(V4)
{
  int data=param.asInt();
  if(data!= State)
  {
    State=data;
    Serial.println("CHANGE");
  }
}

void get_data() 
{
  //////////////////
  /*
  sensors.requestTemperatures(); 
  temperature = sensors.getTempCByIndex(0);
  Serial.print(temperature);
  Serial.println("ºC"); 
  */
  temperature=map(analogRead(34),0,4034,0,100);
  /////////////////
  volume= map(hc.dist(),0,40,100,0);
  Serial.print(volume);
  Serial.println("%"); 
  //////////////////
  //rate=readVolume();
  rate=map(analogRead(34),0,4034,0,100);
  Serial.print(rate);
  Serial.println("ml/sec"); 
}

unsigned long readVolume()
{
    pulse1Sec= pulseCount;
    pulseCount= 0;
    flowRate = ((1000.0 / (millis() - previousMillis)) * pulse1Sec) / calibrationFactor;  //IN LITRE PER MINUTE
    previousMillis = millis();
    flowMilliLitres = (flowRate / 60) * 1000;    //IN MILILITRE PER SECOND
    return flowMilliLitres;
}


void send_update() 
{     
  Blynk.virtualWrite(V0,temperature);
  Blynk.virtualWrite(V1,rate);
  Blynk.virtualWrite(V2,volume);  
}

void Alert(uint8_t num)
{
  for(num;num>0;num--)
  {
    digitalWrite(buzzer,HIGH);
    delay(500);
    digitalWrite(buzzer,LOW);
    delay(500);
  }
}

void loadingdisplay()
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(" OILFLOW MONITORING "); 
  lcd.setCursor(0,1);
  lcd.print("   SYSTEM VIA IoT   "); 
  lcd.setCursor(0,2);
  lcd.print(" SYSTEM INITIALIZE ");
  lcd.setCursor(0,3);
  lcd.print("PLEASE WAIT");
  for(int k=11;k<20;k++)
  {
    lcd.setCursor(k,3);
    lcd.print(".");
    delay(500);
  }
}

void homedisplay()
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("OIL FLOW MONITORING"); 
  lcd.setCursor(0,1);
  lcd.print("TEMPERATURE:"); 
  lcd.print(temperature);
  lcd.setCursor(0,2);
  lcd.print("VOLUME:");
  lcd.print(volume);
  lcd.setCursor(0,3);
  lcd.print("FLOW RATE:");
  lcd.print(rate);
  delay(1000);
}
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module