# main.py
from machine import Pin, I2C, PWM
from time import time, sleep
from ssd1306 import SSD1306_I2C
from keypad import Keypad
# ------------ CONFIG ------------
SECRET_CODE = "21906285"
BUFFER_LEN = 8
# Keypad pins
row_pins = (Pin(9), Pin(8), Pin(7), Pin(6))
col_pins = (Pin(5), Pin(4), Pin(3), Pin(2))
# OLED I2C
i2c = I2C(1, scl=Pin(27), sda=Pin(26))
oled = SSD1306_I2C(128, 64, i2c)
# Servo
servo = PWM(Pin(16))
servo.freq(50)
# LED
led = Pin(25, Pin.OUT)
# ------------ STATE ------------
isLocked = True # 默认锁定
inbuffer = "-" * BUFFER_LEN
attempts = 0
lockout_until = 0 # 防暴力破解冷却时间
# ------------ Functions ------------
def servo_set_angle(angle):
us = 500 + int((angle / 180) * 2000)
duty = int(65535 * (us / 20000))
servo.duty_u16(duty)
def lock_action():
servo_set_angle(0)
print("LOCK STATE → LOCKED") # 打印到控制台
def unlock_action():
servo_set_angle(110)
print("LOCK STATE → UNLOCKED") # 打印到控制台
def oled_refresh():
oled.fill(0)
oled.text("Combo Lock", 0, 0)
oled.text("State: " + ("LOCKED" if isLocked else "UNLOCKED"), 0, 12)
oled.text("Input:", 0, 28)
oled.text(inbuffer, 0, 40) # 显示真实数字
oled.text("Attempts:" + str(attempts), 0, 52)
oled.show()
def keyPressed(k):
global isLocked, inbuffer, attempts, lockout_until
now = time()
if now < lockout_until:
return
# 解锁状态按 * → 锁上
if not isLocked and k == "*":
isLocked = True
inbuffer = "-" * BUFFER_LEN
lock_action()
oled_refresh()
return
# 锁定状态→处理输入
if isLocked:
if k == "#": # 检查密码
if inbuffer == SECRET_CODE:
isLocked = False
attempts = 0
unlock_action()
oled_refresh()
else:
attempts += 1
inbuffer = "-" * BUFFER_LEN
oled_refresh()
if attempts >= 3:
lockout_until = now + 30
for _ in range(3):
led.on(); sleep(0.1)
led.off(); sleep(0.1)
else:
inbuffer = inbuffer[1:] + k
oled_refresh()
else:
pass
# 初始化 keypad
kp = Keypad(rows=row_pins, columns=col_pins, callback=keyPressed)
# 上电执行锁定动作
lock_action()
oled_refresh()
# ------------ Main Loop ------------
while True:
led.value(0 if isLocked else 1)
sleep(0.5)