#include <DHTesp.h>
#include <WiFi.h>
#include <ThingSpeak.h>
#include <Keypad.h>
#include <ESP32Servo.h>
#include <LiquidCrystal_I2C.h>
// WiFi and ThingSpeak Settings
WiFiClient client;
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
unsigned long channelID = 2716175;
const char* writeAPIKey = "67DGUJBT27SKQC2T";
// Sensors and Components Pins
const int trigLid = 33; // Ultrasonic trig pin for lid control
const int echoLid = 16; // Ultrasonic echo pin for lid control
const int trigLevel = 19; // Ultrasonic trig pin for bin level
const int echoLevel = 23; // Ultrasonic echo pin for bin level
const int pirPin = 17; // PIR sensor pin
const int ldrPin = 34; // LDR sensor pin
const int lightPin = 25; // Pin to control the light (LED/Relay)
const int buzzerPin = 4; // Buzzer pin for incorrect password alert
Servo wasteBinServo;
DHTesp dhtSensor;
TempAndHumidity data;
// LCD Display Setup
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adjust address if needed
// Keypad for Door Lock System
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {12, 13, 14, 15}; // Connect to row pinouts of keypad
byte colPins[COLS] = {2, 4, 5, 32}; // Connect to column pinouts of keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Smart Door Lock Variables
bool locked = true;
char enteredCode[5]; // Store entered code
int codeIndex = 0;
int incorrectAttempts = 0; // Track incorrect attempts
unsigned long lockoutEndTime = 0; // Track lockout period
// Function Prototypes
float measureDistance(int trigPin, int echoPin);
void handleKeypadInput(char key);
void updateLockStatus();
void unlockDoor();
void lockDoor();
void controlSmartLight(bool personDetected, int ambientLight);
void updateThingSpeak(float temperature, float humidity, bool lightStatus, bool wasteBinStatus, bool incorrectPin, bool correctPin);
void setup() {
// Serial and WiFi Setup
Serial.begin(115200);
WiFi.mode(WIFI_STA);
ThingSpeak.begin(client);
// Sensor and Servo Setup
dhtSensor.setup(18, DHTesp::DHT22);
pinMode(trigLid, OUTPUT);
pinMode(echoLid, INPUT);
pinMode(trigLevel, OUTPUT);
pinMode(echoLevel, INPUT);
pinMode(pirPin, INPUT);
pinMode(lightPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
digitalWrite(buzzerPin, LOW);
// LCD Setup
lcd.begin(16, 2);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Door Status: Locked");
// Servo Attachments
wasteBinServo.attach(21); // Update this if needed
lockDoor();
}
void loop() {
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.");
}
data = dhtSensor.getTempAndHumidity();
float temp = data.temperature;
float humi = data.humidity;
float distanceLid = measureDistance(trigLid, echoLid);
float distanceLevel = measureDistance(trigLevel, echoLevel);
int ldrValue = analogRead(ldrPin);
Serial.println("LDR Value: " + String(ldrValue));
bool personDetected = digitalRead(pirPin) == HIGH;
controlSmartLight(personDetected, ldrValue);
bool lightStatus = digitalRead(lightPin) == HIGH;
bool wasteBinStatus = distanceLevel < 20;
updateThingSpeak(temp, humi, lightStatus, wasteBinStatus, false, false);
if (distanceLid < 20) {
wasteBinServo.write(0);
delay(1000);
} else {
wasteBinServo.write(90);
}
if (millis() > lockoutEndTime) {
char key = keypad.getKey();
if (key) {
handleKeypadInput(key);
}
} else {
lcd.setCursor(0, 1);
lcd.print("Wait: Locked Out ");
}
delay(1000);
}
float measureDistance(int trigPin, int echoPin) {
digitalWrite(trigPin, LOW);
delay(2);
digitalWrite(trigPin, HIGH);
delay(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
float distance = (duration * 0.0343) / 2;
return distance;
}
void handleKeypadInput(char key) {
if (locked) {
if (key == '#' && codeIndex > 0) {
enteredCode[codeIndex] = '\0';
codeIndex = 0;
if (strcmp(enteredCode, "1234") == 0) {
unlockDoor();
incorrectAttempts = 0;
updateThingSpeak(data.temperature, data.humidity, digitalRead(lightPin) == HIGH, measureDistance(trigLevel, echoLevel) < 20, false, true);
} else {
Serial.println("Incorrect Pin!");
digitalWrite(buzzerPin, HIGH);
delay(1000);
digitalWrite(buzzerPin, LOW);
updateThingSpeak(data.temperature, data.humidity, digitalRead(lightPin) == HIGH, measureDistance(trigLevel, echoLevel) < 20, true, false);
incorrectAttempts++;
if (incorrectAttempts >= 3) {
lockoutEndTime = millis() + 30000;
incorrectAttempts = 0;
}
}
memset(enteredCode, 0, sizeof(enteredCode));
} else if (key == 'C' && codeIndex > 0) {
codeIndex--;
enteredCode[codeIndex] = '\0';
} else if (key != '#' && key != 'C' && codeIndex < sizeof(enteredCode) - 1) {
enteredCode[codeIndex] = key;
codeIndex++;
}
} else {
if (key == '*') {
lockDoor();
}
}
lcd.setCursor(0, 1);
lcd.print("Entered: ");
for (int i = 0; i < codeIndex; i++) {
lcd.print('*');
}
}
void updateLockStatus() {
if (locked) {
Serial.println("Door Locked");
lcd.setCursor(0, 0);
lcd.print("Door Status: Locked");
} else {
Serial.println("Door Unlocked");
lcd.setCursor(0, 0);
lcd.print("Door Status: Unlocked");
}
}
void unlockDoor() {
locked = false;
updateLockStatus();
}
void lockDoor() {
locked = true;
updateLockStatus();
}
void controlSmartLight(bool personDetected, int ambientLight) {
const int lightThreshold = 500;
if (personDetected && ambientLight < lightThreshold) {
digitalWrite(lightPin, HIGH);
Serial.println("Light ON");
} else {
digitalWrite(lightPin, LOW);
Serial.println("Light OFF");
}
}
void updateThingSpeak(float temperature, float humidity, bool lightStatus, bool wasteBinStatus, bool incorrectPin, bool correctPin) {
ThingSpeak.setField(1, temperature);
ThingSpeak.setField(2, humidity);
ThingSpeak.setField(3, lightStatus ? 1 : 0);
ThingSpeak.setField(4, wasteBinStatus ? 1 : 0);
ThingSpeak.setField(5, incorrectPin ? 1 : 0);
ThingSpeak.setField(6, correctPin ? 1 : 0);
ThingSpeak.writeFields(channelID, writeAPIKey);
}