from keypad import Keypad
from machine import Pin, PWM
from time import sleep
# Define the secret code and initial state
secretCode = '23689351'
isLocked = True # Start in the LOCKED state
inbuffer = "--------"
print("State = LOCKED") # Initial state
# Servo setup on GPIO 27
servo_pin = Pin(27) # GPIO 27 for servo control
pwm = PWM(servo_pin)
pwm.freq(50) # Standard servo frequency: 50 Hz
# LED setup
locked_led = Pin(5, Pin.OUT) # GPIO 5 for LOCKED state LED
unlocked_led = Pin(6, Pin.OUT) # GPIO 6 for UNLOCKED state LED
# LCD setup (Manual control)
lcd_rs = Pin(12, Pin.OUT)
lcd_enable = Pin(11, Pin.OUT)
lcd_d4 = Pin(10, Pin.OUT)
lcd_d5 = Pin(9, Pin.OUT)
lcd_d6 = Pin(8, Pin.OUT)
lcd_d7 = Pin(7, Pin.OUT)
# Helper function to send a nibble to the LCD
def lcd_send_nibble(nibble):
lcd_d4.value((nibble >> 0) & 1)
lcd_d5.value((nibble >> 1) & 1)
lcd_d6.value((nibble >> 2) & 1)
lcd_d7.value((nibble >> 3) & 1)
lcd_enable.on()
sleep(0.001)
lcd_enable.off()
# Helper function to send a byte to the LCD
def lcd_send_byte(byte, is_data):
lcd_rs.value(is_data)
lcd_send_nibble(byte >> 4) # High nibble
lcd_send_nibble(byte & 0x0F) # Low nibble
sleep(0.002)
# set up the LCD
def lcd_init():
sleep(0.02)
lcd_send_nibble(0x03)
sleep(0.005)
lcd_send_nibble(0x03)
sleep(0.005)
lcd_send_nibble(0x03)
lcd_send_nibble(0x02) # Set to 4-bit mode
lcd_send_byte(0x28, False)
lcd_send_byte(0x0C, False)
lcd_send_byte(0x01, False) # clears the display
sleep(0.002)
lcd_send_byte(0x06, False)
# Write a string to the LCD
def lcd_write(text, line):
line_addresses = [0x00, 0x40]
lcd_send_byte(0x80 | line_addresses[line], False) # Set cursor position
for char in text:
lcd_send_byte(ord(char), True)
# locked seevo angle
def set_servo_angle(angle):
# Change servo angle to show its unlcoked
duty_u16 = int((1600 + (angle / 180) * 6450))
pwm.duty_u16(duty_u16)
# shows LEDs are based of the displaying of the locked/unlcoked messgae
def update_status():
if isLocked:
locked_led.on() # Turn on LOCKED LED
unlocked_led.off() # Turn off UNLOCKED LED
lcd_write("State: LOCKED", 0)
else:
locked_led.off() # Turn off LOCKED LED
unlocked_led.on() # Turn on UNLOCKED LED
lcd_write("State: UNLOCKED", 0)
# Start with servo at 0 degrees (locked state) and update status
lcd_init()
set_servo_angle(0)
update_status()
# Callback function to handle key presses
def keyPressed(keyValue):
global isLocked, inbuffer
if isLocked:
if keyValue == '#': # User confirms code entry
if inbuffer == secretCode: # If the entered code matches
isLocked = False
set_servo_angle(90) # Unlock: Move servo to 90 degrees
print(" - Correct, State = UNLOCKED")
update_status() # Update status (LEDs and LCD)
else:
print(" - Incorrect code.")
inbuffer = "--------" # Reset the buffer after each attempt
else: # Add the new digit to the buffer
inbuffer = inbuffer[1:] + keyValue
print(keyValue, end="")
elif keyValue == '*': # Lock the padlock
isLocked = True
set_servo_angle(0) # Lock: Move servo to 0 degrees
print("State = LOCKED")
update_status() # Update status (LEDs and LCD)
# Setup the keypad object with the correct pins and callback
kp = Keypad(rows=(Pin(26), Pin(22), Pin(21), Pin(20)),
columns=(Pin(19), Pin(18), Pin(17), Pin(16)),
callback=keyPressed)