#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
const int trigPin = 8;
const int echoPin = 7;
const int buzzer = 9;
const int relay = 6;
const int manualStartPB = 5;
const int manualStopPB = 4;
String stat;
int waterLevelPercentage;
void setup() {
//Start of the Serial Monitor
Serial.begin(9600);
//for LCD intialization
lcd.init();
lcd.backlight();
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(manualStartPB, INPUT_PULLUP);
pinMode(manualStopPB, INPUT_PULLUP);
pinMode(buzzer, OUTPUT);
pinMode(relay, OUTPUT);
//initializes to make the output LOW at first
digitalWrite(relay, LOW);
digitalWrite(buzzer, LOW);
}
void loop() {
//for serially displaying the value
Serial.println(ultrasonicRead(echoPin, trigPin, 250, "cm"));
//maps the value of the ultrasonic Reading into 0 to 100% (100 being almost close to full)
waterLevelPercentage = map(ultrasonicRead(echoPin, trigPin, 250, "cm"), 400.00, 2.00, 0, 100);
//Manually turn on the Pump
if (digitalRead(manualStartPB) == LOW && stat == "") {
digitalWrite(relay, HIGH);
stat = "manualMode";
}
else if (digitalRead(manualStopPB) == LOW && stat == "manualMode") {
digitalWrite(relay, LOW);
stat = "";
}
else if (stat == "") {
//this is a function that triggers the output based on the read ultrasonic value
//and the set targetLevel at which output is triggered (at 75%)
checkWaterLevel(waterLevelPercentage, 75, relay);
}
//displays warning and value to the LCD Screen
display();
}
//displays message in the i2C display
void display() {
lcd.setCursor(0,0);
lcd.print("WaterLvl: ");
if(waterLevelPercentage > 99) {
lcd.setCursor(10,0);
lcd.print(waterLevelPercentage);
}
else {
lcd.setCursor(10,0);
lcd.print(" ");
lcd.setCursor(11,0);
lcd.print(waterLevelPercentage);
}
lcd.setCursor(14,0);
lcd.print("%");
if(waterLevelPercentage > 75) {
lcd.setCursor(0,1);
lcd.print("Water Lvls High!");
}
else {
lcd.setCursor(0,1);
lcd.print("----------------");
}
}
//Controls the output based on the read level value
bool checkWaterLevel(double level, double targetLevel, int output) {
if (level > targetLevel) {
digitalWrite(output, HIGH);
digitalWrite(buzzer, HIGH);
}
else {
digitalWrite(output, LOW);
digitalWrite(buzzer, LOW);
}
}
/* Ultrasonic Reading
---------------------------- Parameters -----------------------------
echoPin ---> Echo Pin of the Ultrasonic
trigPin ---> Trig Pin of the Ultrasonic
refreshRate ---> refresh rate in millis Time/when will the ultrasonic reads
units ---> the unit that the ultrasonic will output
---------------------------------------------------------------------
*/
double ultrasonicRead(int echoPin, int trigPin, unsigned long refreshRate, String units) {
static float duration, distance;
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= refreshRate) {
// Set the trigger pin LOW for 2uS
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Set the trigger pin HIGH for 20us to send pulse
digitalWrite(trigPin, HIGH);
delayMicroseconds(20);
// Return the trigger pin to LOW
digitalWrite(trigPin, LOW);
// Measure the width of the incoming pulse
duration = pulseIn(echoPin, HIGH);
// Determine distance from duration
// Use 343 metres per second as speed of sound
if(units == "cm") {
// Divide by 1000 as we want millimeters
distance = (duration / 2) * 0.0343;
}
else {
//defaults to mm
// Divide by 1000 as we want millimeters
distance = (duration / 2) * 0.343;
}
//loops back to use it and compare back to the current Millis
previousMillis = currentMillis;
}
return distance;
}