#include <Keypad.h>
#include <ESP32Servo.h>
#include <WiFi.h>
#include <PubSubClient.h>
// Wi-Fi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "iotappsec";
// MQTT broker details
const char* mqtt_server = "mqtt-dashboard.com";
const int mqtt_port = 8884; // Use non-encrypted MQTT port
const char* mqtt_client_id = "clientId-Yc21ABPqDs";
const char* mqtt_topic = "smartlock/status";
// Define keypad settings
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] = {21, 19, 18, 5};
byte colPins[COLS] = {17, 16, 4, 0};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Define servo
Servo doorLock;
// GPIO pins for LEDs and buzzer
const int greenLED = 26;
const int redLED = 27;
const int buzzer = 25;
// PIN and state variables
String correctPIN = "1234";
String enteredPIN = "";
bool doorUnlocked = false;
unsigned long lockTimeout = 5000; // 5 seconds
unsigned long unlockTime;
// Wi-Fi and MQTT clients
WiFiClient espClient;
PubSubClient client(espClient);
// Function prototypes
void reconnect();
void unlockDoor();
void lockDoor();
void incorrectPIN();
void playHarmony();
void playEvilTone();
void setup() {
// Initialize servo
doorLock.attach(23); // Servo connected to GPIO 23
lockDoor();
// Initialize LEDs and buzzer
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(buzzer, OUTPUT);
// Start serial communication
Serial.begin(115200);
// Connect to Wi-Fi
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\nWi-Fi Connected!");
// Setup MQTT
client.setServer(mqtt_server, mqtt_port);
}
void loop() {
// Ensure MQTT connection
if (!client.connected()) {
reconnect();
}
client.loop();
// Handle keypad input
char key = keypad.getKey();
if (key) {
Serial.println(key);
if (key == '#') {
// Submit the PIN
if (enteredPIN == correctPIN) {
unlockDoor(); // Unlock the door if the PIN is correct
unlockTime = millis();
client.publish(mqtt_topic, "Door Unlocked");
} else {
incorrectPIN(); // Trigger alarm if the PIN is incorrect
client.publish(mqtt_topic, "Incorrect PIN");
}
enteredPIN = ""; // Reset the entered PIN
} else if (key == '*') {
// Clear the entered PIN
enteredPIN = "";
Serial.println("PIN cleared");
} else {
// Append the pressed key to the entered PIN
enteredPIN += key;
}
}
// Auto-lock the door after timeout
if (doorUnlocked && (millis() - unlockTime > lockTimeout)) {
lockDoor();
client.publish(mqtt_topic, "Door Locked");
}
}
void reconnect() {
// Attempt to reconnect to MQTT
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("ESP32Client")) {
Serial.println("connected");
client.publish(mqtt_topic, "Device Connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void unlockDoor() {
Serial.println("Door Unlocked!");
doorLock.write(90); // Rotate servo to unlock position
digitalWrite(greenLED, HIGH); // Turn on green LED
digitalWrite(redLED, LOW); // Turn off red LED
playHarmony(); // Play harmony sound for correct PIN
doorUnlocked = true;
}
void lockDoor() {
Serial.println("Door Locked!");
doorLock.write(0); // Rotate servo to lock position
digitalWrite(greenLED, LOW); // Turn off green LED
digitalWrite(redLED, HIGH); // Turn on red LED
doorUnlocked = false;
}
void incorrectPIN() {
Serial.println("Incorrect PIN!");
digitalWrite(redLED, HIGH);
playEvilTone();
delay(2000);
digitalWrite(redLED, LOW);
}
void playHarmony() {
tone(buzzer, 523, 300);
delay(300);
tone(buzzer, 659, 300);
delay(300);
tone(buzzer, 784, 300);
delay(300);
noTone(buzzer);
}
void playEvilTone() {
tone(buzzer, 300, 500);
delay(500);
tone(buzzer, 250, 500);
delay(500);
tone(buzzer, 200, 500);
delay(500);
noTone(buzzer);
}