vivek_m
Published © GPL3+

Automated Irrigation System Based on Weather Forecast

A smart approach in watering plants to effectively utilize rainwater using weather forecast data.

IntermediateProtip1,891
Automated Irrigation System Based on Weather Forecast

Things used in this project

Hardware components

NODEMCU - ESP8266 Wifi
×1
Soil Moisture Sensor
×1
Submersible Mini Water Pump - 3-6V DC
×1
NPN Bipolar Transistor(2N2222A)
×1
Resistor 1k ohm
Resistor 1k ohm
×1

Software apps and online services

Blynk
Blynk

Story

Read more

Schematics

Breadboard view

This is a smart plant circuit diagram

Schematic View

Code

[Code-1] Soil Moisture test

Arduino
This code helps you to test soil moisture sensor and set predetermined values for Dryness and Extreme Dryness threshold.
const int moistureSensorPin = A0;
int moistureSensorValue = 0; 
void setup() {
  Serial.begin(115200);  
  pinMode(moistureSensorPin, INPUT);
}

void loop() {
  moistureSensorValue = analogRead(moistureSensorPin);              //read the values of the moisture Sensor
  Serial.print("Moisture level sensor value: ");                    //prints it to the serial monitor
  Serial.println(moistureSensorValue);
  delay(1000);    

}

[Code-2] Water Pump test

Arduino
This code helps to test your actuator(water pump) and adjust amount of water to be pumped to the plant.
const int pumpPin = D1; 
int amountToPump = 5000; 
void setup()
      {
  
          Serial.begin(115200);  
          pinMode(pumpPin, OUTPUT);   
      }
void loop ()
{
       digitalWrite(pumpPin, HIGH);
       Serial.println("pump on");
       delay(amountToPump);           //keep pumping water for 5 sec
       digitalWrite(pumpPin, LOW);
       Serial.println("pump off");
       delay(10000);
}

[Code-3] Get Time from NTP server

Arduino
This code will get the real time data from the NTP server and store the hour in variable name H
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char *ssid     = "Galaxy";        //change Galaxy to your wifi name
const char *password = "12345678901";   //change 12345678901 to your wifi password

const long utcOffsetInSeconds = 19800;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
void setup()
{
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while ( WiFi.status() != WL_CONNECTED ) 
  {
    delay ( 500 );
    Serial.print ( "." );
  }
  timeClient.begin();
}

void loop() 
{
  timeClient.update();
  Serial.print("Time: "); 
  Serial.println(timeClient.getFormattedTime());
  int H=timeClient.getHours();
  Serial.print("H= ");
  Serial.println(H);
  delay(1000);
}

[Code-4] Grab Forecast Data

Arduino
This code is used to get weather forecast data from the weatherapi server
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>
#include <WiFiUdp.h>
#include <NTPClient.h>

const char* ssid = "Galaxy";
const char* password = "12345678901";

const long utcOffsetInSeconds = 19800;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

String openWeatherMapApiKey = "d33c5770088a432699242527210952";   // Enter your APi key
String city = "Mudbidri";   // Replace with your country code and city

unsigned long lastTime = 0;
unsigned long timerDelay = 10000;   // every 10 second we get weather data from the server
String jsonBuffer;

void setup() 
{
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
  Serial.println("Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.");
  timeClient.begin();
}
void loop() 
{
  if ((millis() - lastTime) > timerDelay) 
  {
    if(WiFi.status()== WL_CONNECTED)    // Check WiFi connection status
    {
      timeClient.update();
      Serial.println(timeClient.getFormattedTime());
      int H=timeClient.getHours();
      String serverPath = "http://api.weatherapi.com/v1/forecast.json?key=" + openWeatherMapApiKey + "&q=" + city + "&day=1&hour=" + H ;
      jsonBuffer = httpGETRequest(serverPath.c_str());  
      JSONVar myObject = JSON.parse(jsonBuffer);
      if (JSON.typeof(myObject) == "undefined") 
      {
        Serial.println("Parsing input failed!");
        return;
      }
      Serial.print("JSON object = ");
      Serial.println(myObject);
         
      Serial.print("Time: ");   //Forecasted data time
      Serial.println(timeClient.getFormattedTime());

      Serial.print("Location:");      //Forecasted location
      Serial.println(myObject ["location"]["name"]); 
      
      double Temperature = myObject ["current"]["temp_c"];  //current temperature value
      Serial.print("Current Temperature = ");
      Serial.println(Temperature);

      double Windspeed = myObject ["current"]["wind_kph"];   //current windspeed
      Serial.print("Current Windspeed = ");
      Serial.println(Windspeed);


      int Will_It_Rain = myObject ["forecast"] ["forecastday"][0] ["hour"][0] ["will_it_rain"];
      Serial.print("Will It Rain: ");
      if (Will_It_Rain==1)
      {
        Serial.println("YES");
      }
      else
      {
        Serial.println("NO");
      }
      
      int Chance_Of_Rain = myObject ["forecast"] ["forecastday"][0] ["hour"][0] ["chance_of_rain"];
      Serial.print("Chance of Rain: ");
      Serial.println(Chance_Of_Rain);
      Serial.println("");
    }
    else
    {
    Serial.println("WiFi Disconnected");
    } 
    lastTime = millis();
  }
}

String httpGETRequest(const char* serverName) {
  WiFiClient client;
  HTTPClient http;   
  http.begin(client, serverName);// Your IP address with path or Domain name with URL path 
  int httpResponseCode = http.GET();// Send HTTP POST request 
  String payload = "{}"; 
  if (httpResponseCode>0) 
  {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else 
  {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  http.end();
  return payload;
}

[Code-5] Automate irrigation [Happy Plant] MAIN_CODE

Arduino
This code is used to automate the watering system using weather forecasts, as well as to monitor the smart plant using the Blynk server.
#define BLYNK_TEMPLATE_ID "TMPLfdchHbXn"
#define BLYNK_DEVICE_NAME "Happy Plant"
#define BLYNK_AUTH_TOKEN "tkOSK7PS4-kAzsdc1tm9EMqVJjB_aNmk"
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>
#include <BlynkSimpleEsp8266.h>
#include <WiFiUdp.h>
#include <NTPClient.h>

const long oneSecond = 1000;                        // a second is a thousand milliseconds
const long oneMinute = oneSecond * 60;
const long oneHour = oneMinute * 60;
const int moistureSensorPin = A0;                   // Analog input pin used to check the moisture level of the 
int moistureSensorValue = 0;                    
const int pumpPin = D1;                             // Digital output pin that the water pump is attached to
const int ledPin = D0;                              // In NODE_MCU pin D0 is connected to no board LED
double checkInterval = 30;                          // Time to wait before checking the soil moisture level - default it to an hour = 1800000
int extreme_dryness = 885;                          // Soil is 80% dry [(100-80)=20] that means there is only 20% of moisture in the soil
int dryness = 746;                                  // Soil is 60% dry [(100-60)=40] that means there is only 40% of moisture in the soil
int amountToPump_when_extreme_dryness = 4000;       // Amount of water to pump during extreme_dryness [it pumps for 5 secounds, about 26.25 millimeter}
int amountToPump_when_dryness = 2000;               // Amount of water to pump during dryness [it pumps for 2 secounds, about 10.5 millimeter}


const char* ssid = "Galaxy";
const char* password = "12345678901";

const long utcOffsetInSeconds = 19800;              //UTC of india +5:30
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

String openWeatherMapApiKey = "d33c5770088a432699242527210952";   // Enter your APi key
String city = "Mudbidri";   // Replace with your city name

unsigned long lastTime = 0;
unsigned long timerDelay = 1000;   
String jsonBuffer;

void setup() 
{
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  pinMode(moistureSensorPin, INPUT);
  pinMode(pumpPin, OUTPUT); 
  for (int i=0; i <= 4; i++)    //LED will blink 5 times to indicate the system is ON
  {
        digitalWrite(ledPin, HIGH);
        delay(400);
        digitalWrite(ledPin, LOW);
        delay(400);
  }
  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, password);
  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
  for (int i=0; i <= 14; i++)   //LED will blink fast to indicate that Nodemcu is connected to internet
  {
        digitalWrite(ledPin, HIGH);
        delay(100);
        digitalWrite(ledPin, LOW);
        delay(100);
  }
  timeClient.begin();
  
}

void loop() 
{
  if ((millis() - lastTime) > timerDelay)   // Send an HTTP GET request
  {
    if(WiFi.status()== WL_CONNECTED)    // Check WiFi connection status
    {
      timeClient.update();
      Serial.println(timeClient.getFormattedTime());
      int H=timeClient.getHours();
      String serverPath = "http://api.weatherapi.com/v1/forecast.json?key=" + openWeatherMapApiKey + "&q=" + city + "&day=1&hour=" + H ;
      jsonBuffer = httpGETRequest(serverPath.c_str());
      JSONVar myObject = JSON.parse(jsonBuffer);
      if (JSON.typeof(myObject) == "undefined") 
      {
        Serial.println("Parsing input failed!");
        return;
      }
      Serial.print("JSON object = ");
      Serial.println(myObject);

      Serial.print("Location:");    //Forecasted location
      Serial.println(myObject ["location"]["name"]);   
      Blynk.virtualWrite(V0, city);
  
      Serial.print("Time: ");   //Forecasted data time
      Serial.println(timeClient.getFormattedTime());
      Blynk.virtualWrite(V1, timeClient.getFormattedTime());
   
      double Temperature = myObject ["current"]["temp_c"];  //current temperature value
      Serial.print("Current Temperature = ");
      Serial.println(Temperature);
      Blynk.virtualWrite(V2, Temperature);

   
      double Windspeed = myObject ["current"]["wind_kph"];     //current windspeed
      Serial.print("Current Windspeed = ");
      Serial.println(Windspeed);
      Blynk.virtualWrite(V3, Windspeed);
      
      int Will_It_Rain = myObject ["forecast"] ["forecastday"][0] ["hour"][0] ["will_it_rain"];
      Serial.print("Will It Rain: ");
      if (Will_It_Rain==1)
      {
        Serial.println("YES");
        Blynk.virtualWrite(V4, "YES");
      }
      else
      {
        Serial.println("NO");
        Blynk.virtualWrite(V4, "NO");
      }

      int Chance_Of_Rain = myObject ["forecast"] ["forecastday"][0] ["hour"][0] ["chance_of_rain"];
      Serial.print("Chance of Rain: ");
      Serial.println(Chance_Of_Rain);
      
      moistureSensorValue = analogRead(moistureSensorPin);    //read the value of the moisture Sensor
      Serial.print("Moisture level sensor value: ");    //print it to the serial monitor
      Serial.println(moistureSensorValue);
      Blynk.virtualWrite(V5, moistureSensorValue);
      if(moistureSensorValue >= extreme_dryness)
      {
          digitalWrite(pumpPin, HIGH);
          Serial.println("pump on for 4 seconds");
          delay(amountToPump_when_extreme_dryness);                                     
          digitalWrite(pumpPin, LOW);
          Serial.println("pump off");
          delay(6*oneHour);   //delay for 6 hours
      }   
      else if(moistureSensorValue >= dryness)
      {
           if(Will_It_Rain == 1)
           {
                delay(6*oneHour);     //delay for 6 hours
           }
           else
           {
                 digitalWrite(pumpPin, HIGH);
                 Serial.println("pump on for 2 seconds");
                 delay(amountToPump_when_dryness);                                      
                 digitalWrite(pumpPin, LOW);
                 Serial.println("pump off");
                 delay(6*oneHour);    //delay for 6 hours  
           }
       }  
    }
    else 
    {
      Serial.println("WiFi Disconnected");
    } 
    lastTime = millis();
  }
  delay(6*oneHour);     //delay for 6 hours
}

String httpGETRequest(const char* serverName) {
  WiFiClient client;
  HTTPClient http;
  http.begin(client, serverName);   // Your IP address with path or Domain name with URL path 
  int httpResponseCode = http.GET();    // Send HTTP POST request
  String payload = "{}"; 
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  http.end();
  return payload;
}

Credits

vivek_m

vivek_m

0 projects • 1 follower

Comments