Back to kawshik.dev

EcoSense IoT Monitor

A comprehensive ESP32-based system tracking Soil, Air, Water, and Motion data in real-time using ThingSpeak Cloud.

Get the Code
Soil Moisture
Capacitive tracking (Pin 34)
CO Levels
MQ-7 Gas Sensor (Pin 32)
Water Level
Auto-Buzzer Alert (Pin 35)
DHT22 Weather
Temp & Humidity (Pin 2)

System Architecture

Circuit Diagram

Connect VCC to 3.3V/5V and GND common. Sensor data pins connect to GPIOs as listed below.

Pin Configuration

SensorESP32 Pin
Soil MoistureGPIO 34
Water LevelGPIO 35
MQ-7 (CO)GPIO 32
Motion (PIR)GPIO 18
LDR (Light)GPIO 25
DHT22GPIO 2
BuzzerGPIO 4

Hardware Implementation

3D Enclosure View

Visual Concept

Suggested enclosure design with ventilation for MQ-7/DHT22 sensors and water-proof probe access for Soil/Water sensors.

Key Features

  • Real-time Cloud Sync: Uploads to ThingSpeak every 5s.
  • Safety Alert: Buzzer triggers on low water level (<100).
  • Multi-Sensor: Tracks 7 different environmental metrics simultaneously.

Full Source Code

Copy the code below into your Arduino IDE. Ensure you have installed the DHT and ThingSpeak libraries.

/*
 * IoT Environmental Monitoring System
 * Author: Kawshik Ahmed Ornob
 * Board: ESP32 Dev Module
 */

#include <WiFi.h>
#include "ThingSpeak.h"
#include "DHT.h"

// --- Pin Definitions ---
#define SOIL_PIN 34
#define WATER_PIN 35
#define MQ7_PIN 32
#define PIR_PIN 18
#define LDR_PIN 25
#define DHT_PIN 2
#define BUZZER_PIN 4

// --- Sensor Setup ---
#define DHTTYPE DHT22
DHT dht(DHT_PIN, DHTTYPE);

// --- WiFi Credentials ---
const char* ssid = "YOUR_WIFI_NAME";   // Change this
const char* password = "YOUR_WIFI_PASS"; // Change this

// --- ThingSpeak Setup ---
unsigned long myChannelNumber = 1234567; // Change this
const char* myWriteAPIKey = "YOUR_API_KEY"; // Change this

WiFiClient client;

void setup() {
  Serial.begin(115200);

  // Initialize Pins
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(PIR_PIN, INPUT);
  pinMode(SOIL_PIN, INPUT);
  pinMode(WATER_PIN, INPUT);
  pinMode(MQ7_PIN, INPUT);
  pinMode(LDR_PIN, INPUT);

  // Initialize DHT
  dht.begin();

  // Connect to WiFi
  WiFi.mode(WIFI_STA);
  ThingSpeak.begin(client);
  
  Serial.print("Connecting to WiFi...");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnected!");
}

void loop() {
  // --- 1. Read Sensors ---
  int soilVal = analogRead(SOIL_PIN);
  int waterLevel = analogRead(WATER_PIN);
  int mq7Val = analogRead(MQ7_PIN);
  int ldrVal = analogRead(LDR_PIN);
  int motionVal = digitalRead(PIR_PIN);
  
  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  // Check DHT errors
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // --- 2. Safety Logic (Buzzer) ---
  // Trigger buzzer if water level is critically low
  if (waterLevel < 100) {
    digitalWrite(BUZZER_PIN, HIGH);
    Serial.println("ALERT: Low Water Level!");
  } else {
    digitalWrite(BUZZER_PIN, LOW);
  }

  // --- 3. Debug Print ---
  Serial.print("Temp: "); Serial.print(temperature);
  Serial.print(" | Hum: "); Serial.print(humidity);
  Serial.print(" | Soil: "); Serial.print(soilVal);
  Serial.print(" | Water: "); Serial.print(waterLevel);
  Serial.print(" | CO: "); Serial.println(mq7Val);

  // --- 4. Upload to ThingSpeak ---
  ThingSpeak.setField(1, waterLevel);
  ThingSpeak.setField(2, mq7Val);
  ThingSpeak.setField(3, ldrVal);
  ThingSpeak.setField(4, humidity);
  ThingSpeak.setField(5, temperature);
  ThingSpeak.setField(6, soilVal);
  ThingSpeak.setField(7, motionVal);

  int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);

  if(x == 200){
    Serial.println("Channel update successful.");
  }
  else{
    Serial.println("Problem updating channel. HTTP error code " + String(x));
  }

  // Wait 5 seconds before next update
  delay(5000);
}