/*
SMART PLANT WATERING SYSTEM - ESP32 on Wokwi
============================================
CONNECTIONS:
- Potentiometer: Left→3.3V, Middle→34, Right→GND
- LED: Anode→Resistor→D13, Cathode→GND
- Pushbutton: One pin→D12, Other pin→GND
*/
#include <WiFi.h>
// Pin Definitions - MATCH YOUR CONNECTIONS
const int SOIL_SENSOR_PIN = 34; // Potentiometer middle pin → pin "34"
const int PUMP_RELAY_PIN = 13; // LED via resistor → pin "D13"
const int MANUAL_BUTTON_PIN = 12; // Pushbutton → pin "D12"
// Calibration values
const int DRY_THRESHOLD = 3000; // Above this = soil dry (pump ON)
const int WET_THRESHOLD = 1500; // Below this = soil wet (pump OFF)
// System variables
int soilMoistureValue = 0;
bool isPumpRunning = false;
bool manualOverrideActive = false;
unsigned long manualStartTime = 0;
const unsigned long MANUAL_RUN_TIME = 5000; // 5 seconds
// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
WiFiServer server(80);
void setup() {
Serial.begin(115200);
delay(1000);
// Configure pins
pinMode(SOIL_SENSOR_PIN, INPUT);
pinMode(PUMP_RELAY_PIN, OUTPUT);
pinMode(MANUAL_BUTTON_PIN, INPUT_PULLUP);
// Start with pump OFF
digitalWrite(PUMP_RELAY_PIN, LOW);
isPumpRunning = false;
// Connect to WiFi
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
} else {
Serial.println("\nWiFi not available - continuing offline");
}
Serial.println("\n=== SMART PLANT WATERING SYSTEM ===");
Serial.println("Turn potentiometer:");
Serial.println(" CLOCKWISE (high value) = DRY → Pump ON");
Serial.println(" COUNTER-CLOCKWISE (low value) = WET → Pump OFF");
Serial.println("Press button for manual watering (5 seconds)");
Serial.println("====================================\n");
}
void loop() {
// Read soil moisture
soilMoistureValue = analogRead(SOIL_SENSOR_PIN);
// Check manual button
if (digitalRead(MANUAL_BUTTON_PIN) == LOW && !manualOverrideActive) {
manualOverrideActive = true;
manualStartTime = millis();
digitalWrite(PUMP_RELAY_PIN, HIGH);
isPumpRunning = true;
Serial.println("\n*** MANUAL OVERRIDE: Pump ON for 5 seconds ***");
delay(200); // Debounce
}
// Handle manual override timeout
if (manualOverrideActive && (millis() - manualStartTime >= MANUAL_RUN_TIME)) {
manualOverrideActive = false;
digitalWrite(PUMP_RELAY_PIN, LOW);
isPumpRunning = false;
Serial.println("Manual watering complete - Returning to automatic mode");
}
// Automatic control (if not in manual mode)
if (!manualOverrideActive) {
if (soilMoistureValue > DRY_THRESHOLD && !isPumpRunning) {
digitalWrite(PUMP_RELAY_PIN, HIGH);
isPumpRunning = true;
Serial.println("🌱 SOIL DRY! Pump activated (LED ON)");
}
else if (soilMoistureValue < WET_THRESHOLD && isPumpRunning) {
digitalWrite(PUMP_RELAY_PIN, LOW);
isPumpRunning = false;
Serial.println("✅ Soil moist. Pump OFF (LED OFF)");
}
}
// Display status
int moisturePercent = map(soilMoistureValue, 0, 4095, 100, 0);
moisturePercent = constrain(moisturePercent, 0, 100);
Serial.print("Soil: ");
Serial.print(soilMoistureValue);
Serial.print(" (");
Serial.print(moisturePercent);
Serial.print("%) | Pump: ");
Serial.print(isPumpRunning ? "🔴 ON" : "🟢 OFF");
if (manualOverrideActive) {
unsigned long remaining = (MANUAL_RUN_TIME - (millis() - manualStartTime)) / 1000;
Serial.print(" | MANUAL: ");
Serial.print(remaining);
Serial.print("s left");
}
Serial.println();
// Handle web requests
if (WiFi.status() == WL_CONNECTED) {
WiFiClient client = server.available();
if (client) {
String request = client.readStringUntil('\r');
client.flush();
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
client.println("<!DOCTYPE html><html>");
client.println("<head><meta http-equiv='refresh' content='5'/></head>");
client.println("<body>");
client.println("<h1>🌱 Smart Plant Watering System</h1>");
client.println("<p>Soil Moisture: " + String(soilMoistureValue) + "</p>");
client.println("<p>Pump Status: " + String(isPumpRunning ? "RUNNING" : "OFF") + "</p>");
client.println("</body></html>");
client.stop();
}
}
delay(1000);
}