Sensors
Sensors
Turbidity Sensor Tested

The project uses the LGZD Sensor V1.1 turbidity sensor, powered at 5 V DC with a current consumption of up to 30 mA, making it suitable for direct connection to a microcontroller system. It measures water clarity by providing either an analog output (0–4.5 V) or a digital signal (0–5 V), with a fast response time of less than 500 ms, allowing the system to quickly detect changes in water quality. This sensor is chosen because it enables real-time monitoring of turbidity levels, so the system can automatically trigger actions such as activating the solenoid valve to stop or allow flow and controlling the pump, ensuring only clean water passes through the system while maintaining reliable and responsive automated operation.
const int turbidityPin = A0;
float V_clean = 2.77;
float V_dirty = 0.90;
int getAverage() {
int sum = 0;
for (int i = 0; i < 20; i++) {
sum += analogRead(turbidityPin);
delay(5);
}
return sum / 20;
}
void setup() {
Serial.begin(115200);
Serial.println("=== TURBIDITY MONITOR ===");
}
void loop() {
int raw = getAverage();
float voltage = raw * (3.3 / 4095.0);
float turbidity = ((V_clean - voltage) / (V_clean - V_dirty)) * 100.0;
// Clamp values
if (turbidity < 0) turbidity = 0;
if (turbidity > 100) turbidity = 100;
// Classification
String status;
if (turbidity < 20) {
status = "CLEAN 💧";
}
else if (turbidity < 50) {
status = "SLIGHTLY DIRTY 🌫️";
}
else if (turbidity < 80) {
status = "DIRTY 🟤";
}
else {
status = "VERY DIRTY 🚫";
}
// Print everything nicely
Serial.print("Raw: ");
Serial.print(raw);
Serial.print(" | Voltage: ");
Serial.print(voltage, 2);
Serial.print(" V | Turbidity: ");
Serial.print(turbidity, 1);
Serial.print(" %");
Serial.print(" | Status: ");
Serial.println(status);
delay(1000);
}
Results
SEN0189 Sensor with Xiao Esp32-C3
New sensor readings
clean water
Raw: 3435 Voltage: 2.77 V
Raw: 3438 Voltage: 2.77 V
Raw: 3432 Voltage: 2.77 V
Raw: 3434 Voltage: 2.77 V
Raw: 3432 Voltage: 2.77 V
Raw: 3422 Voltage: 2.76 V
Dirty Water
Raw: 1176 Voltage: 0.95 V
Raw: 1163 Voltage: 0.94 V
Raw: 1161 Voltage: 0.94 V
Raw: 1199 Voltage: 0.97 V
Raw: 1126 Voltage: 0.91 V
Raw: 1097 Voltage: 0.88 V
Raw: 1095 Voltage: 0.88 V
Raw: 1095 Voltage: 0.88 V
Raw: 1070 Voltage: 0.86 V
Raw: 1069 Voltage: 0.86 V
My averages
float V_clean = 2.77;
float V_dirty = 0.90;
with very consistent readings now with new sensor
old sensor readings
Clean Water
Raw: 2029 Voltage: 1.64 V
Raw: 2029 Voltage: 1.64 V
Raw: 2030 Voltage: 1.64 V
Raw: 2037 Voltage: 1.64 V
Raw: 2041 Voltage: 1.64 V
Raw: 2039 Voltage: 1.64 V
Raw: 2040 Voltage: 1.64 V
Raw: 2044 Voltage: 1.65 V
Raw: 2044 Voltage: 1.65 V
Raw: 2043 Voltage: 1.65 V
Average Raw Value: 2037.6
Average Voltage: 1.643 V
dirty Water
Raw: 2139 Voltage: 1.72 V
Raw: 2139 Voltage: 1.72 V
Raw: 2141 Voltage: 1.73 V
Raw: 2151 Voltage: 1.73 V
Raw: 2153 Voltage: 1.74 V
Raw: 2152 Voltage: 1.73 V
Raw: 2152 Voltage: 1.73 V
Raw: 2154 Voltage: 1.74 V
Raw: 2154 Voltage: 1.74 V
Raw: 2152 Voltage: 1.73 V
Raw: 2166 Voltage: 1.75 V
Average Raw Value: 2150.27
Average Voltage: 1.733 V
Flow Sensor

Flow Rate: 0.00 L/min
Flow Rate: 0.00 L/min
Flow Rate: 0.00 L/min
Flow Rate: 0.27 L/min
Flow Rate: 0.27 L/min
Flow Rate: 0.67 L/min
Flow Rate: 0.93 L/min
Flow Rate: 0.93 L/min
Flow Rate: 0.93 L/min
Flow Rate: 1.07 L/min
Flow Rate: 0.93 L/min
Flow Rate: 1.07 L/min
I tested the sensor using xiao esp 32-c3, and connected with MQTT, and got the followng readings:

#include <WiFi.h>
#include <PubSubClient.h>
// WiFi
const char* ssid = "MT";
const char* password = "#@Innovate";
// MQTT
const char* mqtt_server = "broker.emqx.io";
WiFiClient espClient;
PubSubClient client(espClient);
// Flow sensor
const int flowPin = D2; // D2 (change if needed)
volatile int pulseCount = 0;
float flowRate = 0.0;
float totalLiters = 0.0;
unsigned long previousMillis = 0;
// Interrupt
void IRAM_ATTR pulseCounter() {
pulseCount++;
}
// Connect WiFi
void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
}
// Reconnect MQTT
void reconnect() {
while (!client.connected()) {
if (client.connect("ESP32FlowClient")) {
Serial.println("MQTT connected");
} else {
delay(2000);
}
}
}
void setup() {
Serial.begin(115200);
pinMode(flowPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(flowPin), pulseCounter, FALLING);
setup_wifi();
client.setServer(mqtt_server, 1883);
}
void loop() {
if (!client.connected()) reconnect();
client.loop();
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= 1000) { // every 1 sec
previousMillis = currentMillis;
// Calculate flow rate (L/min)
flowRate = pulseCount / 7.5;
// Convert to liters per second and accumulate
float litersThisSecond = flowRate / 60.0;
totalLiters += litersThisSecond;
pulseCount = 0;
// Convert to string
char flowMsg[20];
char totalMsg[20];
sprintf(flowMsg, "%.2f", flowRate);
sprintf(totalMsg, "%.2f", totalLiters);
// Publish to MQTT
client.publish("water/flow", flowMsg);
client.publish("water/total", totalMsg);
// Debug
Serial.print("Flow: ");
Serial.print(flowRate);
Serial.print(" L/min | Total: ");
Serial.println(totalLiters);
}
}