#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <esp32-hal-ledc.h>
#include <ESP32Servo.h>
#include <Wire.h>
// LCD setup
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adjust the I2C address if needed
// Servo setup
Servo myServo;
const int servoPin = 2; // Replace with the appropriate servo pin
// LED pins
const int ledRed = 14; // Pin connected to the red LED
const int ledGreen = 27; // Pin connected to the green LED
// Keypad setup
const byte ROW_NUM = 4; // four rows
const byte COLUMN_NUM = 4; // four columns
char keys[ROW_NUM][COLUMN_NUM] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte pinRows[ROW_NUM] = {26, 25, 33, 32}; // Connect to the row pinouts of the keypad
byte pinColumns[COLUMN_NUM] = {23, 22, 21, 19}; // Connect to the column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), pinRows, pinColumns, ROW_NUM, COLUMN_NUM);
// Variables for OTP
char generatedOTP[5];
char inputPIN[5];
int inputIndex = 0;
void setup() {
Serial.begin(115200);
Wire.begin(21, 22);
// Initialize the LCD
lcd.init(); // Initialize the LCD for I2C
lcd.backlight(); // Turn on the backlight
lcd.print("Generating OTP");
// Initialize LEDs
pinMode(ledRed, OUTPUT);
pinMode(ledGreen, OUTPUT);
myServo.attach(servoPin); // Attach the servo to the pin
myServo.write(0); // Initial position (locked)
// Initialize Servo
delay(2000);
generateOTP(); // Generate OTP when the system starts
lcd.clear();
lcd.print("Enter OTP:");
}
void generateOTP() {
int otp = random(1000, 9999); // Generate a 4-digit OTP
snprintf(generatedOTP, 5, "%04d", otp); // Store OTP as a string
// Print the generated OTP to the Serial monitor
Serial.print("Generated OTP: ");
Serial.println(generatedOTP);
lcd.clear();
lcd.print("OTP Generated"); // Display OTP generated message
delay(1000); // Show message for 1 second
lcd.clear();
lcd.print("Enter OTP:");
}
void loop() {
char key = keypad.getKey();
if (key) {
lcd.setCursor(inputIndex, 1); // Move cursor to the correct position on second line
lcd.print(key); // Display the pressed key
if (key == '#') { // '#' is the enter key
if (inputIndex == 4) { // Only check if 4 digits have been entered
inputPIN[4] = '\0'; // Null-terminate the string
if (strcmp(inputPIN, generatedOTP) == 0) {
unlockDoor();
} else {
lcd.clear();
lcd.print("Wrong PIN!");
digitalWrite(ledRed, HIGH);
delay(2000);
digitalWrite(ledRed, LOW);
}
inputIndex = 0; // Reset input index
lcd.clear();
lcd.print("Enter OTP:");
}
} else if (key == '*') { // '*' to clear input
inputIndex = 0;
lcd.clear();
lcd.print("Enter OTP:");
} else {
if (inputIndex < 4) { // Only allow up to 4 characters
inputPIN[inputIndex] = key;
inputIndex++;
}
}
}
}
void unlockDoor() {
digitalWrite(ledGreen, HIGH);
myServo.write(90);
Serial.println("Servo position: " + String(myServo.read())); // Open the lock (adjust angle as needed)
lcd.clear();
lcd.print("Unlocked!");
Serial.println("Door unlocked!"); // Debug message
delay(15000); // Keep it unlocked for 5 seconds
myServo.write(0); // Lock again
digitalWrite(ledGreen, LOW);
lcd.clear();
lcd.print("Locked");
Serial.println("Door locked!"); // Debug message
delay(1000);
generateOTP(); // Generate a new OTP after locking
}