#include <Keypad.h>
#include <Servo.h>

// Define the keypad matrix size and keys
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'}
};

// Define the pins connected to the keypad
byte rowPins[ROWS] = {6,7,8,9}; 
byte colPins[COLS] = {2,3,4,5}; 

// Create the Keypad object
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

// Define the servo motor pin
#define SERVO_PIN 10

// Define the angles for the locked and unlocked positions of the servo
#define LOCKED_ANGLE 0
#define UNLOCKED_ANGLE 90

// Create the Servo object
Servo servoMotor;

// Define a variable to store the password
const String correctPassword = "1234";

void setup() {
  // Start serial communication
  Serial.begin(9600);

  // Attach the servo to its pin
  servoMotor.attach(SERVO_PIN);

  // Initialize the servo to the locked position
  servoMotor.write(LOCKED_ANGLE);
}

void loop() {
  // Wait for a keypress
  char key = keypad.getKey();
  
  // If a key is pressed, check if it's the correct password
  if (key) {
    if (key == '#') {
      // Attempt to unlock the door
      unlockDoor();
    } else {
      // Add the pressed key to the entered password
      checkPassword(key);
    }
  }
}

// Function to check the entered password
void checkPassword(char key) {
  static String enteredPassword = "";
  
  // Add the pressed key to the entered password
  enteredPassword += key;
  
  // If the entered password is the correct password, unlock the door
  if (enteredPassword == correctPassword) {
    unlockDoor();
  } else if (enteredPassword.length() >= correctPassword.length()) {
    // If the entered password is incorrect, reset the entered password
    enteredPassword = "";
    Serial.println("Incorrect password!");
  }
}

// Function to unlock the door
void unlockDoor() {
  // Move the servo to the unlocked position
  servoMotor.write(UNLOCKED_ANGLE);
  Serial.println("Door unlocked!");
  delay(2000); // Delay for stability
  // Move the servo back to the locked position after a delay
  servoMotor.write(LOCKED_ANGLE);
  Serial.println("Door locked!");
}