ESP32-Based Real-Time Monitoring: The ₹3,500 System That Saved a ₹2.4 Lakh Crop

Listen to this article
Duration: calculating…
Idle

Meta Description: Build ESP32-based real-time monitoring for hydroponics with TDS, pH, water level, and temperature sensors. Complete DIY guide with code, wiring diagrams, and cloud integration for smart farming.

Introduction: The 3:47 AM Alert That Changed Everything

The WhatsApp notification jolted Anna Petrov awake at 3:47 AM: “⚠️ CRITICAL ALERT: pH 8.2 (Target: 6.0) – Nutrient lockout imminent – 427 lettuce plants at risk.” Her ESP32 स्मार्ट मॉनिटरिंग सिस्टम (smart monitoring system) had detected a catastrophic pH spike 4.7 hours before her morning inspection would have discovered it—and 8-12 hours before visible plant damage would have appeared. Within 18 minutes, she had remotely adjusted pH dosing pumps from her smartphone, preventing what would have been a ₹2.4 lakh crop disaster.

Traditional hydroponic monitoring meant checking systems 2-3 times daily by physically visiting the grow area, reading analog gauges, manually logging numbers in notebooks, and hoping nothing went wrong between inspections. Anna’s ₹3,500 ESP32-based monitoring platform transformed agriculture from reactive crisis management to proactive real-time intelligence—continuously measuring TDS, pH, water level, and temperature every 30 seconds, transmitting data instantly to cloud storage, generating intelligent alerts before problems became disasters, and enabling remote monitoring and control from anywhere with internet access.

In the 14 months since deploying her ESP32 monitoring network across 2,400 hydroponic plants, Anna had solved agriculture’s visibility problem: knowing what’s happening in real-time, everywhere, always. Her system logged 4.2 million sensor readings, detected 47 critical issues before crop damage occurred, enabled 94% reduction in manual monitoring time (from 18 hours/week to 1 hour), and most remarkably—paid for itself in just 23 days through a single prevented crop failure.


The Traditional Hydroponic Monitoring Problem

Why Manual Systems Fail

The Standard Approach:

Most hydroponic growers rely on manual monitoring:

  • Visit grow area 2-3 times daily
  • Check pH with handheld meter (₹2,000-8,000)
  • Test EC/TDS with separate meter (₹1,500-6,000)
  • Measure temperature with thermometer
  • Visually inspect water levels
  • Write numbers in notebook or Excel
  • React to problems after discovery

The Critical Failures:

1. Temporal Blindness (16-21 hours/day unmonitored)

  • Check at 8 AM, 2 PM, 8 PM = 3 snapshots
  • No data for 75% of the day
  • Problems develop in blind periods

2. Delayed Problem Detection

  • pH spike at 11 PM → discovered at 8 AM (9 hours later)
  • By discovery time: Plant roots damaged, nutrient uptake blocked
  • Recovery time: 5-14 days (if plants survive)

3. No Historical Analysis

  • Notebook data hard to analyze
  • No trending or pattern recognition
  • Can’t identify recurring issues

4. No Remote Visibility

  • Must physically visit to check status
  • Can’t monitor while traveling
  • No alerts during critical events

5. Labor Intensive

  • 2-3 hours daily checking systems
  • 18-22 hours weekly monitoring time
  • Prevents scaling operation

Anna’s Pre-ESP32 Reality:

Daily Monitoring Routine:

  • 7:00 AM: Walk to greenhouse, check pH (6.2), EC (1240 ppm), temp (21°C), water level (OK)
  • 2:00 PM: Repeat measurements – pH 6.4, EC 1220, temp 24°C
  • 8:00 PM: Final check – pH 6.6, EC 1200, temp 22°C
  • Write in notebook, go to sleep

What She Missed:

  • 11:30 PM: pH begins spiking (automated dosing pump failed)
  • 3:00 AM: pH reaches 7.8 (critical)
  • 7:00 AM: pH 8.2 discovered (16 hours after start)
  • Damage: 187 plants showing nutrient deficiency, 8 days to recovery
  • Loss: ₹84,000 (reduced marketability + delayed harvest)

The ESP32 Solution:

With real-time monitoring:

  • System detects pH rising at 11:35 PM
  • Alert sent at 12:10 AM (pH 7.1 – early warning)
  • Critical alert at 3:47 AM (pH 8.2)
  • Remote response: 18 minutes
  • Damage: Zero
  • Loss: ₹0

Understanding ESP32: The Agricultural IoT Brain

What is ESP32?

ESP32 Definition:

A low-cost microcontroller with built-in WiFi and Bluetooth, specifically designed for IoT (Internet of Things) applications. Think of it as a tiny computer (₹600-1,200) that can:

  • Read sensors (pH, TDS, temperature, etc.)
  • Make decisions based on sensor data
  • Control devices (pumps, lights, fans)
  • Connect to internet (send data to cloud)
  • Communicate with smartphone (mobile app control)

Why ESP32 is Perfect for Hydroponics:

1. Built-in WiFi (vs Arduino requiring external WiFi module)

  • Direct cloud connectivity
  • No additional hardware needed
  • Cost savings: ₹800-1,500

2. Dual-Core Processor (vs Arduino single-core)

  • Core 1: Read sensors, control pumps
  • Core 2: Handle WiFi communication
  • Both run simultaneously without conflicts

3. Low Power Consumption

  • Deep sleep mode: 10µA
  • Active mode: 80mA average
  • Can run on battery + solar panel

4. Large Memory

  • 520 KB RAM (vs Arduino 2 KB)
  • 4 MB flash storage
  • Enough for complex programs + data logging

5. Multiple Communication Protocols

  • I2C, SPI, UART, PWM, ADC
  • Supports virtually any sensor
  • Easy expansion

6. Low Cost

  • ₹600-1,200 per board
  • 10× cheaper than Raspberry Pi
  • Same capabilities for monitoring

ESP32 vs Alternatives:

FeatureArduino UnoESP32Raspberry Pi 4
Price₹400-800₹600-1,200₹4,500-6,500
WiFi built-in❌ No✅ Yes✅ Yes
Power consumption50mA80mA500-1200mA
Processing power16 MHz, 1 core240 MHz, 2 cores1.5 GHz, 4 cores
Memory (RAM)2 KB520 KB2-8 GB
ComplexityLowMediumHigh
Best forBasic automationIoT monitoringAI/ML, cameras

Verdict: ESP32 = Perfect balance of cost, capability, and ease of use for hydroponic monitoring.


Building Your ESP32 Monitoring System

System Architecture Overview

┌─────────────────────────────────────────────────────────┐
│           Sensors (Reading Environment)                 │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐  │
│  │   TDS   │  │   pH    │  │  Temp   │  │  Water  │  │
│  │ Sensor  │  │ Sensor  │  │ DS18B20 │  │  Level  │  │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘  │
│       │            │            │            │         │
│       └────────────┴────────────┴────────────┘         │
└─────────────────────┬───────────────────────────────────┘
                      │
            ┌─────────▼──────────┐
            │    ESP32 Board     │
            │  (WiFi Enabled)    │
            │  - Reads sensors   │
            │  - Processes data  │
            │  - Makes decisions │
            └─────────┬──────────┘
                      │
        ┌─────────────┼─────────────┐
        │             │             │
        ▼             ▼             ▼
┌───────────┐  ┌───────────┐  ┌───────────┐
│   Cloud   │  │  Mobile   │  │   Local   │
│  Storage  │  │    App    │  │  Display  │
│ (Firebase,│  │ (Blynk,   │  │ (OLED     │
│  InfluxDB)│  │  Telegram)│  │  Screen)  │
└───────────┘  └───────────┘  └───────────┘

Component List & Cost Breakdown

Core Components:

ComponentSpecificationsQuantityUnit PriceTotal
ESP32 DevKit38-pin, WiFi+BT1₹800₹800
TDS/EC Sensor0-5000 ppm, analog1₹800₹800
pH Sensor0-14 pH, BNC probe1₹1,500₹1,500
DS18B20 TempWaterproof, digital1₹300₹300
Ultrasonic LevelHC-SR041₹200₹200
0.96″ OLED Display128×64, I2C1₹400₹400
Breadboard + wiresPrototyping1 set₹250₹250
5V Power Supply2A adapter1₹300₹300
EnclosureWaterproof box1₹400₹400
MiscellaneousResistors, caps1 set₹150₹150
TOTAL:₹5,100

Optional Upgrades:

ComponentPurposeCost
DHT22 sensorAir temp & humidity₹400
Real-time clock (DS3231)Accurate timestamps₹200
MicroSD card moduleLocal data backup₹150
Relay module (4-channel)Control pumps/devices₹400
Additional probesMultiple zones₹800-2,500

Minimum System (Budget): ₹3,500

  • ESP32 (₹800) + TDS (₹800) + DS18B20 (₹300) + Ultrasonic (₹200) + Power (₹300) + Enclosure (₹400) + Misc (₹200)
  • Skip pH sensor initially (add later), no display (use phone app)

Professional System: ₹5,100 (as listed above)

Multi-Zone System (4 zones): ₹12,800

  • 1× ESP32, 4× TDS, 4× pH, 4× Temp, 4× Level, display, power, enclosure

Step-by-Step Build Guide

Phase 1: Hardware Assembly

Step 1: Prepare ESP32 Board

ESP32 Pin Layout (38-pin DevKit):
┌─────────────────────────────────────┐
│ 3V3  EN   VP   VN  D34 D35 D32 D33 │  (Left side)
│ GND  D23  D22 TX0  RX0 D21 D19 D18 │
│ D5   D17  D16  D4  D0  D2  D15 SD1 │
│ SD0  CLK  CMD  D13 D12 D14 D27 D26 │
│ D25  D33  D32  D35 D34 VN   VP GND │  (Right side)
│ VIN  EN   3V3                       │
└─────────────────────────────────────┘

Key Pins:
- 3V3: 3.3V output (max 600mA)
- GND: Ground (multiple pins available)
- VIN: 5V input from USB or external power
- GPIO pins: D0-D39 (not all available)
- ADC pins: VP(36), VN(39), D34, D35, D32, D33, D25, D26, D27, D14, D12, D13

Step 2: Connect TDS/EC Sensor

// TDS Sensor Wiring
TDS Sensor Module → ESP32
  VCC (Red)       → 5V (VIN pin)
  GND (Black)     → GND
  Signal (Yellow) → GPIO 34 (ADC1_CH6)

// Physical Connection:
// 1. Insert sensor probe into nutrient solution
// 2. Secure probe with cable tie to tank edge
// 3. Ensure probe fully submerged (5cm minimum depth)
// 4. Keep away from air bubbles and heaters

TDS Sensor Calibration:

// Calibration with known standard solutions
// Use 1000 ppm TDS calibration solution (₹150-300)

float calibrateTDS() {
  // Read known 1000 ppm solution
  int rawValue = analogRead(34);
  float voltage = rawValue * (3.3 / 4095.0);  // ESP32 is 3.3V, 12-bit ADC
  
  // TDS = k * voltage
  // Solve for k: k = TDS / voltage
  // Example: If reading 1.2V with 1000 ppm solution
  // k = 1000 / 1.2 = 833.33
  
  float calibrationFactor = 1000.0 / voltage;
  
  // Store in EEPROM for permanent storage
  EEPROM.writeFloat(0, calibrationFactor);
  EEPROM.commit();
  
  return calibrationFactor;
}

Step 3: Connect pH Sensor

// pH Sensor Wiring
pH Sensor Module → ESP32
  VCC (Red)      → 5V (VIN pin)
  GND (Black)    → GND
  Signal (Blue)  → GPIO 35 (ADC1_CH7)

// BNC Probe Care:
// 1. Remove protective cap, rinse with distilled water
// 2. Store in pH 4.0 storage solution when not in use
// 3. Never let probe dry out (damaged permanently)
// 4. Calibrate weekly for accuracy

pH Sensor Calibration (2-point):

// Use pH 4.0 and pH 7.0 buffer solutions (₹200-400)

struct pHCalibration {
  float voltage_pH4;
  float voltage_pH7;
  float slope;
  float intercept;
};

pHCalibration calibratePH() {
  pHCalibration cal;
  
  // Step 1: Read pH 4.0 buffer
  Serial.println("Place probe in pH 4.0 buffer, wait 60 seconds");
  delay(60000);
  int raw1 = analogRead(35);
  cal.voltage_pH4 = raw1 * (3.3 / 4095.0);
  
  // Step 2: Rinse and read pH 7.0 buffer
  Serial.println("Rinse probe, place in pH 7.0 buffer, wait 60 seconds");
  delay(60000);
  int raw2 = analogRead(35);
  cal.voltage_pH7 = raw2 * (3.3 / 4095.0);
  
  // Calculate slope and intercept: pH = slope * V + intercept
  // Two-point formula: pH = [(pH7 - pH4) / (V7 - V4)] * V + intercept
  cal.slope = (7.0 - 4.0) / (cal.voltage_pH7 - cal.voltage_pH4);
  cal.intercept = 7.0 - (cal.slope * cal.voltage_pH7);
  
  // Store calibration
  EEPROM.writeFloat(4, cal.slope);
  EEPROM.writeFloat(8, cal.intercept);
  EEPROM.commit();
  
  Serial.printf("Calibration complete: pH = %.2f * V + %.2f\n", cal.slope, cal.intercept);
  
  return cal;
}

Step 4: Connect DS18B20 Temperature Sensor

// DS18B20 Wiring (Waterproof version)
DS18B20 → ESP32
  Red wire (VCC)   → 3V3
  Black wire (GND) → GND
  Yellow wire (Data) → GPIO 4 (with 4.7kΩ pull-up resistor to 3V3)

// Circuit Diagram:
//        3V3
//         │
//        4.7kΩ Resistor (pull-up)
//         │
//    GPIO 4 ─── Yellow wire (Data)
//
//    GND ─── Black wire
//    3V3 ─── Red wire

// Physical Installation:
// 1. Submerge probe directly in nutrient solution
// 2. Secure with cable tie
// 3. Position away from heater/chiller (measure solution, not device)

Step 5: Connect HC-SR04 Ultrasonic Water Level Sensor

// HC-SR04 Wiring
HC-SR04 → ESP32
  VCC  → 5V (VIN)
  GND  → GND
  Trig → GPIO 5
  Echo → GPIO 18

// Physical Mounting:
// 1. Mount sensor ABOVE water surface (5-30cm recommended)
// 2. Face sensor straight down (perpendicular to water)
// 3. Avoid foam, turbulence (causes false readings)
// 4. Keep dry (sensor is NOT waterproof)

Step 6: Connect OLED Display (Optional)

// 0.96" OLED Display Wiring (I2C)
OLED Display → ESP32
  VCC  → 3V3
  GND  → GND
  SCL  → GPIO 22 (I2C clock)
  SDA  → GPIO 21 (I2C data)

// I2C address: Usually 0x3C (check with I2C scanner if unsure)

Complete Wiring Diagram:

                      ESP32 DevKit
                    ┌──────────────┐
    TDS Signal ──── │ GPIO 34      │
    pH Signal  ──── │ GPIO 35      │
    Temp Data  ──── │ GPIO 4       │ (with 4.7kΩ pull-up)
    Trig (Level)─── │ GPIO 5       │
    Echo (Level)─── │ GPIO 18      │
    OLED SDA   ──── │ GPIO 21      │
    OLED SCL   ──── │ GPIO 22      │
                    │              │
    5V Power   ──── │ VIN          │ ──── All sensor VCC (5V)
    GND        ──── │ GND          │ ──── All sensor GND
                    │ 3V3          │ ──── DS18B20 VCC, OLED VCC
                    └──────────────┘

Phase 2: Software Programming

Complete Arduino Code

Install Required Libraries:

  1. Open Arduino IDE
  2. Go to Sketch → Include Library → Manage Libraries
  3. Install these libraries:
    • WiFi (built-in for ESP32)
    • OneWire (for DS18B20)
    • DallasTemperature (for DS18B20)
    • Adafruit_SSD1306 (for OLED)
    • Adafruit_GFX (for OLED)
    • PubSubClient (for MQTT – optional)
    • FirebaseESP32 (for Firebase – optional)

Complete Monitoring System Code:

// ESP32 Hydroponic Monitoring System
// By Agriculture Novel - www.agriculturenovel.com

#include <WiFi.h>
#include <HTTPClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>

// ===== WiFi Configuration =====
const char* ssid = "YourWiFiName";          // Replace with your WiFi name
const char* password = "YourWiFiPassword";   // Replace with your WiFi password

// ===== Pin Definitions =====
#define TDS_PIN 34        // TDS sensor analog pin
#define PH_PIN 35         // pH sensor analog pin
#define TEMP_PIN 4        // DS18B20 data pin
#define TRIG_PIN 5        // Ultrasonic trigger pin
#define ECHO_PIN 18       // Ultrasonic echo pin

// ===== Sensor Objects =====
OneWire oneWire(TEMP_PIN);
DallasTemperature tempSensor(&oneWire);

// ===== OLED Display =====
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// ===== Calibration Constants (stored in EEPROM) =====
float tdsCalibration = 833.33;   // TDS calibration factor
float phSlope = -3.5;            // pH slope (from 2-point calibration)
float phIntercept = 21.0;        // pH intercept

// ===== Thresholds =====
struct Thresholds {
  float tds_min = 800;
  float tds_max = 1400;
  float ph_min = 5.5;
  float ph_max = 6.5;
  float temp_min = 18.0;
  float temp_max = 24.0;
  float water_level_min = 15.0;  // cm from sensor to water
} threshold;

// ===== Sensor Data Structure =====
struct SensorData {
  float tds;
  float ph;
  float temperature;
  float waterLevel;
  unsigned long timestamp;
} currentData;

// ===== Alert Tracking =====
unsigned long lastAlertTime = 0;
const unsigned long ALERT_COOLDOWN = 3600000;  // 1 hour between same alerts

void setup() {
  Serial.begin(115200);
  
  // Initialize sensors
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  tempSensor.begin();
  
  // Initialize OLED
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("OLED initialization failed"));
  }
  display.display();
  delay(1000);
  display.clearDisplay();
  
  // Initialize EEPROM
  EEPROM.begin(512);
  loadCalibration();
  
  // Connect to WiFi
  WiFi.begin(ssid, password);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  display.println("Connecting WiFi...");
  display.display();
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("\nWiFi Connected!");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
  
  display.clearDisplay();
  display.setCursor(0,0);
  display.println("WiFi Connected!");
  display.print("IP: ");
  display.println(WiFi.localIP());
  display.display();
  delay(2000);
}

void loop() {
  // Read all sensors
  currentData.tds = readTDS();
  currentData.ph = readPH();
  currentData.temperature = readTemperature();
  currentData.waterLevel = readWaterLevel();
  currentData.timestamp = millis();
  
  // Display on OLED
  updateDisplay();
  
  // Check thresholds and alert
  checkThresholds();
  
  // Send to cloud (every 5 minutes)
  static unsigned long lastCloudUpdate = 0;
  if (millis() - lastCloudUpdate > 300000) {  // 5 minutes
    sendToCloud();
    lastCloudUpdate = millis();
  }
  
  // Serial output for debugging
  printToSerial();
  
  delay(30000);  // Read every 30 seconds
}

// ===== TDS Reading Function =====
float readTDS() {
  int rawValue = analogRead(TDS_PIN);
  float voltage = rawValue * (3.3 / 4095.0);  // ESP32 ADC: 12-bit, 3.3V reference
  float tdsValue = tdsCalibration * voltage;
  
  return tdsValue;
}

// ===== pH Reading Function =====
float readPH() {
  int rawValue = analogRead(PH_PIN);
  float voltage = rawValue * (3.3 / 4095.0);
  
  // Apply calibration: pH = slope * voltage + intercept
  float phValue = (phSlope * voltage) + phIntercept;
  
  // Sanity check (pH must be 0-14)
  if (phValue < 0) phValue = 0;
  if (phValue > 14) phValue = 14;
  
  return phValue;
}

// ===== Temperature Reading Function =====
float readTemperature() {
  tempSensor.requestTemperatures();
  float temp = tempSensor.getTempCByIndex(0);
  
  // Error check (-127 = sensor error)
  if (temp == -127.0) {
    Serial.println("Temperature sensor error!");
    return 20.0;  // Return safe default
  }
  
  return temp;
}

// ===== Water Level Reading Function =====
float readWaterLevel() {
  // Send ultrasonic pulse
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  
  // Read echo
  long duration = pulseIn(ECHO_PIN, HIGH, 30000);  // Timeout 30ms
  
  if (duration == 0) {
    Serial.println("Ultrasonic sensor timeout!");
    return 0;
  }
  
  // Calculate distance in cm
  float distance = duration * 0.034 / 2;
  
  return distance;
}

// ===== Update OLED Display =====
void updateDisplay() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  
  // Line 1: TDS
  display.setCursor(0, 0);
  display.print("TDS: ");
  display.print(currentData.tds, 0);
  display.println(" ppm");
  
  // Line 2: pH
  display.setCursor(0, 12);
  display.print("pH: ");
  display.println(currentData.ph, 2);
  
  // Line 3: Temperature
  display.setCursor(0, 24);
  display.print("Temp: ");
  display.print(currentData.temperature, 1);
  display.println(" C");
  
  // Line 4: Water Level
  display.setCursor(0, 36);
  display.print("Level: ");
  display.print(currentData.waterLevel, 1);
  display.println(" cm");
  
  // Line 5: WiFi Status
  display.setCursor(0, 48);
  if (WiFi.status() == WL_CONNECTED) {
    display.print("WiFi: OK");
  } else {
    display.print("WiFi: LOST");
  }
  
  // Line 6: Last Update
  display.setCursor(0, 56);
  display.print(millis() / 1000);
  display.print(" sec");
  
  display.display();
}

// ===== Check Thresholds & Send Alerts =====
void checkThresholds() {
  String alerts = "";
  
  // TDS out of range
  if (currentData.tds < threshold.tds_min) {
    alerts += "⚠️ TDS LOW (" + String(currentData.tds, 0) + " ppm) - Add nutrients\\n";
  }
  if (currentData.tds > threshold.tds_max) {
    alerts += "⚠️ TDS HIGH (" + String(currentData.tds, 0) + " ppm) - Dilute solution\\n";
  }
  
  // pH out of range
  if (currentData.ph < threshold.ph_min) {
    alerts += "🔴 pH LOW (" + String(currentData.ph, 2) + ") - CRITICAL\\n";
  }
  if (currentData.ph > threshold.ph_max) {
    alerts += "🔴 pH HIGH (" + String(currentData.ph, 2) + ") - CRITICAL\\n";
  }
  
  // Temperature out of range
  if (currentData.temperature < threshold.temp_min) {
    alerts += "❄️ TEMP LOW (" + String(currentData.temperature, 1) + "°C) - Risk of slow growth\\n";
  }
  if (currentData.temperature > threshold.temp_max) {
    alerts += "🔥 TEMP HIGH (" + String(currentData.temperature, 1) + "°C) - Root stress\\n";
  }
  
  // Water level low
  if (currentData.waterLevel > threshold.water_level_min) {
    alerts += "💧 WATER LOW - Refill reservoir\\n";
  }
  
  // Send alerts if any (with cooldown)
  if (alerts.length() > 0 && (millis() - lastAlertTime > ALERT_COOLDOWN)) {
    sendTelegramAlert(alerts);
    lastAlertTime = millis();
  }
}

// ===== Send Data to Cloud =====
void sendToCloud() {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    
    // Example: Send to custom server or Firebase
    String serverURL = "http://your-server.com/api/data";
    
    // Create JSON payload
    String jsonData = "{";
    jsonData += "\"tds\":" + String(currentData.tds, 2) + ",";
    jsonData += "\"ph\":" + String(currentData.ph, 2) + ",";
    jsonData += "\"temperature\":" + String(currentData.temperature, 2) + ",";
    jsonData += "\"water_level\":" + String(currentData.waterLevel, 2) + ",";
    jsonData += "\"timestamp\":" + String(currentData.timestamp);
    jsonData += "}";
    
    http.begin(serverURL);
    http.addHeader("Content-Type", "application/json");
    
    int httpResponseCode = http.POST(jsonData);
    
    if (httpResponseCode > 0) {
      Serial.println("Data sent to cloud: " + String(httpResponseCode));
    } else {
      Serial.println("Cloud upload failed: " + String(httpResponseCode));
    }
    
    http.end();
  }
}

// ===== Send Telegram Alert =====
void sendTelegramAlert(String message) {
  // Telegram Bot API configuration
  String botToken = "YOUR_BOT_TOKEN";  // Get from @BotFather
  String chatID = "YOUR_CHAT_ID";      // Get from @userinfobot
  
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    
    String url = "https://api.telegram.org/bot" + botToken + "/sendMessage";
    url += "?chat_id=" + chatID;
    url += "&text=" + urlEncode(message);
    
    http.begin(url);
    int httpCode = http.GET();
    
    if (httpCode > 0) {
      Serial.println("Alert sent via Telegram");
    } else {
      Serial.println("Telegram alert failed");
    }
    
    http.end();
  }
}

// ===== Serial Print (Debugging) =====
void printToSerial() {
  Serial.println("===== Sensor Readings =====");
  Serial.print("TDS: "); Serial.print(currentData.tds, 2); Serial.println(" ppm");
  Serial.print("pH: "); Serial.println(currentData.ph, 2);
  Serial.print("Temperature: "); Serial.print(currentData.temperature, 1); Serial.println(" °C");
  Serial.print("Water Level: "); Serial.print(currentData.waterLevel, 1); Serial.println(" cm");
  Serial.println("==========================\n");
}

// ===== Load Calibration from EEPROM =====
void loadCalibration() {
  EEPROM.readFloat(0, tdsCalibration);
  EEPROM.readFloat(4, phSlope);
  EEPROM.readFloat(8, phIntercept);
  
  // Sanity check (if EEPROM empty, use defaults)
  if (isnan(tdsCalibration) || tdsCalibration == 0) {
    tdsCalibration = 833.33;
  }
  if (isnan(phSlope)) {
    phSlope = -3.5;
  }
  if (isnan(phIntercept)) {
    phIntercept = 21.0;
  }
  
  Serial.println("Calibration loaded from EEPROM");
}

// ===== URL Encoding Helper =====
String urlEncode(String str) {
  String encoded = "";
  char c;
  char code0;
  char code1;
  for (int i = 0; i < str.length(); i++) {
    c = str.charAt(i);
    if (c == ' ') {
      encoded += '+';
    } else if (isalnum(c)) {
      encoded += c;
    } else {
      code1 = (c & 0xf) + '0';
      if ((c & 0xf) > 9) {
        code1 = (c & 0xf) - 10 + 'A';
      }
      c = (c >> 4) & 0xf;
      code0 = c + '0';
      if (c > 9) {
        code0 = c - 10 + 'A';
      }
      encoded += '%';
      encoded += code0;
      encoded += code1;
    }
  }
  return encoded;
}

Upload Instructions:

  1. Connect ESP32 to computer via USB
  2. Select board: Tools → Board → ESP32 Arduino → ESP32 Dev Module
  3. Select port: Tools → Port → COMx (Windows) or /dev/ttyUSB0 (Linux)
  4. Edit WiFi credentials in code (lines 14-15)
  5. Click Upload button
  6. Wait for “Done uploading” message
  7. Open Serial Monitor (115200 baud) to see sensor readings

Phase 3: Cloud Integration & Mobile App

Option 1: Blynk IoT (Easiest – Recommended for Beginners)

Why Blynk:

  • No coding required for mobile app
  • Drag-and-drop interface builder
  • Real-time graphs
  • Push notifications
  • Free tier available

Setup Steps:

1. Create Blynk Account

  • Download Blynk app (iOS/Android)
  • Sign up at blynk.io
  • Create new template for “Hydroponic Monitor”

2. Add Datastreams

  • TDS (Virtual Pin V0, 0-3000 ppm)
  • pH (Virtual Pin V1, 0-14)
  • Temperature (Virtual Pin V2, 0-40°C)
  • Water Level (Virtual Pin V3, 0-50 cm)

3. Design Mobile Dashboard

  • Add Gauge widget for TDS → Link to V0
  • Add Gauge widget for pH → Link to V1
  • Add Gauge widget for Temperature → Link to V2
  • Add Level widget for Water → Link to V3
  • Add Chart widget for historical trends

4. Add to ESP32 Code:

// Install Blynk library first
#include <BlynkSimpleEsp32.h>

char auth[] = "Your_Blynk_Auth_Token";  // From Blynk app

// In setup()
Blynk.begin(auth, ssid, password);

// In loop() - send data to Blynk
Blynk.run();
Blynk.virtualWrite(V0, currentData.tds);
Blynk.virtualWrite(V1, currentData.ph);
Blynk.virtualWrite(V2, currentData.temperature);
Blynk.virtualWrite(V3, currentData.waterLevel);

Cost: Free (up to 2 devices), ₹1,800/year for unlimited devices

Option 2: Firebase (Google Cloud – Free, Scalable)

Advantages:

  • Completely free (generous quota)
  • Real-time database
  • Unlimited data storage
  • Web + mobile access
  • Google infrastructure reliability

Setup:

// Install FirebaseESP32 library
#include <FirebaseESP32.h>

#define FIREBASE_HOST "your-project.firebaseio.com"
#define FIREBASE_AUTH "your-database-secret"

FirebaseData firebaseData;

// In setup()
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.reconnectWiFi(true);

// In loop() - send data
Firebase.setFloat(firebaseData, "/sensors/tds", currentData.tds);
Firebase.setFloat(firebaseData, "/sensors/ph", currentData.ph);
Firebase.setFloat(firebaseData, "/sensors/temperature", currentData.temperature);
Firebase.setFloat(firebaseData, "/sensors/waterLevel", currentData.waterLevel);

Web Dashboard: Create simple HTML page reading Firebase database

Cost: Free (up to 10 GB/month storage, 360 MB/day downloads)

Option 3: Telegram Bot (Free Alerts)

Why Telegram:

  • Completely free
  • Instant push notifications
  • Works worldwide
  • No app development needed
  • Can control system via commands

Setup Telegram Bot:

  1. Open Telegram, search “@BotFather”
  2. Send /newbot
  3. Choose name: “MyHydroponicBot”
  4. Get bot token: 1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
  5. Start conversation with your bot
  6. Get your chat ID from: https://api.telegram.org/bot<TOKEN>/getUpdates

Code Already Included (see sendTelegramAlert() function)


Real-World Results: Anna’s 14-Month Journey

Performance Metrics

Monitoring Reliability:

MetricManualESP32 SystemImprovement
Monitoring frequency3× daily2,880× daily (30 sec)960× more frequent
Coverage25% of day100% (24/7)4× better
Response time1-16 hours1-5 minutes96% faster
Data points/month2,70086,40032× more data
Historical analysisDifficultEasy (graphs)Transformative

Problem Detection:

14-Month Period:

  • Critical issues detected: 47 (avg 3.4/month)
  • Issues detected before crop damage: 44 (93.6%)
  • Average detection time: 2.1 hours after onset
  • Average response time: 18 minutes
  • Prevented crop losses: ₹8.4 lakh total

Notable Incidents:

1. pH Spike Event (Month 3)

  • Detection: 3:47 AM, pH 8.2 (started 11:30 PM)
  • Response: Remote pH dosing adjustment via phone
  • Time to resolution: 18 minutes
  • Saved: 427 plants, ₹2.4 lakh

2. Temperature Failure (Month 7)

  • Detection: 1:23 PM, temp rising (heater stuck on)
  • Alert: “🔥 TEMP 29.1°C – CRITICAL”
  • Response: Disabled heater circuit, added ice
  • Saved: Entire 2,400 plant operation

3. Low Water (Month 11)

  • Detection: 6:15 AM, level 18cm (critical 15cm)
  • Alert: “💧 WATER LOW – Refill in 2 hours”
  • Response: Scheduled water delivery
  • Prevented: Pump damage (₹12,000), crop stress

Economic Impact

System Cost Breakdown:

Initial Investment:

  • ESP32 + sensors + display: ₹5,100
  • Enclosure + installation: ₹800
  • Backup power (UPS): ₹2,400
  • Total Initial: ₹8,300

Operating Costs (Annual):

  • Electricity (5W × 24h × 365d): ₹315/year
  • Internet (shared): ₹0 (existing WiFi)
  • Cloud services (Blynk): ₹1,800/year
  • Probe replacements (pH): ₹1,500/year (every 12 months)
  • Calibration solutions: ₹400/year
  • Total Annual: ₹4,015/year

Benefits Delivered (14 months):

1. Prevented Losses:

  • Critical events prevented: 47
  • Average loss per event: ₹18,000
  • Total losses prevented: ₹8.46 lakh

2. Labor Savings:

  • Manual monitoring time: 18 hours/week
  • ESP32 monitoring time: 1 hour/week (checking alerts)
  • Time saved: 17 hours/week × 60 weeks = 1,020 hours
  • Value at ₹200/hour: ₹2.04 lakh

3. Optimization Gains:

  • Better nutrient management: ₹14,000/year savings
  • Improved growth rates: ₹28,000/year increased revenue
  • Reduced waste: ₹8,000/year

Total 14-Month Value: ₹10.54 lakh

ROI Calculation:

  • Investment: ₹8,300
  • 14-month benefit: ₹10.54 lakh
  • Net gain: ₹10.46 lakh
  • ROI: 12,602%
  • Payback period: 23 days (first prevented crisis)

Cost per Day:

  • Initial: ₹8,300 / 420 days = ₹19.76/day
  • Operating: ₹4,015 / 365 days = ₹11.00/day
  • Total: ₹30.76/day (₹924/month)

Value per Day:

  • Prevented losses: ₹8.46L / 420 days = ₹2,014/day
  • Labor savings: ₹2.04L / 420 days = ₹486/day
  • Total: ₹2,500/day (₹75,000/month)

Value-to-Cost Ratio: 81:1

Scaling Economics

Multi-Zone System (4 zones on 1 ESP32):

Components:

  • 1× ESP32: ₹800
  • 4× TDS sensors: ₹3,200
  • 4× pH sensors: ₹6,000
  • 4× DS18B20: ₹1,200
  • 4× Ultrasonic: ₹800
  • 1× 16-channel multiplexer: ₹400
  • Display, enclosure, power: ₹1,400
  • Total: ₹13,800

Cost per Zone: ₹3,450 (73% cheaper than separate systems)

10-Zone Farm (₹34,500 total):

  • 3× ESP32 boards (each monitoring 3-4 zones)
  • Centralized dashboard showing all zones
  • Cost per zone: ₹3,450

Troubleshooting Guide

Common Problems & Solutions

Problem: TDS readings erratic (jumping 200+ ppm)

Causes:

  • Poor probe contact
  • Air bubbles on probe
  • Electrical noise from pumps

Solutions:

  • Ensure probe fully submerged (5cm minimum)
  • Install probe away from pumps (30cm minimum)
  • Add 100nF ceramic capacitor across sensor signal and ground
  • Average 10 readings: tds = (reading1 + reading2 + ... + reading10) / 10

Problem: pH readings drift over time

Causes:

  • Probe dried out
  • Probe contamination
  • Need recalibration

Solutions:

  • Store probe in pH 4.0 storage solution between uses
  • Clean probe monthly: Soak in distilled water 30 min, gentle brush
  • Calibrate weekly with pH 4.0 and 7.0 buffers
  • Replace probe annually (₹1,200-1,800)

Problem: Temperature sensor returns -127.0°C

Causes:

  • Loose connection
  • Missing pull-up resistor
  • Damaged sensor

Solutions:

  • Check wiring: Data, VCC, GND all secure
  • Verify 4.7kΩ resistor between data pin and 3V3
  • Test with different sensor (₹300 replacement)

Problem: WiFi disconnects frequently

Causes:

  • Weak signal
  • Router issues
  • ESP32 power brownout

Solutions:

  • Move ESP32 closer to router or add WiFi extender
  • Use external antenna on ESP32 (₹200)
  • Increase power supply to 5V 2A (not 1A)
  • Add auto-reconnect code:
void checkWiFi() {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi lost, reconnecting...");
    WiFi.reconnect();
    delay(5000);
  }
}

// Call in loop()
checkWiFi();

Problem: System reboots randomly

Causes:

  • Insufficient power
  • Watchdog timer reset
  • Memory overflow

Solutions:

  • Use quality 5V 2A power supply (not phone charger)
  • Add watchdog disable: disableCore0WDT(); in setup()
  • Check memory usage: Serial.println(ESP.getFreeHeap());

Advanced Features & Upgrades

1. Automated Control (Relay Integration)

Add Control Capability:

// Add relay control
#define PUMP_RELAY 27
#define HEATER_RELAY 26
#define PH_UP_PUMP 25
#define PH_DOWN_PUMP 33

void setup() {
  pinMode(PUMP_RELAY, OUTPUT);
  pinMode(HEATER_RELAY, OUTPUT);
  pinMode(PH_UP_PUMP, OUTPUT);
  pinMode(PH_DOWN_PUMP, OUTPUT);
}

void automatedControl() {
  // Auto pH adjustment
  if (currentData.ph < 5.8) {
    digitalWrite(PH_UP_PUMP, HIGH);
    delay(1000);  // 1 second dose
    digitalWrite(PH_UP_PUMP, LOW);
  }
  
  if (currentData.ph > 6.2) {
    digitalWrite(PH_DOWN_PUMP, HIGH);
    delay(1000);
    digitalWrite(PH_DOWN_PUMP, LOW);
  }
  
  // Auto temperature control
  if (currentData.temperature < 19.0) {
    digitalWrite(HEATER_RELAY, HIGH);  // Turn on heater
  } else if (currentData.temperature > 23.0) {
    digitalWrite(HEATER_RELAY, LOW);   // Turn off heater
  }
}

Cost: ₹400 (4-channel relay module)

2. Data Logging to SD Card (Offline Backup)

#include <SD.h>
#include <SPI.h>

#define SD_CS 5  // SD card chip select pin

void setup() {
  if (!SD.begin(SD_CS)) {
    Serial.println("SD card initialization failed!");
  }
}

void logToSD() {
  File dataFile = SD.open("hydro_log.csv", FILE_APPEND);
  
  if (dataFile) {
    // Write CSV format: timestamp,tds,ph,temp,level
    dataFile.print(millis());
    dataFile.print(",");
    dataFile.print(currentData.tds);
    dataFile.print(",");
    dataFile.print(currentData.ph);
    dataFile.print(",");
    dataFile.print(currentData.temperature);
    dataFile.print(",");
    dataFile.println(currentData.waterLevel);
    
    dataFile.close();
    Serial.println("Data logged to SD card");
  }
}

Cost: ₹150 (MicroSD module + 16GB card)

3. Battery Backup with Solar

Solar Power System:

  • 10W solar panel: ₹850
  • 18650 Li-ion battery (3× 3.7V): ₹450
  • TP4056 charging module: ₹80
  • DC-DC boost converter (5V): ₹120
  • Total: ₹1,500

Runtime: 24-48 hours on battery, indefinite with solar


Conclusion: The Real-Time Revolution

At 8:42 PM, as Anna reviewed her weekly monitoring dashboard from her smartphone while attending her daughter’s school play 45km away, the ESP32 Smart Monitoring System displayed something extraordinary: across 14 months and 4.2 million sensor readings, the ₹8,300 platform had detected 47 critical issues averaging 2.1 hours after onset, enabled remote responses within 18 minutes average, prevented ₹8.46 lakh in crop losses, and fundamentally transformed hydroponics from reactive guesswork to proactive data-driven precision.

The Monitoring Transformation Reality:

Modern agriculture isn’t about expensive commercial monitoring systems costing ₹50,000-₹2,00,000—it’s about intelligent DIY platforms built with ₹3,500-8,300 in components delivering equivalent functionality through open-source software, cloud connectivity, and real-time visibility that eliminates the blind periods where disasters develop unseen. The ESP32 represents democratization of agricultural technology: professional-grade monitoring accessible to every grower, regardless of budget.

The Economic Imperative:

Anna’s ESP32 implementation required:

  • Capital: ₹8,300 (hardware + installation)
  • Time: 6-8 hours (assembly + programming)
  • Skills: Basic electronics knowledge (learnable in 2-3 days)
  • Operating Cost: ₹4,015/year (electricity + cloud + maintenance)

The transformation delivered:

  • 24/7 Monitoring: 2,880 readings/day vs 3 manual checks
  • Early Detection: 2.1 hours average vs 1-16 hours manual
  • Response Speed: 18 minutes vs 4-12 hours
  • Prevented Losses: ₹8.46 lakh (14 months)
  • ROI: 12,602%
  • Payback: 23 days

The Strategic Insight:

ESP32-based monitoring transforms agriculture from blind intervals of uncertainty to continuous intelligent surveillance. Problems are detected before they cause damage. Trends are identified before they become crises. Remote management enables oversight from anywhere. Data-driven optimization replaces guesswork. The result: consistent yields, prevented disasters, and operational confidence impossible with manual monitoring alone.

As Erik checked the evening sensor readings remotely from a business meeting 120km away—noting pH 6.1, TDS 1180 ppm, temperature 21.4°C, water level optimal—Anna reflected on the fundamental shift: “We’re no longer farmers who check systems. We’re data-driven operators who are alerted when intervention is needed. The ESP32 watches 24/7 so we can focus on growing better crops, not constantly monitoring sensors.”

The real-time monitoring revolution isn’t coming to hydroponics. It’s already here, watching over crops for ₹8,300.


Technical Resources & Support

Hardware Suppliers (India)

ESP32 Boards:

  • RoboElements.in: ₹750-900
  • Robu.in: ₹650-850
  • Amazon.in: ₹700-1,200

Sensors:

  • pH/TDS sensors: RoboMall.in, Amazon.in
  • Temperature sensors: Robu.in
  • Complete kits: Agriculture Novel (₹4,500-6,500)

Software Resources

Arduino IDE: arduino.cc/en/software (free) ESP32 Libraries: github.com/espressif/arduino-esp32 Blynk: blynk.io Firebase: firebase.google.com Telegram Bot: core.telegram.org/bots

Agriculture Novel Support

Contact Information:

  • ESP32 Consulting: esp32@agriculturenovel.com
  • Technical Support: +91-9876543210
  • WhatsApp: Get instant hydroponic monitoring help
  • Website: www.agriculturenovel.com/esp32-monitoring

Services Offered:

  • Pre-assembled ESP32 monitoring kits
  • Custom sensor configurations
  • Programming and setup assistance
  • Cloud platform integration
  • On-site installation (select areas)
  • 24/7 technical support

ESP32 Monitoring Packages:

  • Basic Kit (₹4,500): ESP32 + TDS + Temp + Level sensors
  • Professional Kit (₹6,500): Full system with pH + display
  • Multi-Zone Kit (₹13,800): 4-zone monitoring
  • Installation Service (₹2,500): Professional setup + training

Tags: #ESP32Hydroponics #RealTimeMonitoring #TDSSensor #pHSensor #TemperatureSensor #WaterLevel #IoTAgriculture #SmartFarming #DIYAutomation #HydroponicMonitoring #AgTech #Arduino #CloudMonitoring #TelegramAlerts #BlynkIoT #Firebase #AgricultureNovel #PrecisionAgriculture #SensorIntegration #RemoteMonitoring

Related Posts

Leave a Reply

Discover more from Agriculture Novel

Subscribe now to keep reading and get access to the full archive.

Continue reading