OC
OceanRemote
Low-code IoT platform
← Back to Course

Data-Driven Irrigation Decisions

Data-Driven Irrigation Decisions

πŸ’§ Data-Driven Irrigation Decisions - Smart Water Management

🌾 What You'll Learn in This Lesson:

  • πŸ“Š Make data-driven irrigation decisions using soil moisture + weather data
  • πŸ’§ Save 30-50% water by irrigating only when needed
  • 🌧️ Integrate rain forecasts to avoid wasting water
  • πŸ“ˆ Optimize crop yield with perfect soil moisture levels
  • πŸ€– Build an automated decision engine for your farm

πŸ“Š Why Data-Driven Irrigation Matters

Traditional Irrigation Data-Driven Irrigation
❌ Water on fixed schedule (e.g., every day at 6 AM) βœ… Water only when soil moisture drops below threshold
❌ Wastes water when raining or soil already wet βœ… Integrates rain forecast - skips irrigation when rain expected
❌ Over-watering causes root rot, under-watering reduces yield βœ… Maintains optimal moisture range for each crop type
❌ 30-50% water typically wasted βœ… Up to 50% water savings, 20-30% yield increase
πŸ’‘ The Cost of Over-Watering:

Over-watering is worse than under-watering! It causes:

  • 🌱 Root rot and fungal diseases
  • πŸ’§ Nutrient leaching (washing away fertilizers)
  • πŸ’° Higher water bills and energy costs
  • 🌍 Environmental damage from runoff

🎯 The Complete Irrigation Decision Matrix

Soil Moisture Rain Forecast (24h) Temperature Action Water Duration
< 20% (Critical) Any Any 🚨 EMERGENCY WATER - Immediate! 15-20 minutes
20-35% (Dry) None or < 5mm < 35Β°C πŸ’§ Water Now 10-15 minutes
20-35% (Dry) β‰₯ 10mm expected Any ⏸️ Skip irrigation - rely on rain 0 minutes
35-50% (Adequate) Any < 35Β°C βœ… Monitor only - no action 0 minutes
35-50% (Adequate) Any β‰₯ 35Β°C (Heat wave) πŸ’§ Light cooling irrigation (stress prevention) 3-5 minutes
50-70% (Optimal) Any Any βœ… No irrigation needed - perfect conditions 0 minutes
70-85% (Wet) Any Any ⚠️ Stop irrigation - drying needed 0 minutes
> 85% (Flooded) Any Any 🚨 CRITICAL ALERT - Risk of root rot! Improve drainage 0 minutes

🌧️ Rain Forecast Integration

πŸ’‘ Smart farmers don't water before rain!

Integrating weather forecasts is the #1 way to save water. Always check:

  • Next 24 hours: If β‰₯ 10mm rain expected β†’ Skip irrigation entirely
  • Next 48 hours: If β‰₯ 15mm rain expected β†’ Reduce irrigation by 50%
  • High wind forecast: Increase irrigation by 20% (wind increases evaporation)

🌑️ Temperature Adjustments

Temperature Range Effect on Plants Irrigation Adjustment
< 15Β°CSlow growth, low water needs⬇️ Reduce by 40%
15-25Β°COptimal growthβœ… Normal schedule
25-32Β°CGood growth, higher transpiration⬆️ Increase by 20%
32-38Β°CHeat stress begins⬆️ Increase by 40% + light cooling
> 38°CCritical heat stress🚨 Emergency cooling irrigation

πŸ“ˆ Crop-Specific Moisture Thresholds

Crop Optimal Range (%) Water When Below (%) Critical Below (%)
πŸ… Tomatoes45-70%40%25%
🌢️ Peppers45-70%40%25%
πŸ₯’ Cucumbers50-75%45%30%
πŸ₯¬ Lettuce50-80%45%30%
🌽 Corn40-65%35%20%
πŸ† Eggplant45-70%40%25%
πŸ₯• Carrots40-65%35%20%
πŸ§… Onions35-60%30%15%
πŸ“ Strawberries50-75%45%30%
🌿 Basil/Herbs45-70%40%25%

πŸ’» Arduino Code: Smart Irrigation Decision Engine

/*
 * Smart Irrigation Decision Engine
 * Combines soil moisture, temperature, and rain forecast
 * 
 * Features:
 * - Automatic irrigation based on 5+ data points
 * - Rain forecast integration (saves water)
 * - Temperature compensation
 * - Crop-specific thresholds
 */

#include 

// ========== PIN DEFINITIONS ==========
#define SOIL_PIN 32        // Soil moisture sensor
#define RELAY_PIN 5        // Water pump relay
#define DHT_PIN 4          // DHT22 temperature/humidity

// ========== CALIBRATION VALUES (CALIBRATE THESE!) ==========
const int DRY_VALUE = 3800;
const int WET_VALUE = 1500;

// ========== CROP CONFIGURATION ==========
struct CropConfig {
    const char* name;
    int optimalMin;
    int optimalMax;
    int waterThreshold;    // Water when below this
    int criticalPoint;     // Emergency below this
};

CropConfig crops[] = {
    {"Tomatoes", 45, 70, 40, 25},
    {"Peppers", 45, 70, 40, 25},
    {"Corn", 40, 65, 35, 20},
    {"Lettuce", 50, 80, 45, 30},
    {"Default", 40, 70, 35, 20}
};

int currentCrop = 0; // Index of selected crop

// ========== WEATHER FORECAST ==========
float rainForecastMM = 0;    // mm of rain expected in 24h
bool heatWaveWarning = false;

// ========== IRRIGATION SETTINGS ==========
const int BASE_WATER_DURATION = 600;  // 10 minutes base
const int MAX_WATER_DURATION = 1200;  // 20 minutes max
const int MIN_WATER_DURATION = 180;    // 3 minutes min

// Read soil moisture and return percentage
int readSoilMoisture() {
    int raw = analogRead(SOIL_PIN);
    int percentage = map(raw, DRY_VALUE, WET_VALUE, 0, 100);
    percentage = constrain(percentage, 0, 100);
    return percentage;
}

// Calculate optimal water duration based on multiple factors
int calculateWaterDuration(int moisture, float temperature, float rainMM) {
    CropConfig crop = crops[currentCrop];
    int duration = 0;
    
    // Factor 1: Soil moisture deficit
    if (moisture < crop.criticalPoint) {
        duration = MAX_WATER_DURATION;
    } else if (moisture < crop.waterThreshold) {
        int deficit = crop.waterThreshold - moisture;
        duration = BASE_WATER_DURATION + (deficit * 10);
        duration = constrain(duration, MIN_WATER_DURATION, MAX_WATER_DURATION);
    }
    
    // Factor 2: Temperature adjustment
    if (temperature > 35) {
        duration = duration * 1.4;  // 40% increase for heat wave
    } else if (temperature > 32) {
        duration = duration * 1.2;  // 20% increase for heat
    } else if (temperature < 15) {
        duration = duration * 0.6;  // 40% reduction for cold
    }
    
    // Factor 3: Rain forecast adjustment
    if (rainMM > 15) {
        duration = 0;  // Skip completely if heavy rain
    } else if (rainMM > 8) {
        duration = duration * 0.5;  // 50% reduction if moderate rain
    } else if (rainMM > 3) {
        duration = duration * 0.7;  // 30% reduction if light rain
    }
    
    return constrain(duration, 0, MAX_WATER_DURATION);
}

// Get decision message
String getDecisionMessage(int moisture, float rainMM, float temperature) {
    CropConfig crop = crops[currentCrop];
    
    if (moisture < crop.criticalPoint) {
        return "🚨 CRITICAL: Soil extremely dry! Emergency irrigation required!";
    }
    if (moisture < crop.waterThreshold) {
        if (rainMM > 15) {
            return "⏸️ Soil dry but heavy rain expected - skipping irrigation, relying on rain";
        } else if (rainMM > 8) {
            return "πŸ’§ Soil dry - irrigating at 50% due to forecast rain";
        } else {
            return "πŸ’§ Soil below threshold - starting irrigation";
        }
    }
    if (moisture >= crop.optimalMin && moisture <= crop.optimalMax) {
        return "βœ… Optimal soil moisture - no action needed";
    }
    if (moisture > crop.optimalMax) {
        return "⚠️ Soil too wet - stop irrigation, check drainage";
    }
    return "πŸ“Š Monitoring - conditions normal";
}

// Display complete irrigation report
void displayIrrigationReport(int moisture, int duration, float temp, float rainMM) {
    CropConfig crop = crops[currentCrop];
    
    Serial.println("╔══════════════════════════════════════════════════════════════╗");
    Serial.println("β•‘              πŸ’§ IRRIGATION DECISION REPORT                    β•‘");
    Serial.println("β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•");
    Serial.println("");
    
    Serial.println("πŸ“Š CURRENT CONDITIONS:");
    Serial.printf("   🌱 Crop: %s\n", crop.name);
    Serial.printf("   πŸ’§ Soil Moisture: %d%%\n", moisture);
    Serial.printf("   🌑️ Temperature: %.1f°C\n", temp);
    Serial.printf("   🌧️ Rain Forecast (24h): %.1f mm\n", rainMM);
    Serial.println("");
    
    Serial.println("πŸ“‹ CROP THRESHOLDS:");
    Serial.printf("   🟒 Optimal range: %d-%d%%\n", crop.optimalMin, crop.optimalMax);
    Serial.printf("   🟑 Water below: %d%%\n", crop.waterThreshold);
    Serial.printf("   πŸ”΄ Critical below: %d%%\n", crop.criticalPoint);
    Serial.println("");
    
    Serial.println("🎯 DECISION:");
    Serial.printf("   %s\n", getDecisionMessage(moisture, rainMM, temp).c_str());
    
    if (duration > 0) {
        Serial.printf("   πŸ’§ Watering duration: %d seconds (%d minutes)\n", duration, duration/60);
    }
    Serial.println("");
    Serial.println("══════════════════════════════════════════════════════════════════\n");
}

void setup() {
    Serial.begin(115200);
    pinMode(RELAY_PIN, OUTPUT);
    digitalWrite(RELAY_PIN, HIGH);  // Pump OFF initially
    
    Serial.println("========================================");
    Serial.println("πŸ’§ SMART IRRIGATION DECISION ENGINE v2.0");
    Serial.println("   Data-driven watering decisions");
    Serial.println("========================================\n");
}

void loop() {
    // Read sensors
    int moisture = readSoilMoisture();
    
    // In real implementation, get temperature from DHT22
    float temperature = 26.5;  // Replace with actual sensor reading
    float rainForecast = 0;    // Replace with API call to weather service
    
    // Calculate water duration
    int waterDuration = calculateWaterDuration(moisture, temperature, rainForecast);
    
    // Generate report
    displayIrrigationReport(moisture, waterDuration, temperature, rainForecast);
    
    // Execute irrigation if needed
    if (waterDuration > 0) {
        Serial.printf("πŸ’§ Activating pump for %d seconds...\n", waterDuration);
        digitalWrite(RELAY_PIN, LOW);   // Pump ON
        delay(waterDuration * 1000);
        digitalWrite(RELAY_PIN, HIGH);  // Pump OFF
        Serial.println("βœ… Irrigation complete\n");
    }
    
    // Wait before next check (default: 1 hour = 3,600,000 ms)
    delay(3600000);
}
    

πŸ“± API Integration for Real-Time Weather Data

/*
 * Fetch real-time weather forecast from OpenWeatherMap API
 * Integrate with your irrigation decision engine
 */

#include 
#include 
#include 

const char* ssid = "YOUR_WIFI";
const char* password = "YOUR_PASSWORD";
const char* apiKey = "YOUR_OPENWEATHER_API_KEY";
const char* city = "Nairobi,KE";

struct WeatherForecast {
    float temp;
    float humidity;
    float rainMM;      // mm of rain expected
    int windSpeed;     // km/h
    String condition;
};

WeatherForecast getWeatherForecast() {
    WeatherForecast forecast = {0, 0, 0, 0, "clear"};
    
    if (WiFi.status() == WL_CONNECTED) {
        HTTPClient http;
        String url = "http://api.openweathermap.org/data/2.5/weather?q=" + String(city) + "&appid=" + apiKey + "&units=metric";
        http.begin(url);
        int httpCode = http.GET();
        
        if (httpCode == 200) {
            String payload = http.getString();
            DynamicJsonDocument doc(2048);
            deserializeJson(doc, payload);
            
            forecast.temp = doc["main"]["temp"];
            forecast.humidity = doc["main"]["humidity"];
            
            // Check for rain
            if (doc.containsKey("rain")) {
                forecast.rainMM = doc["rain"]["1h"].as();
            }
            
            // Get weather condition
            const char* condition = doc["weather"][0]["main"];
            forecast.condition = String(condition);
        }
        http.end();
    }
    
    return forecast;
}
    
πŸ“– Real Farm Case Study - Moroccan Tomato Greenhouse:

A 2-hectare tomato farm implemented data-driven irrigation decisions:

  • πŸ’§ Before: Fixed irrigation schedule - watered 2 hours daily
  • πŸ“Š After: Smart system only when moisture < 40% + rain check
  • πŸ’§ Water saved: 45% reduction (saved 2,000 mΒ³/month)
  • πŸ’° Cost saved: $180/month on water + electricity
  • 🌱 Yield: 25% increase (less over-watering stress)

"The decision matrix changed everything. We now irrigate only when needed, and the rain forecast feature has saved us thousands." - Greenhouse Manager, Morocco

πŸ’‘ Pro Tips for Best Results:
  • πŸ“ Soil moisture sensors - Install at root depth (10-30cm), not surface
  • πŸ“ Multiple sensors - Use 3-5 sensors per zone and average readings
  • πŸ“ Rain gauge - Install physical rain gauge to validate forecasts
  • πŸ“ Morning watering - Best time is 5-7 AM to reduce evaporation
  • πŸ“ Keep records - Log all decisions to refine thresholds over time
πŸŽ‰ Congratulations!

You now have a complete data-driven irrigation decision system!

  • βœ… Decision matrix for any soil moisture + weather combination
  • βœ… Crop-specific thresholds for optimal growth
  • βœ… Temperature + rain forecast integration
  • βœ… Complete Arduino code for automation
  • βœ… Save 30-50% water while increasing yields
πŸ“‹ Quick Reference - Daily Irrigation Decision Flow:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    DAILY IRRIGATION DECISION FLOW                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                         β”‚
β”‚  1. Read soil moisture sensor                                           β”‚
β”‚         ↓                                                               β”‚
β”‚  2. Check rain forecast (24h)                                           β”‚
β”‚         ↓                                                               β”‚
β”‚  3. Check current temperature                                           β”‚
β”‚         ↓                                                               β”‚
β”‚  4. Apply decision matrix:                                              β”‚
β”‚                                                                         β”‚
β”‚     Moisture < 20%?  ──YES──→ EMERGENCY WATER (15-20 min)              β”‚
β”‚          ↓ NO                                                           β”‚
β”‚     Moisture < threshold? ──YES──→ Check rain forecast                 β”‚
β”‚          ↓ NO                           ↓                               β”‚
β”‚     Moisture optimal? ──YES──→ No action needed!                        β”‚
β”‚                              Rain > 10mm? ──YES──→ Skip irrigation      β”‚
β”‚                                   ↓ NO                                  β”‚
β”‚                              β†’ Water (10-15 min)                        β”‚
β”‚                                                                         β”‚
β”‚  5. Adjust for temperature (hot = more water, cold = less)              β”‚
β”‚  6. Execute irrigation if needed                                        β”‚
β”‚  7. Log decision for future analysis                                    β”‚
β”‚                                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
πŸ’‘ Key Takeaways:
  • Apply these concepts directly to your farm or project.
  • Take notes on important details for the quiz.
  • Use the button below to track your progress.