A comprehensive ESP32-based system tracking Soil, Air, Water, and Motion data in real-time using ThingSpeak Cloud.
Get the CodeConnect VCC to 3.3V/5V and GND common. Sensor data pins connect to GPIOs as listed below.
| Sensor | ESP32 Pin |
|---|---|
| Soil Moisture | GPIO 34 |
| Water Level | GPIO 35 |
| MQ-7 (CO) | GPIO 32 |
| Motion (PIR) | GPIO 18 |
| LDR (Light) | GPIO 25 |
| DHT22 | GPIO 2 |
| Buzzer | GPIO 4 |
Suggested enclosure design with ventilation for MQ-7/DHT22 sensors and water-proof probe access for Soil/Water sensors.
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);
}