from machine import Pin, PWM, I2C
from time import sleep
from i2c_lcd import I2cLcd
from keypad import Keypad
# GPIO Pin Definitions
SERVO_PIN = 23
RED_LED_PIN = 16
GREEN_LED_PIN = 17
BLUE_LED_PIN = 19
BUZZER_PIN = 2 # Make sure this pin matches your Wokwi wiring
PIR_PIN = 18
PUSHBUTTON_PIN = 4
I2C_SDA = 21
I2C_SCL = 22
# Setup LEDs, PIR Sensor, and Pushbutton
red_led = Pin(RED_LED_PIN, Pin.OUT)
green_led = Pin(GREEN_LED_PIN, Pin.OUT)
blue_led = Pin(BLUE_LED_PIN, Pin.OUT)
pir = Pin(PIR_PIN, Pin.IN)
pushbutton = Pin(PUSHBUTTON_PIN, Pin.IN, Pin.PULL_UP) # Ensure internal pull-up is enabled
# Setup PWM Buzzer
buzzer = PWM(Pin(BUZZER_PIN))
buzzer.freq(3000) # High-pitch sound (3kHz)
buzzer.duty(0) # Start with buzzer OFF
# Setup Servo Motor
servo = PWM(Pin(SERVO_PIN), freq=50)
def set_servo(angle):
duty = int((angle / 180) * 102 + 26)
servo.duty(duty)
# Setup LCD 20x4 (I2C)
i2c = I2C(0, scl=Pin(I2C_SCL), sda=Pin(I2C_SDA), freq=400000)
lcd = I2cLcd(i2c, 0x27, 4, 20)
lcd.clear()
# Setup Keypad (4x4 Matrix)
ROWS = [13, 12, 14, 27]
COLS = [26, 25, 33, 32]
keys = [['1', '2', '3', 'A'],
['4', '5', '6', 'B'],
['7', '8', '9', 'C'],
['*', '0', '#', 'D']]
keypad = Keypad(ROWS, COLS, keys)
# Passcode settings
correct_passcode = "1234"
input_code = ""
is_unlocked = False
# Initialize Servo in Lock Position
set_servo(0)
# State to track if pushbutton was pressed once
button_pressed_once = False
def unlock_door():
global is_unlocked
lcd.clear()
lcd.putstr("HI WELCOME, COME IN")
red_led.off() # Red OFF
green_led.on() # Green ON (Unlocked)
set_servo(90) # Unlock position
is_unlocked = True
sleep(2)
lcd.clear()
def lock_door():
global is_unlocked
lcd.clear()
lcd.putstr("Door Locked")
green_led.off() # Green OFF
red_led.on() # Red ON (Locked)
set_servo(0) # Lock position
is_unlocked = False
sleep(2)
lcd.clear()
def wrong_passcode():
lcd.clear()
lcd.putstr("WRONG PASSWORD! TRY AGAIN")
buzzer.duty(1023) # Loudest sound
sleep(1)
buzzer.duty(0)
lcd.clear()
# Interrupt for PIR Sensor
def motion_detected(pin):
lcd.clear()
lcd.putstr("SOMEONE IS HERE")
buzzer.duty(1023) # Loudest sound
blue_led.on()
sleep(2)
buzzer.duty(0)
blue_led.off()
lcd.clear()
# Pushbutton press handler (interrupt)
def pushbutton_pressed(pin):
global is_unlocked, button_pressed_once
print("Pushbutton pressed!") # Debugging line
if not button_pressed_once:
if is_unlocked:
lock_door() # Lock the door after unlocking
else:
unlock_door() # Unlock the door
# Automatically lock the door after a delay
sleep(2) # Wait for 5 seconds
lock_door() # Lock the door
button_pressed_once = True # Mark that the button has been pressed once
# Attach IRQ (interrupts)
pir.irq(trigger=Pin.IRQ_RISING, handler=motion_detected)
pushbutton.irq(trigger=Pin.IRQ_FALLING, handler=pushbutton_pressed) # Pushbutton trigger on falling edge
def warning_beep():
buzzer.freq(3000) # High-pitch 3kHz
buzzer.duty(1023) # Loudest volume
sleep(10) # Keep buzzing for 10 seconds
buzzer.duty(0) # Turn off buzzer
# Main loop for Keypad and Pushbutton checking
while True:
# Check if any key is pressed from keypad
key = keypad.get_key()
if key:
lcd.clear()
lcd.putstr("Enter Code:")
lcd.move_to(0, 1)
input_code += key
lcd.putstr(input_code)
if len(input_code) == 4:
if input_code == correct_passcode:
unlock_door()
else:
wrong_passcode()
input_code = ""
# Auto-lock after timeout
if is_unlocked:
sleep(10)
lcd.clear()
lcd.putstr("Warning!!! Door Open")
warning_beep() # Call buzzer warning function
lock_door()