IoT Based Smart Irrigation System using NodeMCU ESP8266 & Adafruit IO

4,768 views

Introduction

IoT-based smart irrigation systems have revolutionized the agriculture industry by enabling farmers to remotely monitor and control the water supply to their crops. These systems utilize sensors to measure soil moisture levels and weather conditions, allowing for precise watering schedules that optimize crop growth while conserving water resources.

In this project, we will explore how to build an IoT-based smart irrigation system using NodeMCU ESP8266 and Adafruit IO. The system will incorporate a soil moisture sensor module, LDR, 10K pot, solenoid valve, and relay module, enabling remote control and monitoring of irrigation operations. This project is a perfect example of how technology can be harnessed to increase efficiency and sustainability in agriculture.

Hardware Components

You will require the following hardware Smart Irrigation System.

ComponentsValueQty
ESP8266NodeMCU1
Soil Moisture Sensor Module1
Single Channel Relay1
Battery12V 1
DC Motor / Solenoid Valve1
LED1
LDR1
Potentiometer10k1
Jumper Wires1

Arduino Code

  1. Include necessary libraries:
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
  1. Set up WiFi and MQTT credentials:
const char *ssid =  "Galaxy-M20";     // Enter your WiFi Name
const char *pass =  "ac312124"; // Enter your WiFi Password

WiFiClient client;

#define MQTT_SERV "io.adafruit.com"
#define MQTT_PORT 1883
#define MQTT_NAME "choudharyas"
#define MQTT_PASS "988c4e045ef64c1b9bc8b5bb7ef5f2d9"
  1. Define pins and set intervals:
const int ledPin = D6;
const int ldrPin = D1;
const int moisturePin = A0;             // moisture sensor pin
const int motorPin = D0;
unsigned long interval = 10000;
unsigned long previousMillis = 0;
unsigned long interval1 = 1000;
unsigned long previousMillis1 = 0;
float moisturePercentage;              // moisture reading
  1. Set up MQTT client and feeds:
Adafruit_MQTT_Client mqtt(&client, MQTT_SERV, MQTT_PORT, MQTT_NAME, MQTT_PASS);
Adafruit_MQTT_Publish AgricultureData = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/AgricultureData");
Adafruit_MQTT_Subscribe LED = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/LED");
Adafruit_MQTT_Subscribe Pump = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/Pump");
  1. Set up pins and connect to WiFi:
void setup()
{
  Serial.begin(115200);
  delay(10);
  mqtt.subscribe(&LED);
  mqtt.subscribe(&Pump);
  pinMode(motorPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(ldrPin, INPUT);
  digitalWrite(motorPin, LOW); // keep motor off initially
  
  Serial.println("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");              // print ... till not connected
  }
  Serial.println("");
  Serial.println("WiFi connected");
}
  1. Continuously read sensor data, check thresholds, and publish to MQTT:
void loop()
{
   MQTT_connect();

 int ldrStatus = analogRead(ldrPin);

    if (ldrStatus <= 200) {
    
    digitalWrite(ledPin, HIGH);
    
    Serial.print("Its DARK, Turn on the LED : ");
    
    Serial.println(ldrStatus);
    
    } 
    else {
    
    digitalWrite(ledPin, LOW);
    
    Serial.print("Its BRIGHT, Turn off the LED : ");
    
    Serial.println(ldrStatus);
    
    }

  moisturePercentage = ( 100.00 - ( (analogRead(moisturePin) / 1023.00) * 100.00 ) );

 
    Serial.print("Soil Moisture is  = ");
    Serial.print(moisturePercentage);
    Serial.println("%");
    
    

if (moisturePercentage < 35) {
  digitalWrite(motorPin, HIGH);         // turn on motor
}
if (moisturePercentage > 35 && moisturePercentage < 37) {
  digitalWrite(motorPin, HIGH);        // turn on motor

7. Subscribe to two different MQTT feeds using Adafruit_MQTT_Subscribe object:

 Adafruit_MQTT_Subscribe LED = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/LED");
 Adafruit_MQTT_Subscribe Pump = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/Pump");

8. In the setup() function, subscribe to the above MQTT feeds:

void setup()
{
  Serial.begin(115200);
  delay(10);
  mqtt.subscribe(&LED);
  mqtt.subscribe(&Pump);
  pinMode(motorPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(ldrPin, INPUT);
  digitalWrite(motorPin, LOW); // keep motor off initally
  
  Serial.println("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");              // print ... till not connected
  }
  Serial.println("");
  Serial.println("WiFi connected");
}

9. In the loop() function, connect to MQTT broker by calling MQTT_connect() function and read subscribed MQTT feeds using mqtt.readSubscription():

void loop()
{
   MQTT_connect();
  
   // Reading the LDR sensor data and switching the LED accordingly
   
   // Reading the moisture sensor data and turning the motor pump ON/OFF accordingly
   
   // Publishing the moisture percentage to the MQTT broker
   
   // Reading the subscribed MQTT feeds (LED and Pump) and switching the LED and motor pump accordingly
   Adafruit_MQTT_Subscribe * subscription;
   while ((subscription = mqtt.readSubscription(5000)))
   {
     // Handle the subscribed MQTT feed based on the message received
   }
}

10. Implement MQTT_connect() function which tries to connect to the MQTT broker and if it fails, it will retry for 3 times and then disconnects the client:

void MQTT_connect() 
{
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) 
  {
    return;
  }

  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) // connect will return 0 for connected
  { 
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
       retries--;
       if (retries == 0) 
       {
         // basically die and wait for WDT to reset me
         while (1);
       }
  }
}

Schematic

Make connections according to the circuit diagram given below.

Smart Irrigation System ESP8266 Circuit

Installing Arduino IDE

First, you need to install Arduino IDE Software from its official website Arduino. Here is a simple step-by-step guide on “How to install Arduino IDE“.

Installing Libraries

Before you start uploading a code, download and unzip the following libraries at /Program Files(x86)/Arduino/Libraries (default), in order to use the sensor with the Arduino board. Here is a simple step-by-step guide on “How to Add Libraries in Arduino IDE“.

Code

Now copy the following code and upload it to Arduino IDE Software.

#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

const char *ssid =  "Galaxy-M20";     // Enter your WiFi Name
const char *pass =  "ac312124"; // Enter your WiFi Password

WiFiClient client;

#define MQTT_SERV "io.adafruit.com"
#define MQTT_PORT 1883
#define MQTT_NAME "choudharyas"
#define MQTT_PASS "988c4e045ef64c1b9bc8b5bb7ef5f2d9"

const int ledPin = D6;
const int ldrPin = D1;
const int moisturePin = A0;             // moisteure sensor pin
const int motorPin = D0;
unsigned long interval = 10000;
unsigned long previousMillis = 0;
unsigned long interval1 = 1000;
unsigned long previousMillis1 = 0;
float moisturePercentage;              //moisture reading

//Set up the feed you're publishing to
Adafruit_MQTT_Client mqtt(&client, MQTT_SERV, MQTT_PORT, MQTT_NAME, MQTT_PASS);
Adafruit_MQTT_Publish AgricultureData = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/AgricultureData");

//Set up the feed you're subscribing to
 Adafruit_MQTT_Subscribe LED = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/LED");
  Adafruit_MQTT_Subscribe Pump = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/Pump");

void setup()
{
  Serial.begin(115200);
  delay(10);
  mqtt.subscribe(&LED);
  mqtt.subscribe(&Pump);
  pinMode(motorPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(ldrPin, INPUT);
  digitalWrite(motorPin, LOW); // keep motor off initally
  
  Serial.println("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");              // print ... till not connected
  }
  Serial.println("");
  Serial.println("WiFi connected");
}
 
void loop()

{
   MQTT_connect();
  

 int ldrStatus = analogRead(ldrPin);

    if (ldrStatus <= 200) {
    
    digitalWrite(ledPin, HIGH);
    
    Serial.print("Its DARK, Turn on the LED : ");
    
    Serial.println(ldrStatus);
    
    } 
    else {
    
    digitalWrite(ledPin, LOW);
    
    Serial.print("Its BRIGHT, Turn off the LED : ");
    
    Serial.println(ldrStatus);
    
    }

  moisturePercentage = ( 100.00 - ( (analogRead(moisturePin) / 1023.00) * 100.00 ) );

 
    Serial.print("Soil Moisture is  = ");
    Serial.print(moisturePercentage);
    Serial.println("%");
    
    

if (moisturePercentage < 35) {
  digitalWrite(motorPin, HIGH);         // tun on motor
}
if (moisturePercentage > 35 && moisturePercentage < 37) {
  digitalWrite(motorPin, HIGH);        //turn on motor pump
}
if (moisturePercentage > 38) {
  digitalWrite(motorPin, LOW);          // turn off mottor
}


if (! AgricultureData.publish(moisturePercentage))
       {                     
         delay(5000);   
          }
Adafruit_MQTT_Subscribe * subscription;
while ((subscription = mqtt.readSubscription(5000)))
     {
    
   if (subscription == &LED)
     {
      //Print the new value to the serial monitor
      Serial.println((char*) LED.lastread);
     
   if (!strcmp((char*) LED.lastread, "OFF"))
      {
        digitalWrite(ledPin, HIGH);
    }
    if (!strcmp((char*) LED.lastread, "ON"))
      {
        digitalWrite(ledPin, LOW);
    }
 }
   
   if (subscription == &Pump)
     {
      //Print the new value to the serial monitor
      Serial.println((char*) Pump.lastread);
     
   if (!strcmp((char*) Pump.lastread, "OFF"))
      {
        digitalWrite(motorPin, HIGH);
    }
     if (!strcmp((char*) Pump.lastread, "ON"))
      {
        digitalWrite(motorPin, LOW);
    }

     }
     }
}
void MQTT_connect() 
{
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) 
  {
    return;
  }

  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) // connect will return 0 for connected
  { 
       
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
       retries--;
       if (retries == 0) 
       {
         // basically die and wait for WDT to reset me
         while (1);
       }
  }
}

Working Explanation

The code starts by including the required libraries and defining the necessary credentials for Wi-Fi and MQTT broker connectivity. It then defines the pin modes and creates MQTT client objects for publishing and subscribing to MQTT feeds. The setup function connects to Wi-Fi and subscribes to the LED and Pump MQTT feeds. The loop function starts by calling the MQTT_connect function to connect to the MQTT broker. It then reads the light intensity from an LDR sensor, calculates the moisture percentage from a soil moisture sensor, and controls the motor pump and LED light based on the moisture readings. It also publishes the moisture percentage value to the AgricultureData MQTT feed. Finally, it reads and processes the subscribed LED and Pump MQTT feeds by turning on/off the LED and motor pump based on the received messages.

The MQTT_connect function tries to connect to the MQTT broker and retries for 3 times if it fails to connect. If the connection fails after 3 retries, the code enters an infinite loop and waits for the Watchdog Timer (WDT) to reset the device.

Applications

  • Precision agriculture
  • Greenhouse automation
  • Urban farming
  • Sports field irrigation
  • Landscaping irrigation
  • Golf course irrigation
  • Municipal water management.