#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// LCD setup
LiquidCrystal_I2C lcd(0x27, 20, 4); // Adjust I2C address if necessary
// Pin definitions
const int waterLevelPotPin = 34; // Potentiometer for water level
const int pHPotPin = 35; // Potentiometer for pH level
const int turbidityPotPin = 32; // Potentiometer for turbidity
const int waterLevelBuzzerPin = 14; // Buzzer for water level
const int turbidityBuzzerPin = 27; // Buzzer for turbidity
const int waterLevelLEDPin = 12; // LED for water level
const int turbidityLEDPin = 26; // LED for turbidity
// Threshold constants for turbidity levels (in volts)
const float turbidityVeryDirtyThreshold = 1.5;
const float turbidityDirtyThreshold = 3.0;
// Threshold for water level (in percentage)
const float waterLevelThreshold = 50.0;
void setup() {
// Initialize serial communication for debugging
Serial.begin(9600);
// Initialize LCD
lcd.init();
lcd.backlight();
// Set pin modes
pinMode(waterLevelBuzzerPin, OUTPUT);
pinMode(turbidityBuzzerPin, OUTPUT);
pinMode(waterLevelLEDPin, OUTPUT);
pinMode(turbidityLEDPin, OUTPUT);
// Start with outputs off
digitalWrite(waterLevelBuzzerPin, LOW);
digitalWrite(turbidityBuzzerPin, LOW);
digitalWrite(waterLevelLEDPin, LOW);
digitalWrite(turbidityLEDPin, LOW);
}
void loop() {
// Read values from potentiometers
int waterLevelValue = analogRead(waterLevelPotPin);
int pHPotValue = analogRead(pHPotPin);
int turbidityValue = analogRead(turbidityPotPin);
// Map potentiometer values to meaningful ranges
float waterLevel = (waterLevelValue / 4095.0) * 100.0; // Simulate water level (0-100%)
float pHVoltage = (pHPotValue / 4095.0) * 3.3; // Voltage in volts
float pH = (pHPotValue / 4095.0) * 14.0; // Simulated pH level (0-14)
float turbidityVoltage = (turbidityValue / 4095.0) * 5.0; // Voltage for turbidity sensor
// Water level detection
if (waterLevel > waterLevelThreshold) {
digitalWrite(waterLevelBuzzerPin, HIGH);
digitalWrite(waterLevelLEDPin, HIGH);
} else {
digitalWrite(waterLevelBuzzerPin, LOW);
digitalWrite(waterLevelLEDPin, LOW);
}
// pH level detection
String pHStatus;
if (pH >= 6.9 && pH <= 7.1) {
pHStatus = "NEUTRAL";
} else if (pH < 6.9) {
pHStatus = "ACIDIC";
} else {
pHStatus = "ALKALINE";
}
// Turbidity level detection
String turbidityStatus;
if (turbidityVoltage <= turbidityVeryDirtyThreshold) {
digitalWrite(turbidityBuzzerPin, HIGH);
digitalWrite(turbidityLEDPin, HIGH);
turbidityStatus = "VERY DIRTY";
} else if (turbidityVoltage > turbidityVeryDirtyThreshold && turbidityVoltage <= turbidityDirtyThreshold) {
digitalWrite(turbidityBuzzerPin, LOW);
digitalWrite(turbidityLEDPin, HIGH);
turbidityStatus = "DIRTY";
} else {
digitalWrite(turbidityBuzzerPin, LOW);
digitalWrite(turbidityLEDPin, LOW);
turbidityStatus = "VERY CLEAN";
}
// Update the LCD display with organized formatting
updateLCD(waterLevel, pHVoltage, pH, pHStatus, turbidityStatus);
delay(1000); // Update every second
}
void updateLCD(float waterLevel, float pHVoltage, float pH, String pHStatus, String turbidityStatus) {
static float lastWaterLevel = -1;
static float lastPHVoltage = -1;
static String lastPHStatus = "";
static String lastTurbidityStatus = "";
const float tolerance = 0.1;
// Only update LCD when values change to reduce flickering
if (abs(waterLevel - lastWaterLevel) > tolerance) {
lcd.setCursor(0, 0);
lcd.print("Water Level: ");
lcd.print(waterLevel, 1); // 1 decimal place
lcd.print("% "); // Ensure clearing old data
lastWaterLevel = waterLevel;
}
if (abs(pHVoltage - lastPHVoltage) > tolerance || pHStatus != lastPHStatus) {
lcd.setCursor(0, 1);
lcd.print("pH Voltage: ");
lcd.print(pHVoltage, 2); // 2 decimal places
lcd.print(" V "); // Clear old text with spaces
lcd.setCursor(0, 2);
lcd.print("pH: ");
lcd.print(pH, 1); // 1 decimal place
lcd.print(" ");
lcd.print(pHStatus);
lcd.print(" "); // Clear old text
lastPHVoltage = pHVoltage;
lastPHStatus = pHStatus;
}
if (turbidityStatus != lastTurbidityStatus) {
lcd.setCursor(0, 3);
lcd.print("Turbidity: ");
lcd.print(turbidityStatus);
lcd.print(" "); // Clear old text
lastTurbidityStatus = turbidityStatus;
}
}