Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
Hackster is hosting Impact Spotlights: Smart Home. Watch the stream live on Thursday!Hackster is hosting Impact Spotlights: Smart Home. Stream on Thursday!

Soil Monitoring & Analysis

Monitoring soil moisture & acidity for small-scale plantation.

IntermediateFull instructions providedOver 1 day446
Soil Monitoring & Analysis

Things used in this project

Hardware components

Maker UNO X
×1
LED 5mm - Red
×1
LED 5mm - Green
×1
Resistor 220 Ohm
×1
Male to Male Jumper
×20
Male to Female Jumper
×10
USB Micro B Cable
×1
Breadboard 8.5×5.5cm (400 Holes)
×1
Moisture Sensor Module
×1
PH Electrode Probe E-201-C PHS-25 PHS-3C Open source Composite PH0-14 Analog Meter Sensor Module for Arduino Science Lab
×1
SG90 9g Plastic Gear 360 Degree Micro Servo Motor Set for Arduino TowerPro
×1
LCD 1602 16x2 LCD Screen Liquid Crystal Display Module for DIY Arduino Project (I2C Module)
×1
WiFi UNO Based ESP32 (Wemos D1 R32)
×1

Software apps and online services

Arduino IDE
Arduino IDE
Blynk
Blynk

Hand tools and fabrication machines

6pc Precision Screwdriver Set

Story

Read more

Code

Soil Moisture Sensor

Arduino
To detect the moisture level of the soil.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //LiquidCrystal_I2C lcd(0x27, 16, 2);

#define soilLowWet 50   // Lower Soil Moisture Level Threshold
#define soilHighWet 70  // Upper Soil Moisture Level Threshold
#define sensorPower 7
#define sensorPin A1
int ML = 0;             // ML: Moisture Level


void setup() 
{
  lcd.begin(16,2);//Defining 16 columns and 2 rows of lcd display //lcd.init();                           // Initialize the display 
  lcd.backlight();                      // Power ON the back light
  pinMode(13, OUTPUT);                  // Set digital pin 13 -> Red LED output
  pinMode(12, OUTPUT);                  // Set digital pin 12 -> Green LED output
  pinMode(sensorPower, OUTPUT); // Set analog pin A1 -> soil moisture output
  
  // Initialization
	digitalWrite(sensorPower, LOW); // Soil Moisture Sensor OFF
  digitalWrite(13, LOW);          // Red LED OFF
  digitalWrite(12, LOW);          // Green LED OFF
  
  // //DELAY 1 minute to stablilize sensor reading
  // delay(60000);
  
  Serial.begin(9600);
}

void loop() 
{
  //get the reading from the function below and print it
	int moisture = readSensor();
  ML = (100 - ((moisture / 1023.00) * 100));
	Serial.print("Analog Output: ");
	Serial.println(moisture);
  Serial.print("Moisture Level: ");
  Serial.println(ML);
  
  display();

  // Process Variable
  if (ML < soilLowWet) 
  {
    digitalWrite(12, LOW);
    digitalWrite(13, HIGH);  //Red LED
    display();               // Add Water
  } else if (ML >= soilHighWet) 
  {
    digitalWrite(12, LOW);
    digitalWrite(12, HIGH);  // Green LED
    display();               // Stop Add Water
  } else if (ML > soilLowWet && ML < soilHighWet)
  {
    digitalWrite(13, LOW);
    digitalWrite(12, HIGH);  // Green LED
    display();               // Stop Add Water
  }
}


void display() 
{
  lcd.clear();//Clean the screen
  lcd.setCursor(0, 0);
  lcd.print("ML=");
  lcd.print(ML);
  
  if (ML < soilLowWet) 
  {
    lcd.setCursor(0, 1);
    lcd.print("Add Water");
  } else if (ML >= soilHighWet) {
    lcd.setCursor(0, 1);
    lcd.print("Stop Add Water");
  } else if (ML >= soilLowWet && ML <= soilHighWet) {
    lcd.setCursor(0, 1);
    lcd.print("Stop Add Water");
  }
  
  delay(1000);
  Serial.println();
}

//  This function returns the analog soil moisture measurement
int readSensor() 
{
	digitalWrite(sensorPower, HIGH);	// Turn the sensor ON
	delay(10);							          // Allow power to settle
	int val = analogRead(sensorPin);	// Read the analog value form sensor
	digitalWrite(sensorPower, LOW);		// Turn the sensor OFF
	return val;							          // Return analog moisture value
}

pH Sensor

Arduino
To detect the pH level of the soil.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

float calibration_value = 21.34 + 5.7;
int phval = 0;
unsigned long int avgval;
int buffer_arr[10], temp;

void setup() {
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass, "blynk.cloud", 80);
  lcd.begin(16, 2);
  lcd.backlight();
  pinMode(D13, OUTPUT);                  // Set digital pin 13 -> Red LED output
  pinMode(D12, OUTPUT);                  // Set digital pin 12 -> Green LED output
  delay(2000);
}

void loop() {
  Blynk.run();
  // pH Measurement
  for (int i = 0; i < 10; i++) {
    buffer_arr[i] = analogRead(A0);
    delay(30);
  }
  for (int i = 0; i < 9; i++) {
    for (int j = i + 1; j < 10; j++) {
      if (buffer_arr[i] > buffer_arr[j]) {
        temp = buffer_arr[i];
        buffer_arr[i] = buffer_arr[j];
        buffer_arr[j] = temp;
      }
    }
  }
  avgval = 0;
  for (int i = 2; i < 8; i++) {
    avgval += buffer_arr[i];
  }
  float volt = (float)avgval * 5.0 / 1024 / 6;
  float ph_act = -5.70 * volt + calibration_value;
  lcd.clear();//Clean the screen
  lcd.setCursor(0, 0);
  lcd.print("pH Val:");
  lcd.setCursor(8, 0);
  lcd.print(ph_act);
  
  // Check pH Level and Control LEDs
  if (ph_act < 5.5) {
    digitalWrite(D12, LOW);
    digitalWrite(D13, HIGH);
    lcd.setCursor(0, 1);
    lcd.print("pH too low");
  } else if (ph_act > 6.5) {
    digitalWrite(D12, LOW);
    digitalWrite(D13, HIGH);
    lcd.setCursor(0, 1);
    lcd.print("pH too high");
  } else {
    digitalWrite(D13, LOW);
    digitalWrite(D12, HIGH);
    lcd.setCursor(0, 1);
    lcd.print("pH OK");
  }
  
  delay(1000);
}

Servo Motor

Arduino
To add fertilizer to the soil.
// Include the library
#include <Servo.h>

// Create the servo object
Servo myservo;

// Setup section to run once
void setup() {
  myservo.attach(9); // attach the servo to our servo object

  myservo.write(90); 
}

// Loop to keep the motor turning!
void loop() {
  myservo.write(70); // rotate the motor counterclockwise
  delay(500); // keep rotating for 5 seconds (5000 milliseconds)

  myservo.write(90); // stop the motor
  delay(1000); // stay stopped

  myservo.write(110); // rotate the motor clockwise
  delay(500); // keep rotating for 5 seconds (5000 milliseconds)

  myservo.write(90); // stop the motor
  delay(1000); //staystopped

}

Soil Monitoring and Analysis

Arduino
To monitor, analyze, and prepare the soil to be suitable for chilli padi plantation.
// Soil Monitoring & Analysis System
// Created by Bertrand Lau, Farhan Hekanansyah, Wong Chu Han, and Andrew Denilson
// Note: (1) Specified parameter values as based on chilli padi plant.
//       (2) Water and fertilizer are added manually onto the spoon connected to the servo motor.

#include <Wire.h>
#include <Servo.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //LiquidCrystal_I2C lcd(0x27, 16, 2);

#define soilLowWet 50   // Lower Soil Moisture Level Threshold
#define soilHighWet 70  // Upper Soil Moisture Level Threshold
#define sensorPower 7
#define sensorPin A1
int ML = 0;             // ML: Moisture Level

float calibration_value = 21.34 + 5.7;
int phval = 0;
unsigned long int avgval;
int buffer_arr[10], temp;

Servo myservo;


void setup() 
{
  lcd.begin(16,2);                      //Defining 16 columns and 2 rows of lcd display
  lcd.backlight();                      // Power ON the back light
  pinMode(13, OUTPUT);                  // Set digital pin 13 -> Red LED output
  pinMode(12, OUTPUT);                  // Set digital pin 12 -> Green LED output
  pinMode(sensorPower, OUTPUT);         // Set analog pin A1 -> soil moisture output
  myservo.attach(9);                    // Attach the servo to servo object

  // Initialization
	digitalWrite(sensorPower, LOW);       // Soil Moisture Sensor OFF
  digitalWrite(13, LOW);                // Red LED OFF
  digitalWrite(12, LOW);                // Green LED OFF
  myservo.write(90);                    // Initialize servo at 0 speed or 'rest position'

  //Delay 5 seconds to stablilize sensor reading
  delay(5000);
  
  Serial.begin(9600);
}


void loop() 
{
  // Soil Moisture Sensing
  int moisture = readSensor();
  ML = (100 - ((moisture / 1023.00) * 100));
	Serial.print("Analog Output: ");
	Serial.println(moisture);
  Serial.print("Moisture Level: ");
  Serial.println(ML);
  display();

  if (ML < soilLowWet) 
  {
    digitalWrite(12, LOW);
    digitalWrite(13, HIGH);  //Red LED
    display();               // Add Water
  } else if (ML >= soilHighWet) 
  {
    digitalWrite(12, LOW);
    digitalWrite(12, HIGH);  // Green LED
    display();               // Stop Add Water
  } else if (ML > soilLowWet && ML < soilHighWet)
  {
    digitalWrite(13, LOW);
    digitalWrite(12, HIGH);  // Green LED
    display();               // Stop Add Water
    
    delay(1000);
    pH_Fertilizer(); // Continue to next pH sensing & fertilizer addition when ML is sufficient
  }
}


void pH_Fertilizer()
{
  // pH Measurement
  for (int i = 0; i < 10; i++) {
    buffer_arr[i] = analogRead(A0);
    delay(30);
  }
  for (int i = 0; i < 9; i++) {
    for (int j = i + 1; j < 10; j++) {
      if (buffer_arr[i] > buffer_arr[j]) {
        temp = buffer_arr[i];
        buffer_arr[i] = buffer_arr[j];
        buffer_arr[j] = temp;
      }
    }
  }
  avgval = 0;
  for (int i = 2; i < 8; i++) {
    avgval += buffer_arr[i];
  }
  float volt = (float)avgval * 5.0 / 1024 / 6;
  float ph_act = -5.70 * volt + calibration_value;
  lcd.clear(); //Clean the screen
  lcd.setCursor(0, 0);
  lcd.print("pH Val:");
  lcd.setCursor(8, 0);
  lcd.print(ph_act);
  
  // Check pH Level and Control LEDs
  if (ph_act < 5.5) {
    digitalWrite(12, LOW);
    digitalWrite(13, HIGH);
    lcd.setCursor(0, 1);
    lcd.print("pH too low");
    delay(10000);
    
    // Add a bit of water
    myservo.write(70); // rotate the motor counterclockwise
    delay(500); // keep rotating for 0.5 seconds (500 milliseconds)
    myservo.write(90); // stop the motor
    delay(1000); // stay stopped
    myservo.write(110); // rotate the motor clockwise
    delay(500); // keep rotating for 0.5 seconds (500 milliseconds)
    myservo.write(90); // stop the motor
    delay(1000); //staystopped
  } else if (ph_act > 6.5) {
    digitalWrite(12, LOW);
    digitalWrite(13, HIGH);
    lcd.setCursor(0, 1);
    lcd.print("pH too high");
    delay(10000);
    
    // Add fertilizer
    myservo.write(70); // rotate the motor counterclockwise
    delay(500); // keep rotating for 0.5 seconds (500 milliseconds)
    myservo.write(90); // stop the motor
    delay(1000); // stay stopped
    myservo.write(110); // rotate the motor clockwise
    delay(500); // keep rotating for 0.5 seconds (500 milliseconds)
    myservo.write(90); // stop the motor
    delay(1000); //staystopped
  } else {
    digitalWrite(13, LOW);
    digitalWrite(12, HIGH);
    lcd.setCursor(0, 1);
    lcd.print("pH OK");
    delay(1000);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Soil Ready!");
  }
  
  delay(1000);
}


void display() 
{
  lcd.clear();//Clean the screen
  lcd.setCursor(0, 0);
  lcd.print("ML=");
  lcd.print(ML);
  
  if (ML < soilLowWet) 
  {
    lcd.setCursor(0, 1);
    lcd.print("Add Water");
  } else if (ML >= soilHighWet) {
    lcd.setCursor(0, 1);
    lcd.print("Stop Add Water");
  } else if (ML >= soilLowWet && ML <= soilHighWet) {
    lcd.setCursor(0, 1);
    lcd.print("Stop Add Water");
  }
  
  delay(1000);
  Serial.println();
}


//  This function returns the analog soil moisture measurement
int readSensor() 
{
	digitalWrite(sensorPower, HIGH);	// Turn the sensor ON
	delay(10);							          // Allow power to settle
	int val = analogRead(sensorPin);	// Read the analog value form sensor
	digitalWrite(sensorPower, LOW);		// Turn the sensor OFF
	return val;							          // Return analog moisture value
}

Credits

Bertrand Lau Yu Pang
1 project • 1 follower
Contact
NARENDRAN
20 projects • 22 followers
Contact
Wong Chu Han
1 project • 2 followers
Contact
Andrew Denilson
1 project • 2 followers
Contact
Farhan Hekanansyah
1 project • 1 follower
Contact

Comments

Please log in or sign up to comment.