#include <WiFi.h>
#include <RTClib.h>
#include <DHTesp.h>
#include <ThingSpeak.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
// ----- Pin Definitions -----
#define MQ2_AOUT_PIN 35
#define MQ2_DOUT_PIN 34
#define GASLIGHT_PIN 26
#define DHTPIN 18
#define REDLEDPIN 12
#define ORANGELEDPIN 13
#define GREENLEDPIN 14
#define PERSON_TRIG_PIN 19
#define PERSON_ECHO_PIN 4
#define SERVO_PIN 23
// ----- WiFi & ThingSpeak -----
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
WiFiClient client;
unsigned long channelID = 3027723;
const char* writeAPIKey = "TM9PHV4E6Q6GG6TG";
// ----- Global Objects -----
LiquidCrystal_I2C lcd(0x27, 16, 2);
DHTesp dht;
RTC_DS3231 rtc;
Servo radarServo;
// ----- Radar Servo Scan -----
const int centerAngle = 90;
const int scanDelay = 20;
const int objectThreshold = 30;
bool scanningRight = true;
int currentAngle = centerAngle;
int statusCode;
// ----- Function Prototypes -----
void connectWiFi();
long readDistanceCM();
void displayLCD(float temp, float humi, DateTime now);
void controlLEDs(float temp, float humi);
void gasSensorCheck();
void radarScan();
void uploadToThingSpeak(float temp, float humi, int gasValue, long distance);
void setup() {
Serial.begin(115200);
Serial.println("System Starting...");
dht.setup(DHTPIN, DHTesp::DHT22);
lcd.init();
lcd.backlight();
pinMode(REDLEDPIN, OUTPUT);
pinMode(ORANGELEDPIN, OUTPUT);
pinMode(GREENLEDPIN, OUTPUT);
pinMode(GASLIGHT_PIN, OUTPUT);
pinMode(MQ2_DOUT_PIN, INPUT);
pinMode(MQ2_AOUT_PIN, INPUT);
pinMode(PERSON_TRIG_PIN, OUTPUT);
pinMode(PERSON_ECHO_PIN, INPUT);
radarServo.attach(SERVO_PIN);
radarServo.write(centerAngle);
delay(1000);
if (!rtc.begin()) {
Serial.println("RTC initialization failed!");
while (1);
}
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
lcd.setCursor(0, 0);
lcd.print("Welcome to");
lcd.setCursor(0, 1);
lcd.print("Smart World");
delay(3000);
lcd.clear();
connectWiFi();
ThingSpeak.begin(client);
Serial.println("Smart Envi Robot Initialized");
}
void loop() {
if (WiFi.status() != WL_CONNECTED) {
connectWiFi();
}
TempAndHumidity data = dht.getTempAndHumidity();
float temp = data.temperature;
float humi = data.humidity;
if (isnan(humi) || isnan(temp)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
DateTime now = rtc.now();
displayLCD(temp, humi, now);
controlLEDs(temp, humi);
gasSensorCheck();
radarScan();
int gasAnalog = analogRead(MQ2_AOUT_PIN);
long distance = readDistanceCM();
uploadToThingSpeak(temp, humi, gasAnalog, distance);
delay(2000); // delay between readings
}
void connectWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\nConnected to WiFi.");
}
long readDistanceCM() {
digitalWrite(PERSON_TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(PERSON_TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(PERSON_TRIG_PIN, LOW);
long duration = pulseIn(PERSON_ECHO_PIN, HIGH, 30000);
return duration * 0.034 / 2;
}
void displayLCD(float temp, float humi, DateTime now) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.printf("T:%.1fC H:%.1f%%", temp, humi);
lcd.setCursor(0, 1);
lcd.printf("%02d/%02d/%d %02d:%02d", now.day(), now.month(), now.year(), now.hour(), now.minute());
Serial.printf("Humidity: %.1f %%\n", humi);
Serial.printf("Temperature: %.1f ºC\n", temp);
Serial.println("-----");
}
void controlLEDs(float temp, float humi) {
digitalWrite(REDLEDPIN, LOW);
digitalWrite(ORANGELEDPIN, LOW);
digitalWrite(GREENLEDPIN, LOW);
if (temp >= 70 && humi <= 30) {
digitalWrite(REDLEDPIN, HIGH);
Serial.println("Warning: You're in danger");
} else if (temp >= 30 && temp <= 70 && humi >= 30 && humi <= 60) {
digitalWrite(GREENLEDPIN, HIGH);
Serial.println("You're fine");
} else if (temp < 30 && humi > 60) {
digitalWrite(ORANGELEDPIN, HIGH);
Serial.println("Caution: Low temp/high humidity");
}
}
void gasSensorCheck() {
int analogValue = analogRead(MQ2_AOUT_PIN);
int gasDigital = digitalRead(MQ2_DOUT_PIN);
Serial.printf("Analog Gas Value: %d | Digital Trigger: %s\n", analogValue, gasDigital == HIGH ? "🚨 Detected" : "Safe");
digitalWrite(GASLIGHT_PIN, gasDigital == HIGH ? HIGH : LOW);
}
void radarScan() {
radarServo.write(currentAngle);
delay(scanDelay);
long distance = readDistanceCM();
Serial.printf("Angle: %d°, Distance: %ld cm\n", currentAngle, distance);
if (distance > 0 && distance < objectThreshold) {
Serial.println("🔍 Object detected within 30cm!");
delay(2000);
radarServo.write(centerAngle);
Serial.println("↩️ Returning to center");
delay(1000);
scanningRight = true;
currentAngle = centerAngle;
return;
}
if (scanningRight) {
currentAngle += 2;
if (currentAngle >= 180) {
scanningRight = false;
currentAngle = 180;
}
} else {
currentAngle -= 2;
if (currentAngle <= 0) {
scanningRight = true;
currentAngle = 0;
}
}
}
void uploadToThingSpeak(float temp, float humi, int gasValue, long distance) {
ThingSpeak.setField(1, temp);
ThingSpeak.setField(2, humi);
ThingSpeak.setField(3, gasValue);
ThingSpeak.setField(4, distance);
statusCode = ThingSpeak.writeFields(channelID, writeAPIKey);
if (statusCode == 200) {
Serial.println("✅ Channel update successful.");
} else {
Serial.printf("❌ Problem Writing data. HTTP error: %d\n", statusCode);
}
}