#include <LiquidCrystal.h>
#include <NewPing.h>
#include <DHT.h>
// Constants
#define MAX_DISTANCE 197 // Maximum sensor distance in cm
#define MEDIAN_SAMPLE 5 // Number of samples for median filter
#define DEBOUNCE_DELAY 70 // Button debounce delay
#define MIN_MEASUREMENT_INTERVAL 100 // Minimum time between ultrasonic measurements in milliseconds
#define GREEN_LED_PIN 8
#define YELLOW_LED_PIN 9
#define RED_LED_PIN 10
#define TRIGGER_PIN 7
#define ECHO_PIN 7
#define BUTTON_PIN 13
#define RELAY_PIN A1
#define LCDPOWER_PIN A3
#define DHT_PIN 6
#define DHT_TYPE DHT22
// Initialize objects
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
DHT dht(DHT_PIN, DHT_TYPE);
// Variables
volatile bool buttonState = LOW;
bool previousButtonState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long lastDisplayUpdateTime = 0;
unsigned int distance;
int waterLevel = 0; // This will store the water level in centimeters
byte waterLevelPercent = 0;
bool pumpFlag = false;
unsigned long lastMeasurementTime = 0; // Last time ultrasonic measurement was performed
void setup() {
pinMode(BUTTON_PIN, INPUT);
pinMode(LCDPOWER_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(YELLOW_LED_PIN, OUTPUT);
pinMode(RED_LED_PIN, OUTPUT);
Serial.begin(9600);
lcd.begin(16, 2);
dht.begin();
}
void loop() {
buttonState = digitalRead(BUTTON_PIN);
unsigned long currentMillis = millis();
// Button debounce
if (currentMillis - lastDebounceTime > DEBOUNCE_DELAY) {
if (buttonState != previousButtonState) {
if (buttonState == LOW) {
buttonPressed();
}
lastDebounceTime = currentMillis;
}
}
previousButtonState = buttonState;
// Perform ultrasonic measurement if MIN_MEASUREMENT_INTERVAL has passed
if (currentMillis - lastMeasurementTime >= MIN_MEASUREMENT_INTERVAL) {
lastMeasurementTime = currentMillis;
checkWaterLevel();
}
// Periodic tasks
if (currentMillis - lastDisplayUpdateTime > 1000) {
updateDisplay();
controlRelay();
updateLEDs(); // Update the LED status based on the water level
lastDisplayUpdateTime = currentMillis;
}
}
void buttonPressed() {
analogWrite(LCDPOWER_PIN, 255); // Ensure LCD backlight is on
lcd.clear();
lcd.print(F("Button Pressed!"));
delay(2000); // Display message for 2 seconds
}
void updateDisplay() {
float temperature = dht.readTemperature();
if (!isnan(temperature)) {
lcd.setCursor(0, 0);
lcd.print(F("Temp: "));
lcd.print(temperature,1);
lcd.print(F(" C "));
}
lcd.setCursor(0, 1);
lcd.print(F("Water: "));
lcd.print(waterLevelPercent);
lcd.print(F("% "));
drawWaterLevelGraph(waterLevelPercent);
}
void drawWaterLevelGraph(int percentage) {
int blocks = percentage / 20; // 5 blocks max for 0-100%
lcd.setCursor(11, 1);
for (int i = 0; i < 5; i++) {
lcd.write(i < blocks ? 255 : 32); // Full block for water, space for empty
}
}
void checkWaterLevel() {
unsigned int currentDistance = sonar.ping_cm(); // Perform ultrasonic measurement
// Ensure the measurement is within valid range and interval
if (currentDistance > 0 && currentDistance <= MAX_DISTANCE) {
distance = currentDistance; // Update the distance variable
waterLevel = MAX_DISTANCE - distance; // Calculate water level
waterLevelPercent = map(waterLevel, 0, MAX_DISTANCE, 0, 100); // Calculate water level percentage
Serial.println("Water level measured: " + String(waterLevelPercent) + "%");
} else {
Serial.println("Invalid measurement or interval exceeded.");
}
}
void controlRelay() {
// Turn on the relay when water level is below 12%
if (waterLevelPercent < 12) {
digitalWrite(RELAY_PIN, HIGH);
} else {
digitalWrite(RELAY_PIN, LOW);
}
}
void updateLEDs() {
if (waterLevelPercent >= 75) {
// High water level - Green LED on
digitalWrite(GREEN_LED_PIN, HIGH);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, LOW);
} else if (waterLevelPercent >= 25 && waterLevelPercent < 75) {
// Medium water level - Yellow LED on
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, HIGH);
digitalWrite(RED_LED_PIN, LOW);
} else {
// Low water level - Red LED on
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, HIGH);
}
}