ESP32 irrigation system

I have a project using ESP32 where I fetch irrigation data from a database hosted on AWS. Based on the fetched irrigation data, I control a water pump to perform irrigation. Additionally, I collect data from a DHT11 sensor and a soil moisture sensor and successfully send these readings to the database.

The issue arises with fetching data and controlling the water pump. While sending data works perfectly, fetching data and triggering the irrigation process is inconsistent. Sometimes the system fetches data and irrigates properly, but other times it fails to fetch the data, leading to no irrigation.

#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <DHT.h>

// Wi-Fi Settings
const char* ssid = "........";
const char* password = " ";

// User-defined Server IP
String serverIP = ".........eu-north-1.compute.amazonaws.com:80";
bool useDynamicIP = false; // Set to true if using dynamic IP

// DHT Settings
#define DHTPIN 26    
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// Soil Moisture Sensor
#define SOIL_MOISTURE_PIN 14

// Motor Driver Pins (For L298N or similar)
#define MOTOR_IN1 32
#define MOTOR_IN2 33
#define MOTOR_ENA 25 // For PWM control

String sensorSerialNumber = "qwe"; // Example serial number

// Irrigation Info
int irrigationAmount = 0; // Irrigation amount (ml)
int wateringFrequency = 0; // Watering frequency per week
unsigned long irrigationInterval = 0; // Irrigation interval (milliseconds)
unsigned long lastIrrigationTime = 0; // Last irrigation timestamp

// Generate Base URL Based on Dynamic or Static Server IP
String getBaseURL() {
  if (useDynamicIP) {
    String dynamicIP = WiFi.localIP().toString();
    return "http://" + dynamicIP + "/api";
  } else {
    return "http://" + serverIP + "/api";
  }
}

// Function: Perform Irrigation
void performIrrigation(int amount) {
  if (amount > 0) {
    Serial.println("Irrigation started!");
    Serial.print(amount);
    Serial.println(" ml irrigation in progress...");

    // Calculate operation time based on irrigation amount
    unsigned long operationTime = amount * 80; // 80 ms per 1 ml

    digitalWrite(MOTOR_IN1, HIGH);
    digitalWrite(MOTOR_IN2, LOW);
    analogWrite(MOTOR_ENA, 100);

    delay(operationTime); // Wait based on operation time

    digitalWrite(MOTOR_IN1, LOW);
    digitalWrite(MOTOR_IN2, LOW);
    analogWrite(MOTOR_ENA, 0);

    Serial.println("Irrigation completed!");
    lastIrrigationTime = millis(); // Update last irrigation time
  } else {
    Serial.println("Invalid irrigation amount, no operation performed.");
  }
}

// Function: Fetch Irrigation Info from Server
void fetchIrrigationInfo(String sensorSerialNumber) {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    String serverNameGet = getBaseURL() + "/Plant/PlantBySensorSerialNumber/" + sensorSerialNumber;
    http.begin(serverNameGet);

    int httpResponseCode = http.GET();

    if (httpResponseCode > 0) {
      String payload = http.getString();
      Serial.println("Received Irrigation Info: " + payload);

      StaticJsonDocument<256> jsonDoc;
      DeserializationError error = deserializeJson(jsonDoc, payload);

      if (!error) {
        irrigationAmount = jsonDoc["irrigationAmount"];
        wateringFrequency = jsonDoc["wateringFrequency"];

        if (wateringFrequency == 1) {
          irrigationInterval = 7UL * 24UL * 60UL * 60UL * 1000UL; // Weekly
        } else if (wateringFrequency == 2) {
          irrigationInterval = 3.5 * 24UL * 60UL * 60UL * 1000UL; // Half-week
        } else {
          irrigationInterval = 0; // Invalid value
        }
        Serial.print("Irrigation Interval (ms): ");
        Serial.println(irrigationInterval);

        // Start irrigation after successfully fetching irrigation info
       // performIrrigation(irrigationAmount);
      } else {
        Serial.println("Error parsing irrigation info JSON!");
      }
    } else {
      Serial.print("Failed to fetch irrigation info. HTTP Error: ");
      Serial.println(httpResponseCode);
    }

    http.end();
  } else {
    Serial.println("No Wi-Fi connection, unable to fetch irrigation info.");
  }
}

// Function: Send Sensor Data to Server
void sendData(int soilMoisture, int airHumidity, int temperature, String sensorSerialNumber) {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    String serverNamePost = getBaseURL() + "/SensorDataLog/AddSensorDataLog";
    http.begin(serverNamePost);

    StaticJsonDocument<1024> jsonDoc;
    jsonDoc["sensorSerialNumber"] = sensorSerialNumber;
    jsonDoc["temperature"] = temperature;
    jsonDoc["moisture"] = airHumidity;
    jsonDoc["soilMoisture"] = soilMoisture;

    String jsonData;
    serializeJson(jsonDoc, jsonData);
    Serial.println("Sent JSON Data: " + jsonData);

    http.addHeader("Content-Type", "application/json");
    int httpResponseCode = http.POST(jsonData);

    if (httpResponseCode > 0) {
      Serial.print("Data successfully sent. HTTP Response Code: ");
      Serial.println(httpResponseCode);
    } else {
      Serial.print("Data send error: ");
      Serial.println(httpResponseCode);
    }

    http.end();
  } else {
    Serial.println("No Wi-Fi connection, unable to send data.");
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println("System Starting...");

  dht.begin();

  WiFi.begin(ssid, password);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWi-Fi connection successful!");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  pinMode(MOTOR_IN1, OUTPUT);
  pinMode(MOTOR_IN2, OUTPUT);
  pinMode(MOTOR_ENA, OUTPUT);

  digitalWrite(MOTOR_IN1, LOW);
  digitalWrite(MOTOR_IN2, LOW);
  analogWrite(MOTOR_ENA, 0);

  fetchIrrigationInfo(sensorSerialNumber);
}

void loop() {
  int temperature = dht.readTemperature();
  int humidity = dht.readHumidity();
  int soilMoisturePercentage = 100.0;

  if (isnan(temperature) || isnan(humidity)) {
    Serial.println("DHT11 Data Unavailable! Check connections.");
  } else {
    Serial.print("Temperature: ");
    Serial.print(temperature);
    Serial.print(" °C    Humidity: ");
    Serial.print(humidity);
    Serial.println(" %");

    Serial.print("Soil Moisture Level (%): ");
    Serial.print(soilMoisturePercentage);
    Serial.println(" %");

    sendData(soilMoisturePercentage, humidity, temperature, sensorSerialNumber);
  }

  if (irrigationInterval > 0 && millis() - lastIrrigationTime >= irrigationInterval) {
    performIrrigation(irrigationAmount);
  }

  delay(10000); // 10-second loop
}

Is there a way to tell in your code if it failed? If so, try again. I would have a retry logic of try 5 times 10 secs apart, wait 15 mins, try 5 times 10 secs apart, wait 15 mins. Either do that until you get the data, or after a certain number of tries send a MQTT message so you can intervene.

1 Like

And you know this how?

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.