#include <OneWire.h>
#include <DallasTemperature.h>
#include <ESP32Servo.h>
// Pin Definitions
#define RTD_PIN 6 // Pin data RTD (ADC)
#define TDS_PIN 12 // TDS Sensor
#define TURBIDITY_PIN 13 // Turbidity Sensor
#define PH_PIN 14 // pH Sensor
#define DO_PIN 15 // DO Sensor
// Actuator pins
#define BUZZER_PIN 1
#define RELAY1_PIN 2
#define RELAY2_PIN 3
#define SERVO_PIN 4
#define SLIDE_POT_PIN 5
// Setup sensor objects
OneWire oneWire(RTD_PIN);
DallasTemperature tempSensor(&oneWire);
Servo servo;
// Konstanta untuk RTD PT100
const float RTD_R0 = 100.0; // Resistansi RTD pada 0°C
const float RTD_A = 0.00385; // Koefisien temperatur
// Threshold values
const float RTD_MIN = 25.0;
const float RTD_MAX = 32.0;
const float TDS_MIN = 1000.0;
const float TDS_MAX = 1500.0;
const float TURBIDITY_MIN = 0.0;
const float TURBIDITY_MAX = 50.0;
const float PH_MIN = 7.0;
const float PH_MAX = 8.5;
const float DO_MIN = 4.0;
const float DO_MAX = 8.0;
void setup() {
Serial.begin(115200);
// Initialize sensors
tempSensor.begin();
// Setup pin RTD
pinMode(RTD_PIN, INPUT);
// Initialize actuators
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
servo.attach(SERVO_PIN);
pinMode(SLIDE_POT_PIN, INPUT);
// Initial position
servo.write(90);
}
void loop() {
// Read sensor values
float temperature = readTemperature();
float tds = readTDS();
float turbidity = readTurbidity();
float ph = readPH();
float do_level = readDO();
// Process each sensor and control corresponding actuator
processTemperature(temperature); // Controls Buzzer
processTDS(tds); // Controls Relay1
processTurbidity(turbidity); // Controls Relay2
processPH(ph); // Controls Servo
processDO(do_level); // Controls Slide Potentiometer
// Print readings
printReadings(temperature, tds, turbidity, ph, do_level);
delay(1000);
}
// Sensor reading functions
float readTemperature() {
int rawValue = analogRead(RTD_PIN);
float voltage = (rawValue * 3.3) / 4095.0;
// Konversi voltage ke resistansi
float resistance = voltage * 100.0; // Asumsi voltage divider dengan resistor 100 ohm
// Konversi resistansi ke temperatur menggunakan persamaan Callendar-Van Dusen
float temperature = (resistance - RTD_R0) / (RTD_R0 * RTD_A);
// Cek validitas pembacaan
if(temperature < -200 || temperature > 850) { // Range valid untuk PT100
Serial.println("Error: Invalid temperature reading!");
return 0.0;
}
return temperature;
}
float readTDS() {
int rawValue = analogRead(TDS_PIN);
// Convert analog reading to TDS value (ppm)
float voltage = rawValue * 3.3 / 4095.0;
float tdsValue = (133.42 * voltage * voltage * voltage - 255.86 * voltage * voltage + 857.39 * voltage) * 0.5;
return tdsValue;
}
float readTurbidity() {
int rawValue = analogRead(TURBIDITY_PIN);
// Convert analog reading to NTU
float voltage = rawValue * 3.3 / 4095.0;
float ntu = -1120.4 * voltage * voltage + 5742.3 * voltage - 4353.8;
return ntu;
}
float readPH() {
int rawValue = analogRead(PH_PIN);
// Convert analog reading to pH value
float voltage = rawValue * 3.3 / 4095.0;
float phValue = 3.5 * voltage + 0.0;
return phValue;
}
float readDO() {
int rawValue = analogRead(DO_PIN);
// Convert analog reading to DO value (mg/L)
float voltage = rawValue * 3.3 / 4095.0;
float doValue = voltage * 2.5;
return doValue;
}
// Actuator control functions
void processTemperature(float temp) {
// Temperature controls Buzzer
if (temp < RTD_MIN || temp > RTD_MAX) {
digitalWrite(BUZZER_PIN, HIGH);
} else {
digitalWrite(BUZZER_PIN, LOW);
}
}
void processTDS(float tds) {
// TDS controls Relay1 (water pump)
if (tds > TDS_MAX) {
digitalWrite(RELAY1_PIN, HIGH); // Activate water pump for dilution
} else {
digitalWrite(RELAY1_PIN, LOW);
}
}
void processTurbidity(float turb) {
// Turbidity controls Relay2 (filter system)
if (turb > TURBIDITY_MAX) {
digitalWrite(RELAY2_PIN, HIGH); // Activate filter
} else {
digitalWrite(RELAY2_PIN, LOW);
}
}
void processPH(float ph) {
// pH controls Servo (chemical dosing)
if (ph < PH_MIN) {
servo.write(180); // Add base
} else if (ph > PH_MAX) {
servo.write(0); // Add acid
} else {
servo.write(90); // Neutral position
}
}
void processDO(float do_level) {
// DO controls Slide Potentiometer (aerator intensity)
int aeratorIntensity = map(do_level * 100, DO_MIN * 100, DO_MAX * 100, 0, 255);
analogWrite(SLIDE_POT_PIN, aeratorIntensity);
}
void printReadings(float temp, float tds, float turb, float ph, float do_level) {
// Print header
Serial.println("======= Water Quality Monitoring System =======");
// Temperature status
String tempStatus = (temp >= RTD_MIN && temp <= RTD_MAX) ? "Normal" : "Warning";
String alarmStatus = digitalRead(BUZZER_PIN) ? "Active" : "Inactive";
Serial.print("Temp: ");
Serial.print(temp, 1);
Serial.print(" °C (Status: ");
Serial.print(tempStatus);
Serial.print(", Buzzer: ");
Serial.println(alarmStatus);
Serial.println(") ");
// TDS status
String tdsStatus = (tds >= TDS_MIN && tds <= TDS_MAX) ? "Normal" : "Warning";
String pump = digitalRead(RELAY1_PIN) ? "ON" : "OFF";
Serial.print("TDS: ");
Serial.print(tds, 0);
Serial.print(" ppm (Status: ");
Serial.print(tdsStatus);
Serial.print(", Pump: ");
Serial.print(pump);
Serial.println(")");
// Turbidity status
String turbStatus = (turb >= TURBIDITY_MIN && turb <= TURBIDITY_MAX) ? "Normal" : "Warning";
String filter = digitalRead(RELAY2_PIN) ? "ON" : "OFF";
Serial.print("Turbidity: ");
Serial.print(turb, 1);
Serial.print(" NTU (Status: ");
Serial.print(turbStatus);
Serial.print(", Filter: ");
Serial.print(filter);
Serial.println(")");
// pH status
String phStatus = (ph >= PH_MIN && ph <= PH_MAX) ? "Normal" : "Warning";
int servoPos = servo.read();
String dosingStatus;
if (servoPos < 45) dosingStatus = "Adding Acid";
else if (servoPos > 135) dosingStatus = "Adding Base";
else dosingStatus = "Neutral";
Serial.print("pH: ");
Serial.print(ph, 2);
Serial.print(" (Status: ");
Serial.print(phStatus);
Serial.print(", Dosing: ");
Serial.print(dosingStatus);
Serial.println(")");
// DO status
String doStatus = (do_level >= DO_MIN && do_level <= DO_MAX) ? "Normal" : "Warning";
int aeratorPower = map(analogRead(SLIDE_POT_PIN), 0, 255, 0, 100);
Serial.print("DO: ");
Serial.print(do_level, 2);
Serial.print(" mg/L (Status: ");
Serial.print(doStatus);
Serial.print(", Aerator: ");
Serial.print(aeratorPower);
Serial.println("%)");
Serial.println("===========================================");
Serial.println();
}control pompa
control filter
peringatan high temp
control pH
control intensitas aerator