#include <Keypad.h>
#include <Wire.h>
#include <ESP32Servo.h>
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ThingSpeak.h>
// Pin definitions for the components
#define SERVO_PIN 5
#define BUZZER_PIN 15
#define RED_LED_PIN 27
#define GREEN_LED_PIN 26
#define BLUE_LED_PIN 25
// Wi-Fi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* thingSpeakUrl = "https://api.thingspeak.com/update?api_key=XL3RF6SCTRQK7RSM";
// Door code
const String doorCode = "1234"; // Mã khóa cửa (bạn có thể thay đổi theo nhu cầu)
const int MAX_ATTEMPTS = 3; // So lan sai mat khau toi da
String enteredCode = ""; // Ma khoa nhap vao
int attemptCount = 0; // Dem so lan nhap sai code
int usageCount = 0; // So lan su dung he thong (hay so lan mo cua thanh cong)
unsigned long doorOpenTime = 0; // Thoi gian mo cua
// Door control state
bool doorStatus = false; // false = closed, true = open
// LCD setup
LiquidCrystal_I2C lcd(0x27, 16, 2); // Address 0x27, 16 columns and 2 rows
// Servo setup
Servo myServo;
// Keypad setup (4x4 matrix)
const byte ROWS = 4;
const byte COLUMNS = 4;
char keys[ROWS][COLUMNS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte pin_rows[ROWS] = {2, 0, 4, 16};
byte pin_column[COLUMNS] = {17, 18, 19, 23};
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROWS, COLUMNS);
void setRGBColor(int r, int g, int b) {
// digitalWrite(RED_LED_PIN, r > 0 ? HIGH : LOW);
// digitalWrite(GREEN_LED_PIN, g > 0 ? HIGH : LOW);
// digitalWrite(BLUE_LED_PIN, b > 0 ? HIGH : LOW);
analogWrite(RED_LED_PIN, r);
analogWrite(GREEN_LED_PIN, g);
analogWrite(BLUE_LED_PIN, b);
}
void buzz(int times) {
for (int i = 0; i < times; i++) {
tone(BUZZER_PIN, 1000);
delay(200);
noTone(BUZZER_PIN);
delay(200);
}
}
void displayMessage(const String& line1, const String& line2 = "") {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(line1);
if (!line2.isEmpty()) {
lcd.setCursor(0, 1);
lcd.print(line2);
}
}
void sendDataToThingSpeak(int doorStatus, int wifiStatus, int usageCount, int attemptCount, const String& passcode) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = String(thingSpeakUrl)
+ "&field1=" + String(doorStatus)
+ "&field2=" + String(millis() - doorOpenTime)
+ "&field3=" + String(wifiStatus)
+ "&field4=" + String(attemptCount)
+ "&field5=" + String(usageCount)
+ "&field6=" + passcode;
http.begin(url);
int httpCode = http.GET(); // Make HTTP GET request
if (httpCode > 0) {
Serial.println("Data sent successfully!");
} else {
Serial.println("Error sending data");
}
http.end();
}
}
void lockDoor() {
myServo.write(0);
setRGBColor(255, 0, 0);
doorStatus = false;
displayMessage("Door Closed");
delay(500);
}
void unlockDoor() {
myServo.write(90);
delay(1000);
setRGBColor(0, 255, 0);
doorStatus = true;
doorOpenTime = millis();
}
void processCorrectPassword() {
attemptCount = 0;
usageCount++;
unlockDoor();
displayMessage("Door Opened");
buzz(1);
Serial.println("Open Door");
sendDataToThingSpeak(1, WiFi.status() == WL_CONNECTED ? 1 : 0, usageCount, attemptCount, enteredCode);
delay(5000);
lockDoor();
Serial.println("Close Door");
displayMessage("Enter Passcode:");
}
void processIncorrectPassword() {
attemptCount++;
setRGBColor(255, 255, 0);
displayMessage("Incorrect Code");
buzz(2);
Serial.println("Invalid PIN Code");
sendDataToThingSpeak(0, WiFi.status() == WL_CONNECTED ? 1 : 0, usageCount, attemptCount, enteredCode);
if (attemptCount >= MAX_ATTEMPTS) {
lockDoor();
buzz(3);
displayMessage("Door Closed");
setRGBColor(255, 0, 0);
attemptCount = 0;
}
delay(2000);
setRGBColor(255, 255, 255);
displayMessage("Enter Passcode:");
}
// Setup function
void setup() {
// Init Serial
Serial.begin(115200);
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.print("Connecting...");
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi...");
}
displayMessage("Wifi Connected");
delay(2000);
Serial.println("Connected to WiFi");
displayMessage("Enter Passcode:");
// Setup servo
myServo.attach(SERVO_PIN);
myServo.write(0);
delay(1000);
Serial.println("Servo in lock status");
// Setup LEDs
pinMode(RED_LED_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(BLUE_LED_PIN, OUTPUT);
setRGBColor(255, 0, 0);
delay(200);
buzz(1);
setRGBColor(255, 255, 255);
delay(200);
displayMessage("Enter Passcode:");
}
// Main loop
void loop() {
char key = keypad.getKey();
if (key) {
if (key == '#') {
if (enteredCode == doorCode) {
processCorrectPassword();
setRGBColor(255, 255, 255);
} else {
processIncorrectPassword();
}
enteredCode = "";
} else if (key == '*') {
enteredCode = "";
displayMessage("Enter Passcode:");
} else {
enteredCode += key;
displayMessage("Enter Passcode:", enteredCode);
}
}
}