#define BLYNK_TEMPLATE_ID "TMPL66_fKJ2he"
#define BLYNK_TEMPLATE_NAME "Kien smarthome"
#define BLYNK_AUTH_TOKEN "6MImbj5l5yOq9GwL8mYO_JmmW1eKE6kI"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <DHTesp.h>
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
BlynkTimer timer;
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// Definitions and Global Variables for Smart Home
int val = 0, va1, va2, va3, va4, va5, ge, t = 15;
float tmp, hum = 0;
int ledPin = 33;
int inputPin = 27;
int pirState;
int k = 0;
int v = 0;
int displayMode = 0;
// Definitions and Global Variables for Door Lock
char password[5] = "1234"; // Default password
bool keyPress = false; // Flag to indicate if a key has been pressed
unsigned long timerMillis = 0;
int incorrectAttempts = 0; // Counter for incorrect password attempts
bool exceeded = false; // Add a new variable to keep track of exceeded attempts
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};
byte colPins[COLS] = {32, 17, 25, 26};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Define potentiometer pin
const int potPin = A0;
// Define servo settings
Servo myServo;
const int servoPin = 16;
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;
//temp symbol
byte t1[8]={B00000, B00001, B00010, B00100, B00100, B00100, B00100, B00111,};
byte t2[8]={B00111, B00111, B00111, B01111,B11111, B11111, B01111, B00011,};
byte t3[8]={B00000, B10000, B01011, B00100, B00111, B00100, B00111, B11100,};
byte t4[8]={B11111, B11100, B11100, B11110,B11111, B11111, B11110, B11000,};
//humidity symbol
byte hum1[8]={B00000, B00001, B00011, B00011,B00111, B01111, B01111, B11111,};
byte hum2[8]={B11111, B11111, B11111, B01111,B00011, B00000, B00000, B00000,};
byte hum3[8]={B00000, B10000, B11000, B11000, B11100, B11110, B11110, B11111,};
byte hum4[8]={B11111, B11111, B11111, B11110, B11100, B00000, B00000, B00000,};
//Home Symbol
byte house1[8]={B00000, B00001, B00011, B00011, B00111, B01111, B01111, B11111,};
byte house2[8]={B11111, B11111, B11100, B11100, B11100, B11100, B11100, B11100,};
byte house3[8]={B00000, B10010, B11010, B11010, B11110, B11110, B11110, B11111,};
byte house4[8]={B11111, B11111, B11111, B10001, B10001, B10001, B11111, B11111,};
byte d[8] = { 0b00011,0b00011,0b00000,0b00000,0b00000,0b00000,0b00000,0b00000 };
byte Lck[] = { B01110, B10001, B10001, B11111, B11011, B11011, B11111, B00000 };
// Declare DHTesp object
DHTesp temps;
BLYNK_WRITE(V0){
va1 = param.asInt();
digitalWrite(5, va1);
}
BLYNK_WRITE(V1){
va2 = param.asInt();
digitalWrite(18, va2);
}
BLYNK_WRITE(V2){
va3 = param.asInt();
digitalWrite(19, va3);
}
BLYNK_WRITE(V3){
va4 = param.asInt();
digitalWrite(4, va4);
}
BLYNK_WRITE(V4){
va5 = param.asInt();
digitalWrite(2, va5);
}
BLYNK_WRITE(V7) {
pirState = param.asInt();
if(pirState == 0){
digitalWrite(ledPin, LOW);
k = 1;
ge = 0;
}
else {
digitalWrite(ledPin, HIGH);
k= 0;
ge = 1;
}
}
BLYNK_WRITE(V8) {
int switchState = param.asInt();
if (switchState == HIGH) {
unlockDoor();
} else {
lockDoor();
}
}
BLYNK_WRITE(V9) {
String newPassword = param.asStr();
newPassword.toCharArray(password, sizeof(password));
// Reset the exceeded variable to false when a new password is set
incorrectAttempts = 0;
exceeded = false;
}
void myTimer() {
Blynk.virtualWrite(V5, tmp);
Blynk.virtualWrite(V6, hum);
}
void setup() {
Serial.begin(115200);
Blynk.begin(auth, ssid, pass);
pinMode(5, OUTPUT);
pinMode(18, OUTPUT);
pinMode(19, OUTPUT);
pinMode(4, OUTPUT);
pinMode(23, INPUT);
pinMode(2, OUTPUT);
temps.setup(t, DHTesp::DHT22);
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT_PULLUP);
lcd.init();
lcd.backlight();
digitalWrite(5, LOW);
digitalWrite(18, LOW);
digitalWrite(19, LOW);
digitalWrite(21, LOW);
lcd.setCursor(0, 2);
lcd.print("--------------------");
delay(3000);
lcd.clear();
lcd.createChar(6, Lck);
lcd.createChar(1, house1);
lcd.createChar(2, house2);
lcd.createChar(3, house3);
lcd.createChar(4, house4);
lcd.setCursor(1, 2);
lcd.write(1);
lcd.setCursor(1, 3);
lcd.write(2);
lcd.setCursor(2, 2);
lcd.write(3);
lcd.setCursor(2, 3);
lcd.write(4);
lcd.setCursor(17, 2);
lcd.write(1);
lcd.setCursor(17, 3);
lcd.write(2);
lcd.setCursor(18, 2);
lcd.write(3);
lcd.setCursor(18, 3);
lcd.write(4);
lcd.setCursor(19, 0);
lcd.write(6);
lcd.setCursor(9, 0);
lcd.print("connected-");
lcd.setCursor(2, 1);
lcd.print("HOME AUTOMATION");
lcd.setCursor(6, 2);
lcd.print("USING IOT");
delay(3000);
Blynk.virtualWrite(V7, pirState);
timer.setInterval(1000L, myTimer);
myServo.attach(servoPin);
lcd.init();
lcd.backlight();
updateLockStatus();
timer.setInterval(1000L, updateBlynk);
}
void updateBlynk() {
Blynk.virtualWrite(V8, locked ? 0 : 1); // Update switch widget state
}
void loop() {
Blynk.run();
timer.run();
char key = keypad.getKey();
if (key) {
keyPress = true; // A key has been pressed
Serial.println(key); // Debugging line
handleKeypadInput(key);
}
// Check for locked variable and do not call the displayInfo function if the door is locked
if (!locked) {
// Check the timerMillis condition here
if (millis() - timerMillis > 5000) {
// Call the displayInfo function if 5 seconds have passed
displayInfo();
}
}
}
void updateLockStatus() {
if (locked) {
lcd.clear();
lcd.print("Door Locked");
} else {
lcd.clear();
lcd.print("Door Unlocked");
}
}
void unlockDoor() {
locked = false;
myServo.write(unlockPosition);
updateLockStatus();
}
void lockDoor() {
locked = true;
myServo.write(lockPosition);
updateLockStatus();
}
void handleKeypadInput(char key) {
keyPress = true; // A key has been pressed
if (locked && incorrectAttempts < 3 && !exceeded) { // Check for exceeded variable
if (key == '#') {
lcd.clear();
lcd.print("Door Locked");
enteredCode[codeIndex] = '\0'; // Null-terminate the entered code
codeIndex = 0;
if (strcmp(enteredCode, password) == 0) { // Check if the entered code is correct
unlockDoor();
lcd.clear();
lcd.print("Door Unlocked");
Blynk.virtualWrite(V8, 1); // Set switch widget ON
incorrectAttempts = 0; // Reset the counter
// Set the locked variable to false when the password is correct
locked = false;
// Set the timer to the current time when the door is unlocked
timerMillis = millis();
displayMode = 0;
} else {
incorrectAttempts++; // Increment the counter
lcd.clear();
lcd.print("Incorrect Pin!");
delay(2000); // Display the message for 2 seconds
lcd.clear();
lcd.print("Door Locked");
if (incorrectAttempts >= 3) { // Check if the counter has reached 3
Blynk.logEvent("wrong_password", "Warning: 3 incorrect password attempts!"); // Log an event and send a notification
lcd.clear();
lcd.print("3 Incorrect Attempts!");
delay(2000); // Display the message for 2 seconds
lcd.clear();
lcd.print("Door Locked");
// Set the exceeded variable to true when 3 incorrect attempts are made
exceeded = true;
}
}
} 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' && key != '*' && key != 'A' && key != 'B' && key != 'D' && codeIndex < sizeof(enteredCode) - 1) {
// Check for '*' key and 'A', 'B', 'C', 'D' keys and ignore them
enteredCode[codeIndex] = key;
lcd.setCursor(codeIndex, 1);
lcd.print('*');
codeIndex++;
}
} else if (!locked) {
if (key == '*') {
lockDoor();
lcd.clear();
lcd.print("Door Locked");
Blynk.virtualWrite(V8, 0); // Set switch widget OFF
// Set the locked variable to true when the door is locked
locked = true;
} else {
// Call the handleKeypadInput function when any other key is pressed while the door is unlocked
handleKeypadInput(key);
}
}
}
void displayInfo() {
// Check for exceeded variable and display the message if true
if (exceeded) {
lcd.clear();
lcd.print("You have exceeded");
lcd.setCursor(0, 1);
lcd.print("the maximum number");
lcd.setCursor(0, 2);
lcd.print("of attempts");
return; // Return from the function and do not display anything else
}
TempAndHumidity x = temps.getTempAndHumidity();
tmp = x.temperature;
hum = x.humidity;
val = digitalRead(23);
Serial.print("Value of digitalRead(23): "); // Debug print statement
Serial.println(val); // Debug print statement
if (val == 1) {
digitalWrite(2, va5);
} else {
digitalWrite(2, LOW);
}
v = digitalRead(inputPin);
Serial.print("Value of digitalRead(inputPin): "); // Debug print statement
Serial.println(v); // Debug print statement
if (v == HIGH) {
if (k == 1) {
digitalWrite(ledPin, LOW);
k = 0 ;
ge = 0;
}
else if (k == 0) {
digitalWrite(ledPin, HIGH);
k = 1;
ge = 1;
}
}
// Use the displayMode variable to switch between different displays
switch (displayMode) {
case 0: // Display the switches status
if (va1 == 1) {
lcd.clear();
lcd.setCursor(19, 0);
lcd.write(6);
lcd.setCursor(0, 1);
lcd.print("SW_1= ");
lcd.print("ON ");
} else {
lcd.clear();
lcd.setCursor(19, 0);
lcd.write(6);
lcd.setCursor(0, 1);
lcd.print("SW_1= ");
lcd.print("OFF");
}
if (va2 == 1) {
lcd.setCursor(11, 1);
lcd.print("SW_2= ");
lcd.print("ON ");
} else {
lcd.setCursor(11, 1);
lcd.print("SW_2= ");
lcd.print("OFF");
}
if (va3 == 1) {
lcd.setCursor(0, 2);
lcd.print("SW_3= ");
lcd.print("ON ");
} else {
lcd.setCursor(0, 2);
lcd.print("SW_3= ");
lcd.print("OFF");
}
if (va4 == 1) {
lcd.setCursor(11, 2);
lcd.print("SW_4= ");
lcd.print("ON ");
} else {
lcd.setCursor(11, 2);
lcd.print("SW_4= ");
lcd.print("OFF");
}
if (va5 == 1) {
lcd.setCursor(0, 3);
lcd.print("OD_L= ");
lcd.print("ON ");
} else {
lcd.setCursor(0, 3);
lcd.print("OD_L= ");
lcd.print("OFF");
}
if (ge == 1) {
lcd.setCursor(11, 3);
lcd.print("WR_L= ");
lcd.print("ON ");
} else {
lcd.setCursor(11, 3);
lcd.print("WR_L= ");
lcd.print("OFF");
}
delay(1500);
// Increment the displayMode variable to switch to the next display
displayMode++;
break;
case 1: // Display the temperature
lcd.clear();
lcd.createChar(1, t1);
lcd.createChar(2, t2);
lcd.createChar(3, t3);
lcd.createChar(4, t4);
lcd.createChar(5, d);
lcd.createChar(6, Lck);
lcd.setCursor(19, 0);
lcd.write(6);
lcd.setCursor(1, 1);
lcd.write(1);
lcd.setCursor(1, 2);
lcd.write(2);
lcd.setCursor(2, 1);
lcd.write(3);
lcd.setCursor(2, 2);
lcd.write(4);
lcd.setCursor(4, 1);
lcd.print("Temperature :");
lcd.setCursor(7, 2);
lcd.print(tmp);
lcd.setCursor(11, 2);
lcd.write(5);
lcd.setCursor(12, 2);
lcd.print("C");
// Increment the displayMode variable to switch to the next display
delay(750);
displayMode++;
break;
case 2: // Display the humidity
lcd.clear();
lcd.createChar(1, hum1);
lcd.createChar(2, hum2);
lcd.createChar(3, hum3);
lcd.createChar(4, hum4);
lcd.setCursor(19, 0);
lcd.write(6);
lcd.setCursor(3, 1);
lcd.write(1);
lcd.setCursor(3, 2);
lcd.write(2);
lcd.setCursor(4, 1);
lcd.write(3);
lcd.setCursor(4, 2);
lcd.write(4);
lcd.setCursor(6, 1);
lcd.print("Humidity :");
lcd.setCursor(7, 2);
lcd.print(hum);
lcd.setCursor(12, 2);
lcd.print("%");
delay(750);
// Reset the displayMode variable to switch to the first display
displayMode = 0;
break;
}
}