#define BLYNK_TEMPLATE_ID "TMPL6BPiGZOpK"
#define BLYNK_TEMPLATE_NAME "smart"
#include <BlynkSimpleEsp32.h>
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
#include <WiFi.h>
#include <Keypad.h>
// Pin Definitions
#define DHTPIN 15
#define DHTTYPE DHT22
#define PUSHBUTTON_PIN 13
#define LED_PIN 14
#define SERVO_PIN 26
#define BUZZER_PIN 12 // Pin for Buzzer
// Define keypad layout and pins
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] = {16, 2, 4, 5};
byte colPins[COLS] = {18, 19, 27, 23};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Define servo settings
Servo myServo;
const int servoPin = 17;
const int unlockPosition = -90; // Set servo position to -90 degrees
const int lockPosition = 90; // Set servo position to +90 degrees
// Variables
bool locked = true;
char enteredCode[5]; // To store the entered code
int codeIndex = 0;
// Objects
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo hangerServo;
BlynkTimer timer;
// Blynk Auth and Wi-Fi Credentials
char auth[] = "ivBvGQ0o2KKZCR6mjH-pNva6VIRSqQmC";
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// State Variables
bool hangerOutside = false; // Tracks if the hanger is outside
bool buttonPressed = false; // Tracks the button press state
BLYNK_WRITE(V0) {
int switchState = param.asInt();
if (switchState == HIGH) {
unlockDoor();
} else {
lockDoor();
}
}
void setup() {
// Initialize Serial
Serial.begin(115200);
// Initialize Blynk
Blynk.begin(auth, ssid, pass);
myServo.attach(servoPin);
updateLockStatus();
timer.setInterval(1000L, updateBlynk);
// Initialize Pins
pinMode(PUSHBUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT); // Initialize buzzer pin
// Initialize DHT Sensor, LCD, and Servo
dht.begin();
hangerServo.attach(SERVO_PIN);
lcd.init();
lcd.backlight();
hangerServo.write(90); // Initial position inside
// Print Wi-Fi Status
if (WiFi.status() == WL_CONNECTED) {
Serial.println("Wi-Fi connected!");
} else {
Serial.println("Wi-Fi connection failed!");
}
// Timer for periodic updates to Blynk
timer.setInterval(2000L, sendToBlynk); // Every 2 seconds
Serial.println("System Initialized");
}
void updateBlynk() {
Blynk.virtualWrite(V0, locked ? 0 : 1); // Update switch widget state
}
void loop() {
Blynk.run();
timer.run(); // Run the BlynkTimer
char key = keypad.getKey();
if (key) {
handleKeypadInput(key);
}
// Read Pushbutton State with Debouncing
if (digitalRead(PUSHBUTTON_PIN) == LOW) {
if (!buttonPressed) {
buttonPressed = true; // Prevent multiple toggles for a single press
// Toggle the hanger position
hangerOutside = !hangerOutside;
if (hangerOutside) {
hangerServo.write(0); // Move hanger outside
digitalWrite(LED_PIN, LOW); // LED off
digitalWrite(BUZZER_PIN, LOW); // Turn off buzzer (sunny)
Serial.println("It's Sunny..! Moving hanger outside");
lcd.setCursor(0, 0);
lcd.print("It's sunny ");
} else {
hangerServo.write(90); // Move hanger inside
digitalWrite(LED_PIN, HIGH); // LED on
digitalWrite(BUZZER_PIN, HIGH); // Turn on buzzer (rainy)
Serial.println("It's rainy..! Moving hanger inside");
lcd.setCursor(0, 0);
lcd.print("It's raining ");
}
}
} else {
buttonPressed = false; // Reset button state when released
}
// Update LCD with Temperature and Humidity
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
lcd.setCursor(0, 1);
lcd.print("T:");
lcd.print(temperature);
lcd.print(" H:");
lcd.print(humidity);
}
// Function to send data to Blynk
void sendToBlynk() {
// Read DHT Sensor
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
// Check Sensor Readings
if (isnan(temperature) || isnan(humidity)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// Prepare status
String status = hangerOutside ? "Sunny" : "Raining";
// Send data to Blynk
Blynk.virtualWrite(V1, status); // V0 for Status
Blynk.virtualWrite(V2, temperature); // V1 for Temperature
Blynk.virtualWrite(V3, humidity); // V2 for Humidity
// Debug
Serial.print("Status: ");
Serial.println(status);
Serial.print("Temperature: ");
Serial.println(temperature);
Serial.print("Humidity: ");
Serial.println(humidity);
}
void updateLockStatus() {
if (locked) {
lcd.clear();
lcd.print("Door Locked");
Blynk.virtualWrite(V4, 0); // LED off for locked state
Blynk.virtualWrite(V5, "Door Locked");
} else {
lcd.clear();
lcd.print("Door Unlocked");
Blynk.virtualWrite(V0, 255); // LED on for unlocked state
Blynk.virtualWrite(V5, "Door Unlocked");
}
}
void handleKeypadInput(char key) {
if (locked) {
if (key == '#' && codeIndex > 0) { // Check for Enter key and if code is entered
enteredCode[codeIndex] = '\0'; // Null-terminate the entered code
codeIndex = 0; // Reset code index for next input
if (strcmp(enteredCode, "2222") == 0) { // Check if the entered code is correct
unlockDoor(); // Call function to unlock the door
lcd.clear();
lcd.print("Door Unlocked");
Blynk.virtualWrite(V5, "Door Unlocked"); // Update Blynk status
Blynk.virtualWrite(V0, 1); // Update Blynk switch widget
} else {
lcd.clear();
lcd.print("Incorrect Pin!");
delay(2000); // Display the message for 2 seconds
lcd.clear();
lcd.print("Door Locked");
Blynk.virtualWrite(V5, "Incorrect Pin!"); // Update Blynk status
}
// Clear entered code
memset(enteredCode, 0, sizeof(enteredCode));
} else if (key == 'C' && codeIndex > 0) { // Check for 'C' key to delete
lcd.setCursor(codeIndex - 1, 1);
lcd.print(' ');
codeIndex--;
enteredCode[codeIndex] = '\0';
} else if (key != '#' && key != 'C' && codeIndex < sizeof(enteredCode) - 1) {
enteredCode[codeIndex] = key;
lcd.setCursor(codeIndex, 1);
lcd.print('*');
codeIndex++;
}
} else {
if (key == '*') {
lockDoor();
lcd.clear();
lcd.print("Door Locked");
Blynk.virtualWrite(V5, "Door Locked");
Blynk.virtualWrite(V0, 0); // Set switch widget OFF
}
}
}
void unlockDoor() {
locked = false;
myServo.write(unlockPosition);
updateLockStatus();
}
void lockDoor() {
locked = true;
myServo.write(lockPosition);
updateLockStatus();
}