OC
OceanRemote
Low-code IoT platform
โ† Back to Course

Complete Soil Monitoring Station

Complete Soil Monitoring Station

๐Ÿ› ๏ธ Complete Soil Monitoring Station - Smart Soil Health System

๐ŸŒฑ What You'll Learn in This Lesson:

  • ๐ŸŒก๏ธ Monitor soil moisture, temperature, NPK nutrients, and pH
  • ๐Ÿ“Š Build a complete soil health monitoring station
  • ๐Ÿ’ฐ Understand ROI - pays for itself in 1-2 seasons
  • ๐Ÿ”‹ Make your station solar-powered for remote operation
  • ๐Ÿ“ก Send soil data to OceanRemote cloud dashboard

๐Ÿ›’ Complete Bill of Materials

๏ฝœ๏ฝœDSML๏ฝœ๏ฝœ
Component Model/Type Purpose Cost
Soil Moisture Capacitive (v2.0) Measures water content 0-100% $8-12
Soil Temperature DS18B20 Waterproof -55ยฐC to +125ยฐC at root depth $5-8
NPK Sensor JXCT RS485 Nitrogen, Phosphorus, Potassium levels $50-70
pH Meter Analog pH Sensor (SEN0161) Soil acidity/alkalinity (3-9 pH) $12-18
Microcontroller ESP32 (30-pin) Data processing + WiFi $6-10
Solar Power 6V 2W Solar + TP4056 + 18650 Off-grid power for remote fields $12-18
Enclosure IP65 Weatherproof Box Protects electronics from rain/dust $8-12
Total Investment - Complete soil monitoring station $100-140
๐ŸŒŸ Return on Investment (ROI) Calculation:
  • ๐Ÿ’ง Water savings: 30-40% reduction โ†’ saves $30-50 per season
  • ๐ŸŒฑ Fertilizer savings: Apply only when needed โ†’ saves $40-60 per season
  • ๐Ÿ“ˆ Yield increase: 20-30% higher production โ†’ $100-200 additional revenue
  • ๐Ÿ’ฐ Total annual savings: $170-310 per hectare
  • โฐ Payback period: 1-2 growing seasons!

๐Ÿ”Œ Complete Wiring Diagram

โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
                    COMPLETE SOIL MONITORING STATION WIRING
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

    ESP32 PIN MAPPING:
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚                                                                         โ”‚
    โ”‚  Soil Moisture Sensor (Capacitive)                                     โ”‚
    โ”‚  VCC  โ†’ 3.3V                                                           โ”‚
    โ”‚  GND  โ†’ GND                                                            โ”‚
    โ”‚  OUT  โ†’ GPIO32 (Analog)                                                โ”‚
    โ”‚                                                                         โ”‚
    โ”‚  DS18B20 (Soil Temperature)                                            โ”‚
    โ”‚  Red     โ†’ 3.3V                                                        โ”‚
    โ”‚  Black   โ†’ GND                                                         โ”‚
    โ”‚  Yellow  โ†’ GPIO4 (OneWire) + 4.7kฮฉ pull-up to 3.3V                    โ”‚
    โ”‚                                                                         โ”‚
    โ”‚  NPK Sensor (RS485) - requires MAX485 module                           โ”‚
    โ”‚  MAX485          โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ESP32                                      โ”‚
    โ”‚  VCC             โ†’ 5V                                                  โ”‚
    โ”‚  GND             โ†’ GND                                                 โ”‚
    โ”‚  RO (Receiver Out) โ†’ GPIO16 (RX2)                                      โ”‚
    โ”‚  DI (Driver In)   โ†’ GPIO17 (TX2)                                       โ”‚
    โ”‚  RE/DE            โ†’ GPIO18 (Control)                                   โ”‚
    โ”‚                                                                         โ”‚
    โ”‚  pH Sensor (Analog)                                                    โ”‚
    โ”‚  VCC  โ†’ 3.3V                                                           โ”‚
    โ”‚  GND  โ†’ GND                                                            โ”‚
    โ”‚  OUT  โ†’ GPIO33 (Analog)                                                โ”‚
    โ”‚                                                                         โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

    SOLAR POWER CONNECTION:
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚  6V Solar Panel โ”€โ”€โ–บ TP4056 Charger (IN+ / IN-)                        โ”‚
    โ”‚  18650 Battery   โ”€โ”€โ–บ TP4056 (BAT+ / BAT-)                             โ”‚
    โ”‚  TP4056 (OUT+)    โ”€โ”€โ–บ MT3608 Boost Converter (IN+)                     โ”‚
    โ”‚  TP4056 (OUT-)    โ”€โ”€โ–บ MT3608 (IN-) + ESP32 GND                        โ”‚
    โ”‚  MT3608 (OUT+)    โ”€โ”€โ–บ ESP32 VIN (5V)                                   โ”‚
    โ”‚                                                                         โ”‚
    โ”‚  This provides stable 5V for ESP32 and sensors for 3-5 days without sunโ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

๐Ÿ’ป Complete Soil Monitoring Code

/*
 * Complete Soil Monitoring Station
 * Measures: Moisture, Temperature, NPK, pH
 * 
 * Components:
 * - Capacitive soil moisture sensor
 * - DS18B20 soil temperature sensor
 * - JXCT NPK sensor (RS485)
 * - Analog pH sensor
 * - ESP32 with WiFi
 */

#include 
#include 
#include 
#include 
#include 

// ========== WIFI CONFIGURATION ==========
const char* ssid = "YOUR_WIFI";
const char* password = "YOUR_PASSWORD";
const char* oceanRemoteToken = "YOUR_TOKEN";

// ========== PIN DEFINITIONS ==========
#define SOIL_MOISTURE_PIN 32
#define PH_PIN 33
#define ONE_WIRE_BUS 4
#define RS485_RX 16
#define RS485_TX 17
#define RS485_RE_DE 18

// ========== SENSOR CALIBRATION ==========
const int SOIL_DRY = 3800;
const int SOIL_WET = 1500;

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature soilTemp(&oneWire);

ModbusMaster npkSensor;

// ========== READ SOIL MOISTURE ==========
int readSoilMoisture() {
    int raw = analogRead(SOIL_MOISTURE_PIN);
    int percentage = map(raw, SOIL_DRY, SOIL_WET, 0, 100);
    percentage = constrain(percentage, 0, 100);
    return percentage;
}

// ========== READ SOIL TEMPERATURE ==========
float readSoilTemperature() {
    soilTemp.requestTemperatures();
    float temp = soilTemp.getTempCByIndex(0);
    if (temp == -127.0) return 0;
    return temp;
}

// ========== READ NPK VALUES (RS485) ==========
void readNPK(float &nitrogen, float &phosphorus, float &potassium) {
    uint8_t result;
    uint16_t data[6];
    
    // Read NPK sensor using Modbus protocol
    result = npkSensor.readHoldingRegisters(0x001E, 3);
    if (result == npkSensor.ku8MBSuccess) {
        data[0] = npkSensor.getResponseBuffer(0);
        data[1] = npkSensor.getResponseBuffer(1);
        data[2] = npkSensor.getResponseBuffer(2);
        
        nitrogen = data[0] / 10.0;
        phosphorus = data[1] / 10.0;
        potassium = data[2] / 10.0;
    } else {
        nitrogen = 0;
        phosphorus = 0;
        potassium = 0;
    }
}

// ========== READ PH VALUE ==========
float readPH() {
    int raw = analogRead(PH_PIN);
    float voltage = raw * (3.3 / 4095.0);
    
    // pH = 7 + (2.5 - voltage) * (7 / 1.5)
    float ph = 7.0 + (2.5 - voltage) * 4.67;
    ph = constrain(ph, 3.0, 9.0);
    return ph;
}

// ========== GET SOIL RECOMMENDATIONS ==========
String getSoilRecommendations(int moisture, float temp, 
                               float nitrogen, float phosphorus, 
                               float potassium, float ph) {
    String rec = "";
    
    if (moisture < 35) rec += "โš ๏ธ Soil dry - Irrigate soon. ";
    else if (moisture > 75) rec += "โš ๏ธ Soil wet - Reduce watering. ";
    else rec += "โœ… Moisture optimal. ";
    
    if (temp < 15) rec += "โ„๏ธ Soil cool - Delay planting. ";
    else if (temp > 35) rec += "๐Ÿ”ฅ Soil hot - Increase mulch/water. ";
    else rec += "โœ… Temperature optimal. ";
    
    if (nitrogen < 30) rec += "๐ŸŒฟ Low nitrogen - Add manure/fertilizer. ";
    else if (nitrogen > 100) rec += "โš ๏ธ Excess nitrogen - Reduce fertilizer. ";
    
    if (phosphorus < 15) rec += "๐ŸŒฑ Low phosphorus - Add bone meal. ";
    if (potassium < 150) rec += "๐ŸŒ Low potassium - Add wood ash/potash. ";
    
    if (ph < 5.5) rec += "๐Ÿงช Soil acidic - Add lime. ";
    else if (ph > 7.5) rec += "๐Ÿงช Soil alkaline - Add sulfur/organic matter. ";
    else rec += "โœ… pH optimal (6.0-7.0). ";
    
    return rec;
}

// ========== SEND TO OCEANREMOTE ==========
void sendToCloud(int moisture, float temp, 
                  float nitrogen, float phosphorus, 
                  float potassium, float ph) {
    if (WiFi.status() != WL_CONNECTED) return;
    
    HTTPClient http;
    http.begin("https://api.oceanremote.net/device/state");
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    
    String data = "token=" + String(oceanRemoteToken);
    data += "&soil_moisture=" + String(moisture);
    data += "&soil_temperature=" + String(temp);
    data += "&nitrogen=" + String(nitrogen);
    data += "&phosphorus=" + String(phosphorus);
    data += "&potassium=" + String(potassium);
    data += "&ph=" + String(ph);
    data += "&recommendation=" + getSoilRecommendations(moisture, temp, nitrogen, phosphorus, potassium, ph);
    
    http.POST(data);
    http.end();
}

// ========== DISPLAY REPORT ==========
void displayReport(int moisture, float temp,
                    float nitrogen, float phosphorus,
                    float potassium, float ph) {
    Serial.println("\nโ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—");
    Serial.println("โ•‘              ๐ŸŒฑ SOIL HEALTH MONITORING REPORT                 โ•‘");
    Serial.println("โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•");
    
    Serial.println("\n๐Ÿ’ง SOIL MOISTURE:");
    Serial.printf("   %d%% - ", moisture);
    if (moisture < 35) Serial.println("Needs irrigation");
    else if (moisture > 75) Serial.println("Reduce watering");
    else Serial.println("โœ… Optimal");
    
    Serial.println("\n๐ŸŒก๏ธ SOIL TEMPERATURE:");
    Serial.printf("   %.1fยฐC - ", temp);
    if (temp < 15) Serial.println("Too cool");
    else if (temp > 35) Serial.println("Too hot");
    else Serial.println("โœ… Optimal for most crops");
    
    Serial.println("\n๐ŸŒฟ SOIL NUTRIENTS:");
    Serial.printf("   Nitrogen (N): %.1f mg/kg - ", nitrogen);
    Serial.println(nitrogen < 30 ? "Low" : (nitrogen > 100 ? "High" : "Optimal"));
    Serial.printf("   Phosphorus (P): %.1f mg/kg - ", phosphorus);
    Serial.println(phosphorus < 15 ? "Low" : (phosphorus > 50 ? "High" : "Optimal"));
    Serial.printf("   Potassium (K): %.1f mg/kg - ", potassium);
    Serial.println(potassium < 150 ? "Low" : (potassium > 300 ? "High" : "Optimal"));
    
    Serial.println("\nโš—๏ธ SOIL pH:");
    Serial.printf("   %.1f - ", ph);
    if (ph < 5.5) Serial.println("Acidic (Add lime)");
    else if (ph > 7.5) Serial.println("Alkaline (Add sulfur)");
    else Serial.println("โœ… Optimal (6.0-7.0)");
    
    Serial.println("\n๐ŸŽฏ RECOMMENDATIONS:");
    Serial.println("   " + getSoilRecommendations(moisture, temp, nitrogen, phosphorus, potassium, ph));
    
    Serial.println("\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•\n");
}

void setup() {
    Serial.begin(115200);
    
    // Initialize sensors
    soilTemp.begin();
    pinMode(SOIL_MOISTURE_PIN, INPUT);
    pinMode(PH_PIN, INPUT);
    
    // Initialize RS485 for NPK sensor
    Serial2.begin(9600, SERIAL_8N1, RS485_RX, RS485_TX);
    pinMode(RS485_RE_DE, OUTPUT);
    digitalWrite(RS485_RE_DE, LOW);
    npkSensor.begin(1, Serial2);
    
    // Connect to WiFi
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) delay(500);
    Serial.println("โœ… WiFi connected!");
    
    Serial.println("โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•");
    Serial.println("๐ŸŒฑ COMPLETE SOIL MONITORING STATION v2.0");
    Serial.println("   Soil Health Monitoring System");
    Serial.println("โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•\n");
}

void loop() {
    int moisture = readSoilMois
        
        
        
        
        
        
        
        
        
        
        
        
๐Ÿ’ก Key Takeaways:
  • Apply these concepts directly to your farm or project.
  • Take notes on important details for the quiz.
  • Use the button below to track your progress.