/*
Created: 03-Dec-24 7:11:45 PM
*
Author : Mostafa Salem
*/
#include <Ultrasonic.h> // The ultrasonic library for converting the signal from sensor to a distance directly
#include <LCD-I2C.h> // library for interfacing LCD I2C module to the arduino
#include <math.h> // math library for interfacing arithmetic equations that included within the code
LCD_I2C lcd(0x27,16,2);
Ultrasonic ultrasonic(12, 13);
int Relaypin=6;
float distance;
float h;
float HPressure; // hydrostatic pressure
float pi=3.14159265359; // Pi constant
int roah=1000; // water density in kg/m^3 --> 1 m^3 = 1000L
float g=9.81; // gravitational acceleration in kg*m/s^2
float epsilon = 0.0000015; // ε is the pipe's effective roughness
float D = 0.0127; // Pipe diameter in meters
float L = 0.82; // Pipe Length in meters
float meu=0.001; // dynamic viscosity
float Re; // Reynold's number
float V; // Fluid velocity
float pressure; // Fluid pressure
float A=(pi * pow(D / 2, 2)); // Pipe crossectional Area
float ffactor; // Darcy friction factor
#define FlowMeterfactor 21.5472//22.445//14.33 // Flow meter sensor calibration factor
byte sensorInterrupt = 0;
float FlowCalcDuration =1000;
float FlowCalcStartTime;
volatile float PulseCount;
float LPM;
int LPMdecimal;
void pulseCounter() // Interrupt function
{
PulseCount++;
}
void setup()
{
Serial.begin(9600);
Wire.begin();
lcd.begin(&Wire);
lcd.display();
lcd.backlight();
lcd.print("***feel*********");
lcd.setCursor(0, 1);
lcd.print("********alive***");
delay(2000);
lcd.clear();
pinMode(6, OUTPUT);
PulseCount=0;
LPM=0;
LPMdecimal=2;
attachInterrupt(sensorInterrupt,pulseCounter,FALLING);
FlowCalcStartTime=millis();
}
void loop()
{
distance = ultrasonic.read(); // The read value from Ultrasonic sensor
h= 31-distance; // Hight of the fluid in the tank
HPressure = roah*g*(h/100); // hydrostatic pressure equation
Serial.print("Q= ");
Serial.println(LPM/*0.001/60.0*/);
Serial.print("P= ");
Serial.println(pressure);
delay(1000);
V=(LPM*0.001 / 60.0)/A; // calculating fluid velocity --> Q = V/A
Re=(roah * V * D) / (pi * meu); // calculating Reynold's number --> Re = ρ*V / pi*D*μ
if (Re>=4000) { // if the Reynold's number is indecating turbulent flow
float term1 = epsilon / (3.7 * D);
float term2 = 5.74 / pow(Re, 0.9);
float denominator = log10(term1 + term2);
ffactor = 0.25 / pow(denominator, 2); // calculating Darcy friction factor by Swamee–Jain equation
}
else if (Re<4000){ // else if the Reynold's number is indecating laminar flow
ffactor= 64/Re ; // calculating Darcy friction factor by the following equation
}
pressure = ffactor * (L / D) * (pow(V,2) / 2 * g) * roah * g; // calculating the pressure from the energy equation
lcd.setCursor(0, 0);
lcd.print("h=");
lcd.print(h);
lcd.print(" cm");
lcd.setCursor(0, 1);
lcd.print("P=");
lcd.print(HPressure/1000 +101.33);
lcd.print(" KPa");
delay(2000);
CalculateFlow();
if( h >= 11 ){
digitalWrite(Relaypin,LOW); //if the distance between the fluid and the ultrasonic sensor is less than or equal to 11cm shutdown the pump
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("******PUMP******");
lcd.setCursor(0, 1);
lcd.print("*******OFF******");
delay(1000);
lcd.clear();
}
else{ //if the distance between the fluid and the ultrasonic sensor is more than 11cm open the pump
digitalWrite(Relaypin,HIGH);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("******PUMP******");
lcd.setCursor(0, 1);
lcd.print("*******ON******");
delay(1000);
lcd.clear();
}
}
void CalculateFlow() // the function that calculate flow rate by deviding the freqency of pulses by the calibration factor
{
if(millis()-FlowCalcStartTime > FlowCalcDuration)
{
LPM = PulseCount/(FlowMeterfactor*(FlowCalcDuration/1000));
DisplayLPM();
FlowCalcStartTime = millis();
PulseCount=0;
}
}
void DisplayLPM() // the function that display the flow rate and pressure of the fluid on the LCD
{
lcd.setCursor(0, 0);
lcd.print("Q=");
lcd.print(LPM,LPMdecimal);
lcd.print(" L/M");
lcd.setCursor(0, 1);
lcd.print("P12=");
lcd.print(pressure/1000);
lcd.print(" KPa ");
delay(2000);
}