import machine
import time
from machine import Pin, I2C, PWM
from lcd_api import LcdApi
from pico_i2c_lcd import I2cLcd
# --- CONFIGURACIÓN DE PINES ---
# LEDs
led_verde = Pin(14, Pin.OUT)
led_rojo = Pin(15, Pin.OUT)
# Servomotor (Configurado en el Pin 16)
pin_servo = Pin(16)
servo = PWM(pin_servo)
servo.freq(50) # Los servos estándar funcionan a 50Hz
# Pantalla LCD 16x2 I2C
I2C_ADDR = 0x27
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, 2, 16)
# Teclado Matricial 4x4
filas_pines = [2, 3, 4, 5]
columnas_pines = [6, 7, 8, 9]
filas = [Pin(pin, Pin.OUT) for pin in filas_pines]
columnas = [Pin(pin, Pin.IN, Pin.PULL_DOWN) for pin in columnas_pines]
teclas = [
['1', '2', '3', 'A'],
['4', '5', '6', 'B'],
['7', '8', '9', 'C'],
['*', '0', '#', 'D']
]
# --- VARIABLES DEL SISTEMA ---
CLAVE_CORRECTA = "#*B1" # Contraseña con caracteres especiales admitidos
clave_usuario = ""
# --- FUNCIONES ---
def mover_servo(angulo):
"""Mueve el servo a un ángulo entre 0 y 180 grados."""
# Mapea el ángulo (0 a 180) al duty cycle de MicroPython (entre 2000 y 8000)
duty = int(2000 + (angulo / 180) * 6000)
servo.duty_u16(duty)
def leer_teclado():
"""Escanea el teclado matricial y devuelve la tecla presionada o None."""
for i in range(4):
filas[i].value(1)
for j in range(4):
if columnas[j].value() == 1:
while columnas[j].value() == 1:
time.sleep(0.05)
filas[i].value(0)
return teclas[i][j]
filas[i].value(0)
return None
def reiniciar_interfaz():
"""Vuelve al estado inicial pidiendo la clave y asegura el servo en 0 grados."""
global clave_usuario
clave_usuario = ""
led_verde.value(0)
led_rojo.value(0)
mover_servo(0) # Regresa el servo a la posición base (0 grados)
lcd.clear()
lcd.putstr("INGRESAR CLAVE:\n")
# --- BUCLE PRINCIPAL ---
# Inicialización del sistema
reiniciar_interfaz()
while True:
tecla = leer_teclado()
if tecla is not None:
# Acepta cualquier tecla para la clave
if len(clave_usuario) < 4:
clave_usuario += tecla
lcd.move_to(len(clave_usuario) - 1, 1)
lcd.putstr("*")
# Cuando se completan los 4 caracteres, se verifica automáticamente
if len(clave_usuario) == 4:
time.sleep(0.3)
lcd.clear()
if clave_usuario == CLAVE_CORRECTA:
lcd.putstr("Clave Correcta\nPuerta Abierta")
led_verde.value(1)
mover_servo(120) # <<--- GIRA A 120 GRADOS CUANDO ES CORRECTA
time.sleep(3) # Mantiene la posición por 3 segundos
else:
lcd.putstr("Clave Incorrecta")
led_rojo.value(1)
mover_servo(45) # <<--- GIRA A 45 GRADOS CUANDO ES INCORRECTA
time.sleep(3) # Mantiene la posición de error por 3 segundos
# Restablece el servo a 0 grados, apaga LEDs y limpia pantalla
reiniciar_interfaz()
time.sleep(0.1)