from machine import Pin,PWM,I2C
import time
from pico_i2c_lcd import I2cLcd

I2C_ADDR  = 39
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16

i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=100000)
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)
lcd.move_to(3,0)
lcd.putstr("Enter PIN:")


servo = PWM(Pin(28))
servo.freq(50)
def set_angle(angle):
  # Convert angle (0-180) to duty cycle (typically 1000-9000 for Pico)
    min_duty = 1638
    max_duty = 8192
    duty = int(min_duty + (angle / 180) * (max_duty - min_duty))
    servo.duty_u16(duty)

matrix_keys = [['1', '2', '3', 'A'],
               ['4', '5', '6', 'B'],
               ['7', '8', '9', 'C'],
               ['*', '0', '#', 'D']]

keypad_rows = [27, 26, 22, 21]
keypad_columns = [20, 19, 18, 17]

col_pins = [Pin(col, Pin.IN, Pin.PULL_DOWN) for col in keypad_columns]
row_pins = [Pin(row, Pin.OUT) for row in keypad_rows]

# User input and secret PIN
guess = []
secret_pin = ['1', '2', '3', '4', '5', '6']
lock=['6','5','4','3','2','1']

# LED feedback
buzz = Pin(2, Pin.OUT)
buzz.value(0)

def scankeys():
    for row in range(4):
        row_pins[row].high()
        for col in range(4):
            if col_pins[col].value() == 1:
                key_press = matrix_keys[row][col]
                guess.append(key_press)

                # Display * starting at (5, 1)
                lcd.move_to(5 + len(guess) - 1, 1)
                lcd.putstr("*")

                # Wait for key release to avoid multiple detections
                while col_pins[col].value() == 1:
                    time.sleep(0.01)
                time.sleep(0.1)  # debounce delay

                if len(guess) == len(secret_pin):
                    checkPin(guess)
                    guess.clear()
                    lcd.move_to(0, 1)
                    lcd.putstr(" " * I2C_NUM_COLS)  # Clear line
                    lcd.move_to(3, 0)
                    lcd.putstr("Enter PIN:")
        row_pins[row].low()


def checkPin(guess):
    if guess == secret_pin:
        lcd.move_to(1, 1)  # Move to the second row
        lcd.putstr("Access Granted")  # Display "Access Granted"
        set_angle(0)
        time.sleep(2)  # Display for 2 seconds
        lcd.move_to(0, 1)  # Move back to the second row
        lcd.putstr("                ")  # Clear the row
        lcd.move_to(3, 0)
        lcd.putstr("Enter PIN:")  # Reset the prompt
    elif guess == lock:
        lcd.move_to(4, 1)  # Move to the second row
        lcd.putstr("Locking")  # Display "Access Granted"
        set_angle(90)
        time.sleep(2)  # Display for 2 seconds
        lcd.move_to(0, 1)  # Move back to the second row
        lcd.putstr("                ")  # Clear the row
        lcd.move_to(3, 0)
        lcd.putstr("Enter PIN:")  # Reset the prompt 
    else:
        buzz.on()
        time.sleep(0.5)
        buzz.off()
        time.sleep(0.5)
        buzz.on()
        time.sleep(0.5)
        buzz.off


# Main loop to continuously scan
while True:
    scankeys()
    time.sleep(0.05)
    
    
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT