IoT based Smart Agriculture Monitoring System: We are going to construct a smart agricultural monitoring system which can collect crucial agricultural data and send it to an IoT platform called Thingspeak in real time where the data can be logged and analyzed. The logged data on Thingspeak is in graphical format, a botanist or a reasonably knowledged farmer can analyze the data (from anywhere in the world) to make sensible changes in the supplied resources (to crops) to obtain high quality yield.
Smart agriculture monitoring system or simply smart farming is an emerging technology concept where data from several agricultural fields ranging from small to large scale and its surrounding are collected using smart electronic sensors. The collected data are analyzed by experts and local farmers to draw short term and long term conclusion on weather pattern, soil fertility, current quality of crops, amount of water that will be required for next week to a month etc.

Why we need IoT?
IoT is here to reduce the manual labour involved in collecting these crucial agricultural data. If manual labour is involved we have to deploy several thousands of personnel to different agricultural sites to collect the tedious readings every single day and there will be no assurance in the data integrity since we are humans we may get inert and may manipulate the data which could push the expert conclusions in wrong direction.

This project consists of Arduino as brain and we are utilizing 5 sensors:
1. Temperature and humidity sensor.
2. Air Quality / gas sensor.
3. Light sensor.
4. Soil moisture sensor.
5. Barometric pressure sensor.
We are also utilizing a GSM module SIM 900 in the circuit, which can connect to GPRS internet for sending sensor data to thingspeak server.

I2C adapter module:
A 16×2 LCD display will display the sensor data which is interfaced with I2C adapter module for reducing the number of wire that connects from Arduino to LCD.
Light Sensor:
It is obvious that plants need good sun shine to prepare its own food and this process called photosynthesis. Plants need optimum amount of light not less or not too much. The amount of light received on a plot of land can be measured using LDR or photoresistor.
The LDR changes its electrical resistance depending on amount of light incident on it. The amount of light is converted to 10-bit digital value and further converted to percentage out of 100.
Zero means no light and 100% means a lot of light.

Air Quality Sensor / Gas Sensor:
It is less known fact to many that plants and trees need fresh air for nourishment and growth. Polluted air will make the plants grow sick and we may not get best quality of fruits and vegetables. Polluted air may also make the crops less immune to disease and bugs.
So air quality is a very important parameter to judge the growth of crops, to do this we are using MQ 135 air quality sensor. MQ 135 comes with a breakout board as shown and it has 4 terminals and we are going to use just 3 of them Vcc, GND and Aout which is analog output of the sensor.
When MQ 135 detects toxic gases the analog output value increases and vice versa. The analog output is converted into 10-bit digital value and converted to percentage out of 100.
100% means lot of air contamination and 0% means least air contamination, so lower the value better the air quality. The main disadvantage of MQ135 sensor is that it cannot say which pollutant gas is detected.

Temperature and Humidity sensor:
Plants are evolved to be temperature and humidity sensitive just like human or any other living begins. We prepare our self for upcoming winter or summer or rainy seasons so that we can stay comfortable. Similarly plants do prepare themselves for upcoming seasons either to adapt them for the worst or to flourish with fruits and flowers.
So temperature and humidity are important factors in deciding when crops and fruits will get ready to cultivate or begin to produce. This parameter is measured by a digital sensor called DHT11 which can measure both temperature and humidity.

Soil Moisture Sensor:
Plants are of 90% water. The amount of water required varies from plants to plants. The amount of water to be irrigated every day also varies; this depends on how well the soil can hold moisture, current season, temperature and humidity as mentioned in the beginning of this post.
Many farmers irrigate their crops more than sufficient most of the times just to be sure that all their crops received adequate water; this will lead to inefficient management of water.
The soil moisture can be measured using the illustrated senor, which has two prongs (electrodes) which are to be inserted on top layer of soil. This is an analog sensor which will output analog values to Arduino.
We are going to use only the analog output of this sensor, just like other analog sensors mentioned here; the output is converted to 10-bit digital value and finally to percentage out of 100. 0% means the soil is dry 100% means the soil wet. But with this sensor we found that anywhere between 50% to 70% reading, the soil was fully wet.

Barometric Pressure Sensor BMP180:
A barometric pressure sensor can be used for measuring atmospheric pressure. Using atmospheric pressure data you can predict weather for short term and also can be used for studying how plants behave in different atmospheric pressure conditions.
BM180 is a digital sensor and connects to I2C bus and operates at 3.3V; it can measure ATM pressure, Altitude and temperature. We are going to extract only the ATM pressure data but you can edit the code and include altitude data to see how plantations behave at different altitude. Temperature data is ignored from this sensor because we already use DHT11 which can measure temperature.

Need of ESP8266 or NodeMCU:
If you are already familiar with some IoT projects, you would have come across ESP8266 or NodeMCU which are IoT enabled boards that connect our projects to internet via Wi-Fi.
In this particular project we are using GSM modem to access GPRS internet, this is because our project will be placed outdoors like middle of an agriculture field where providing Wi-Fi could get difficult and even if we set a Wi-Fi network outdoors anyone could hack into the network.

Setting up Thingspeak
You need to sign up for Thingspeak by entering your E-mail ID and filling up all the necessary credentials asked. Now your channel is ready, but you need to make the following changes in your channel to receive 6 sensor data:
Click on channel settings and name / rename your channel as shown:
Write API key is a private key consisting of letters and numbers which is used to identify and write values to your channel. This key should be kept confidential if you don’t want others writing to your channel. This API key will be inserted in the given program code.
Arduino libraries:
1. LiquidCrystal_I2C.h: click here
2. Adafruit_BMP085.h: click here
3. DHT11 sensor: click here

System operation:
1. With completed hardware setup insert a valid SIM card that has a working mobile data plan.
2. Upload the program code using USB cable with correct APN and write API key (without powering the circuit from wall adapter).
3. Once the program is uploaded remove the USB, now turn on the circuit using 9V to 12V / 1 amp (or more) wall adapter.
4. The circuit will boot and it tells you to wait for 1 minute. Meanwhile the GSM module is getting ready and latching to the mobile network. The MQ 135 is also getting ready for operation by heating up the metal body.
5. After one minute the LCD will display all the sensor data (two at a time).
6. Now you can see network LED of GSM module is blinking fast which means your project connected to internet and started to send data to Thingspeak.
Open your Thingspeak account and click on private view tab; you will see this (output of this project):

Arduino Source Code:

#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <dht.h>
#include <Adafruit_BMP085.h>
Adafruit_BMP085 bmp;
dht DHT;
LiquidCrystal_I2C lcd(0x27, 16, 2);
SoftwareSerial gsm(10, 11); // RX, TX
#define DHT11_PIN A3
int chk;
int humi = 0;
int temp = 0;
int soil = 0;
int light = 0;
int BMP = 0;
int gas = 0;
boolean HT;
void setup()
{
  gsm.begin(9600);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Please wait for");
  lcd.setCursor(0, 1);
  lcd.print("60 seconds.");
  delay(20000);
  delay(20000);
  delay(20000);
  modem_init();
  data_init();
  internet_init();
  lcd.clear();
}

void loop()
{
  chk = DHT.read11(DHT11_PIN);
  temp = DHT.temperature;
  humi = DHT.humidity;
  soil = analogRead(A0);
  light = analogRead(A1);
  gas = analogRead(A2);
  BMP = bmp.readPressure();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Soil:");
  soil = map(soil, 0, 1023, 100, 0);
  lcd.print(soil);
  lcd.print("%");
  lcd.setCursor(0, 1);
  lcd.print("Light:");
  light = map(light, 0, 1023, 0, 100);
  lcd.print(light);
  lcd.print("%");
  delay(3000);
  lcd.clear();
  lcd.setCursor(0, 0);
  switch (chk)
  {
    case DHTLIB_OK:
      HT = true;
      break;
    default:
      HT = false;
      break;
  }
  if (HT == true)
  {
    lcd.print("Temp:");
    lcd.print(temp);
    lcd.print(" *C");
    lcd.setCursor(0, 1);
    lcd.print("Humidity:");
    lcd.print(humi);
    lcd.print("%");
  }
  else
  {
    temp = 0;
    humi = 0;
    lcd.print("Temp:");
    lcd.print("No Data");
    lcd.setCursor(0, 1);
    lcd.print("Humidity:");
    lcd.print("No Data");
  }
  delay(3000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Air Qlt: ");
  gas = map(gas, 0, 1023, 0, 100);
  lcd.print(gas);
  lcd.print("%");
  lcd.setCursor(0, 1);
  lcd.print("Pressure:");
  if (!bmp.begin())
  {
    lcd.print("No Data");
    BMP = 0;
  }
  else
  {
    lcd.print(BMP);
  }
  lcd.print("Pa");
  delay(3000);
  Send_data();
}
void modem_init()
{
  Serial.println("Please wait.....");
  gsm.println("AT");
  delay(1000);
  gsm.println("AT+CMGF=1");
  delay(1000);
  gsm.println("AT+CNMI=2,2,0,0,0");
  delay(1000);
}
void data_init()
{
  Serial.println("Please wait.....");
  gsm.println("AT");
  delay(1000); delay(1000);
  gsm.println("AT+CPIN?");
  delay(1000); 
  delay(1000);
  gsm.print("AT+SAPBR=3,1");
  gsm.write(',');
  gsm.write('"');
  gsm.print("contype");
  gsm.write('"');
  gsm.write(',');
  gsm.write('"');
  gsm.print("GPRS");
  gsm.write('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000); ;
  gsm.print("AT+SAPBR=3,1");
  gsm.write(',');
  gsm.write('"');
  gsm.print("APN");
  gsm.write('"');
  gsm.write(',');
  gsm.write('"');
  //------------APN------------//
  gsm.print("bsnlnet"); //APN Here
  //--------------------------//
  gsm.write('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);
  gsm.print("AT+SAPBR=3,1");
  gsm.write(',');
  gsm.write('"');
  gsm.print("USER");
  gsm.write('"');
  gsm.write(',');
  gsm.write('"');
  gsm.print("  ");
  gsm.write('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);
  gsm.print("AT+SAPBR=3,1");
  gsm.write(',');
  gsm.write('"');
  gsm.print("PWD");
  gsm.write('"');
  gsm.write(',');
  gsm.write('"');
  gsm.print("  ");
  gsm.write('"');
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(2000);
  gsm.print("AT+SAPBR=1,1");
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(3000);
}
void internet_init()
{
  Serial.println("Please wait.....");
  delay(1000);
  gsm.println("AT+HTTPINIT");
  delay(1000); delay(1000);
  gsm.print("AT+HTTPPARA=");
  gsm.print('"');
  gsm.print("CID");
  gsm.print('"');
  gsm.print(',');
  gsm.println('1');
  delay(1000);
}
void Send_data()
{
  lcd.clear();
  lcd.print("Sending the data");
  lcd.setCursor(0, 1);
  lcd.print("to Thingspeak...");
  delay(1500);
  gsm.print("AT+HTTPPARA=");
  gsm.print('"');
  gsm.print("URL");
  gsm.print('"');
  gsm.print(',');
  gsm.print('"');
  gsm.print("http:");
  gsm.print('/');
  gsm.print('/');
  //-----------------------Your API Key Here-----------------------//
  //Replace xxxxxxxxxxx with your write API key.
  gsm.print("api.thingspeak.com/update?api_key=xxxxxxxxxxxxx&field1=");
  gsm.print(soil);
  gsm.print("&field2=");
  gsm.print(light); 
  gsm.print("&field3=");
  gsm.print(gas); 
  gsm.print("&field4=");
  gsm.print(temp); 
  gsm.print("&field5=");
  gsm.print(humi); 
  gsm.print("&field6=");
  gsm.print(BMP); 
  gsm.write(0x0d);
  gsm.write(0x0a);
  delay(1000);
  gsm.println("AT+HTTPACTION=0");
  delay(1000);
}

About the Author

Subramanian

Hello! My Dear Friends. I am Subramanian. I am writing posts on androiderode about Electronics testing and equipments.

View All Articles