#include <Wire.h>
#include <RTClib.h> // Interface real-time clock
#include <DHTesp.h>
#include <WiFi.h>
#include <ThingSpeak.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
// Pin definitions
#define PIR_PIN 26 // PIR sensor pin (motion detection)
#define LDR_PIN 34 // LDR sensor pin (ambient light detection, must be an analog-capable pin on ESP32)
#define LIGHT_PIN 25 // Light control pin (for LED or relay to control a light)
#define DHTPIN 18
#define REDLEDPIN 12 // Red LED pin
#define ORANGELEDPIN 13 // Orange LED pin
#define GREENLEDPIN 14 // Green LED pin
#define ECHO_PIN 32 // Ultrasonic sensor echo pin
#define TRIG_PIN 33 // Ultrasonic sensor trigger pin
#define PERSON_ECHO_PIN 4 // Person detection echo pin
#define PERSON_TRIG_PIN 19 // Person detection trigger pin
// Servo object for the bin
Servo servo;
int pos = 20; // Initial position of the servo
// Thresholds and timeout settings
const int lightThreshold = 500; // Adjust based on ambient light level needed to turn on the light
const unsigned long motionTimeout = 10000; // 10 seconds without motion to turn off light
// Variables for tracking state
unsigned long lastMotionTime = 0; // Last time motion was detected
bool lightOn = false; // Track if the light is currently on
WiFiClient client;
// WiFi credentials
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// ThingSpeak settings
unsigned long channelID = 2725112;
const char* writeAPIKey = "34G2P67PJ6J4EFMB";
LiquidCrystal_I2C lcd(0x27, 16, 2);
DHTesp banu;
TempAndHumidity data;
RTC_DS3231 rtc;
long duration;
int distance;
void checkDustbinStatus() {
// Maximum distance for the bin
int maxDistance = 400;
// Check the dustbin status
digitalWrite(TRIG_PIN, LOW);
delay(2000);
digitalWrite(TRIG_PIN, HIGH);
delay(10000);
digitalWrite(TRIG_PIN, LOW);
duration = pulseIn(ECHO_PIN, HIGH);
distance = duration * 0.034 / 2;
int percentage = (maxDistance - distance) * 100 / maxDistance;
Serial.print("Dust bin: ");
Serial.print(percentage);
if (percentage <= 80) {
Serial.println(" %");
} else {
Serial.println(" %, the dustbin is going to be full");
}
}
void controlServo(int personTrigPin, int personEchoPin, Servo &servo) {
long duration, distance;
// Send a pulse to the ultrasonic sensor
digitalWrite(personTrigPin, LOW);
delayMicroseconds(2);
digitalWrite(personTrigPin, HIGH);
delayMicroseconds(10);
digitalWrite(personTrigPin, LOW);
// Read the echo and calculate the distance
duration = pulseIn(personEchoPin, HIGH);
distance = duration * 0.034 / 2;
Serial.print("Person Distance from the bin: ");
Serial.print(distance);
Serial.println(" cm");
// Control the servo based on the person distance
if (distance <= 30) {
servo.write(pos + 160);
} else {
servo.write(pos);
}
}
int statusCode;
void setup() {
ThingSpeak.begin(client);
Serial.begin(115200);
Serial.println("System Starting...");
banu.setup(DHTPIN, DHTesp::DHT22);
lcd.init();
lcd.backlight();
pinMode(REDLEDPIN, OUTPUT);
pinMode(ORANGELEDPIN, OUTPUT);
pinMode(GREENLEDPIN, OUTPUT);
pinMode(PIR_PIN, INPUT); // Set PIR sensor as input
pinMode(LDR_PIN, INPUT); // Set LDR sensor as input
pinMode(LIGHT_PIN, OUTPUT); // Set light control pin as output
digitalWrite(LIGHT_PIN, LOW); // Start with light turned off
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(PERSON_TRIG_PIN, OUTPUT);
pinMode(PERSON_ECHO_PIN, INPUT);
servo.attach(23);
servo.write(pos);
Serial.println("Smart Light System Initialized");
if (!rtc.begin()) {
Serial.println("RTC initialization failed!");
while (1); // Halt if RTC fails to initialize
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, setting time to compile time.");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Display welcome message
lcd.setCursor(0, 0);
lcd.print("Welcome to");
lcd.setCursor(0, 1);
lcd.print("Smart Home");
delay(3000);
lcd.clear();
// Connect to WiFi
WiFi.mode(WIFI_STA);
}
void loop() {
// Ensure Wi-Fi connection
if (WiFi.status() != WL_CONNECTED) {
Serial.print("Attempting to connect");
while (WiFi.status() != WL_CONNECTED) {
WiFi.begin(ssid, pass);
Serial.print(".");
delay(5000);
}
Serial.println("\nConnected to WiFi.");
}
// Read sensor data
TempAndHumidity data = banu.getTempAndHumidity();
float temp = data.temperature;
float humi = data.humidity;
// Check for failed reads
if (isnan(humi) || isnan(temp)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// Get RTC time
DateTime now = rtc.now();
// Display data on LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(temp);
lcd.print("C H:");
lcd.print(humi);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print(now.day());
lcd.print('/');
lcd.print(now.month());
lcd.print('/');
lcd.print(now.year());
lcd.print(' ');
lcd.print(now.hour());
lcd.print(':');
lcd.print(now.minute());
// Print data to Serial Monitor
Serial.println("Humidity: " + String(humi) + " %");
Serial.println("Temperature: " + String(temp) + " ºC");
Serial.println("-----");
// Read the PIR sensor to detect motion
int pirState = digitalRead(PIR_PIN);
// Read the LDR sensor for ambient light level
int ldrValue = analogRead(LDR_PIN);
// Print readings to Serial Monitor
Serial.print("PIR State: ");
Serial.print(pirState);
Serial.print(" | LDR Value: ");
Serial.println(ldrValue);
// Check if motion is detected and ambient light is below threshold
if (pirState == HIGH && ldrValue < lightThreshold) {
lastMotionTime = millis(); // Update last motion detection time
if (!lightOn) {
digitalWrite(LIGHT_PIN, HIGH); // Turn on the light
lightOn = true;
Serial.println("Light ON");
}
}
// Check if the light should be turned off due to no motion
if (lightOn && (millis() - lastMotionTime > motionTimeout)) {
digitalWrite(LIGHT_PIN, LOW); // Turn off the light
lightOn = false;
Serial.println("Light OFF");
}
// LED control based on temperature and humidity
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: Temperature and humidity are low");
}
// Call controlServo function to update the servo position based on person detection
controlServo(PERSON_TRIG_PIN, PERSON_ECHO_PIN, servo);
// Check the dustbin status
checkDustbinStatus();
// Calculate fullness percentage and update ThingSpeak
int fullnessPercentage = (400 - distance) * 100 / 400; // Assuming maxDistance is 400
ThingSpeak.setField(1, temp);
ThingSpeak.setField(2, humi);
ThingSpeak.setField(3, String(now.year()) + "-" + String(now.month()) + "-" + String(now.day()) + " " + String(now.hour()) + ":" + String(now.minute()));
ThingSpeak.setField(4, lightOn ? 1 : 0);
Serial.print("Light Status: ");
ThingSpeak.setField(5, fullnessPercentage); // Assuming you want to send the distance as the bin level
statusCode = ThingSpeak.writeFields(channelID,writeAPIKey);
if(statusCode == 200) { //successful writing code
Serial.println("Channel update successful.");
}
else {
Serial.println("Problem Writing data. HTTP error code :" +
String(statusCode));
}
delay(2000); // Adjust delay as needed
}