#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <math.h>
// ===== LCD I2C =====
LiquidCrystal_I2C lcd(0x27, 20, 4);
// ===== PIN =====
#define PH_PIN 34
#define TDS_PIN 35
#define TURB_PIN 32
#define FLOW_PIN 33 // potentiometer
#define BUZZER_PIN 25
// ===== FLOW =====
float flowRate = 0;
float totalLiters = 0;
// Moving average
#define FLOW_AVG_COUNT 5
int flowBuffer[FLOW_AVG_COUNT] = {0};
int flowIndex = 0;
void setup() {
Serial.begin(115200);
pinMode(BUZZER_PIN, OUTPUT);
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("System Starting...");
delay(2000);
lcd.clear();
}
void loop() {
// ===== READ SENSOR =====
int phRaw = analogRead(PH_PIN);
int tdsRaw = analogRead(TDS_PIN);
int turbRaw = analogRead(TURB_PIN);
int flowRaw = analogRead(FLOW_PIN);
// ===== pH =====
float voltagePH = phRaw * (3.3 / 4095.0);
float pH = (voltagePH / 3.3) * 14.0;
// ===== TDS =====
float voltageTDS = tdsRaw * (3.3 / 4095.0);
float tds = (133.42 * pow(voltageTDS, 3)
- 255.86 * pow(voltageTDS, 2)
+ 857.39 * voltageTDS) * 0.5;
if (tds < 0) tds = 0;
if (tds > 1000) tds = 1000;
// ===== TURBIDITY (LIMITED TO 500 NTU) =====
float turbidity = map(turbRaw, 0, 4095, 0, 500);
if (turbidity < 0) turbidity = 0;
if (turbidity > 500) turbidity = 500;
// ===== FLOW =====
flowBuffer[flowIndex] = flowRaw;
flowIndex = (flowIndex + 1) % FLOW_AVG_COUNT;
long sum = 0;
for (int i = 0; i < FLOW_AVG_COUNT; i++) sum += flowBuffer[i];
int flowAvg = sum / FLOW_AVG_COUNT;
flowRate = map(flowAvg, 0, 4095, 0, 1000) / 100.0;
totalLiters += flowRate / 60.0;
// ===== CONDITION =====
String status;
if (pH >= 6.5 && pH <= 8.5 && tds < 500 && turbidity < 5) {
status = "SAFE";
digitalWrite(BUZZER_PIN, LOW);
} else {
status = "UNSAFE";
digitalWrite(BUZZER_PIN, HIGH);
}
// ===== SERIAL =====
Serial.print("pH: "); Serial.print(pH, 2);
Serial.print(" | TDS: "); Serial.print(tds, 0);
Serial.print(" | NTU: "); Serial.print(turbidity, 0);
Serial.print(" | Flow: "); Serial.print(flowRate, 2);
Serial.print(" | Total: "); Serial.print(totalLiters, 2);
Serial.print(" | "); Serial.println(status);
// ===== LCD =====
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("pH:");
lcd.print(pH, 2);
lcd.setCursor(10, 0);
lcd.print("TDS:");
lcd.print((int)tds);
lcd.setCursor(0, 1);
lcd.print("NTU:");
lcd.print((int)turbidity);
lcd.print("/500");
lcd.setCursor(10, 1);
lcd.print(status);
lcd.setCursor(0, 2);
lcd.print("Flow:");
lcd.print(flowRate, 1);
lcd.print("L/m");
lcd.setCursor(0, 3);
lcd.print("Vol:");
lcd.print(totalLiters, 2);
lcd.print("L");
delay(1000);
}