#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "DHT.h"
// ==================== PIN DEFINITIONS ====================
#define DHTPIN 15
#define DHTTYPE DHT22
#define TRIG_PIN 5
#define ECHO_PIN 18
#define PIR_PIN 19
#define LDR_PIN 34 // ADC pin - Light sensor
#define MQ2_PIN 35 // ADC pin - Gas sensor (simulated with potentiometer)
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
// ==================== OBJECTS ====================
DHT dht(DHTPIN, DHTTYPE);
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ==================== VARIABLES ====================
float temperature = 0;
float humidity = 0;
long distance = 0;
bool motionDetected = false;
int lightValue = 0;
int gasValue = 0;
unsigned long lastUpdate = 0;
const int updateInterval = 2000;
// ==================== SETUP ====================
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n╔══════════════════════════════════════╗");
Serial.println("║ ESP32 5-SENSOR MONITORING SYSTEM ║");
Serial.println("║ DHT22 | HC-SR04 | PIR | LDR | MQ-2 ║");
Serial.println("╚══════════════════════════════════════╝\n");
// Initialize pins
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(PIR_PIN, INPUT);
// Initialize DHT
dht.begin();
// Initialize OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
} else {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0,0);
display.println(F("Initializing..."));
display.display();
}
delay(2000);
Serial.println("✓ All sensors initialized successfully");
Serial.println("Starting readings...\n");
}
// ==================== SENSOR FUNCTIONS ====================
float readUltrasonic() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000); // 30ms timeout
if (duration == 0) return 400; // No echo received
float dist = duration * 0.034 / 2;
// Constrain to realistic range
if (dist > 400) dist = 400;
if (dist < 2) dist = 2;
return dist;
}
void readDHT() {
float newTemp = dht.readTemperature();
float newHum = dht.readHumidity();
if (!isnan(newTemp)) temperature = newTemp;
if (!isnan(newHum)) humidity = newHum;
}
void readAnalogSensors() {
// Read LDR (0-4095 for ESP32 12-bit ADC)
lightValue = analogRead(LDR_PIN);
// Read MQ-2 Gas Sensor (simulated with potentiometer)
gasValue = analogRead(MQ2_PIN);
}
void readPIR() {
motionDetected = digitalRead(PIR_PIN);
}
// ==================== DISPLAY FUNCTIONS ====================
void updateSerialMonitor() {
Serial.println("┌────────────────────────────────────┐");
Serial.println("│ SENSOR READINGS │");
Serial.println("├────────────────────────────────────┤");
// Temperature & Humidity
Serial.printf("│ 🌡️ Temperature: %.1f °C │\n", temperature);
Serial.printf("│ 💧 Humidity: %.1f %% │\n", humidity);
// Distance
Serial.printf("│ 📏 Distance: %3ld cm │\n", distance);
// Motion
Serial.print("│ 🚶 Motion: ");
if (motionDetected) {
Serial.println("DETECTED! ⚠️ │");
} else {
Serial.println("None │");
}
// Light percentage
int lightPercent = map(lightValue, 0, 4095, 0, 100);
Serial.printf("│ 💡 Light Level: %3d %% │\n", lightPercent);
// Gas with status
Serial.printf("│ ☁️ Gas Level: %4d ", gasValue);
if (gasValue > 3000) Serial.print("DANGER! ");
else if (gasValue > 2000) Serial.print("Warning ");
else Serial.print("Safe ");
Serial.println(" │");
Serial.println("└────────────────────────────────────┘");
Serial.println();
}
void updateOLED() {
display.clearDisplay();
// Header
display.setTextSize(1);
display.setCursor(0,0);
display.print(F("5-SENSOR SYSTEM"));
display.drawLine(0, 10, 128, 10, SSD1306_WHITE);
// Temperature & Humidity
display.setCursor(0, 14);
display.printf("T:%.1fC H:%.0f%%", temperature, humidity);
// Distance
display.setCursor(0, 24);
display.printf("Dist:%3ldcm", distance);
// Motion indicator
display.setCursor(0, 34);
display.print(F("Motion:"));
if (motionDetected) {
display.print(F("YES!"));
display.fillCircle(110, 36, 4, SSD1306_WHITE);
} else {
display.print(F("No"));
}
// Light & Gas
int lightPercent = map(lightValue, 0, 4095, 0, 100);
display.setCursor(0, 44);
display.printf("Light:%3d%%", lightPercent);
display.setCursor(0, 54);
display.printf("Gas:%4d", gasValue);
// Alert indicator on OLED
if (gasValue > 3000 || motionDetected) {
display.setCursor(80, 54);
display.print(F("ALERT!"));
}
display.display();
}
// ==================== MAIN LOOP ====================
void loop() {
unsigned long currentMillis = millis();
// Read all sensors
readDHT();
distance = readUltrasonic();
readPIR();
readAnalogSensors();
// Update displays every interval
if (currentMillis - lastUpdate >= updateInterval) {
lastUpdate = currentMillis;
updateSerialMonitor();
updateOLED();
checkAlerts();
}
delay(100);
}
void checkAlerts() {
bool alert = false;
if (motionDetected) {
Serial.println("⚠️ ALERT: Motion detected in area!");
alert = true;
}
if (gasValue > 3000) {
Serial.println("🚨 DANGER: High gas concentration detected!");
alert = true;
}
if (temperature > 50) {
Serial.println("🔥 WARNING: Extreme temperature detected!");
alert = true;
}
if (alert) {
Serial.println("═══════════════════════════════════════\n");
}
}