from machine import I2C, Pin
from ssd1306 import SSD1306_I2C
from utime import sleep
# 设置GPIO与键盘引脚
row_list = [15, 14, 13, 12] # R系接口 - 连接到矩阵键盘的行线
col_list = [5, 4, 3, 2] # C系接口 - 连接到矩阵键盘的列线
# 初始化键盘引脚 - 行线设为输出模式,列线设为输入模式并启用上拉电阻
R = [Pin(i, Pin.OUT) for i in row_list] # R为输出
C = [Pin(i, Pin.IN, Pin.PULL_UP) for i in col_list] # C为输入
# 键盘映射表 - 定义每个按键对应的字符
key_map = [['1','2','3','A'],
['4','5','6','B'],
['7','8','9','C'],
['*','0','#','D']]
# 设置LED指示灯 - 锁定和解锁状态的LED
led_lock = Pin(25, Pin.OUT) # 锁定状态LED - 亮起表示系统已锁定
led_unlock = Pin(26, Pin.OUT) # 解锁状态LED - 亮起表示系统已解锁
# 初始化I2C和OLED显示屏
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=200000)
oled = SSD1306_I2C(128, 64, i2c)
# 系统配置
CORRECT_PASSWORD = "1234" # 固定密码 - 系统预设的解锁密码
lock_status = True # 初始锁定状态 - 系统启动时默认为锁定状态
# 初始化显示和LED状态
def init_system():
oled.fill(0) # 清屏
oled.text("Electronic Lock", 0, 0) # 显示标题
oled.text("look on", 0, 32) # 锁定时显示"look on"
oled.show() # 更新OLED显示
led_lock.value(1) # 锁定LED亮
led_unlock.value(0) # 解锁LED灭
# 键盘读取函数 - 扫描矩阵键盘并检测按键输入
def keypad_read(rows, cols):
key = None
# 逐行扫描键盘
for i in range(len(rows)):
rows[i].value(0) # 将当前行设为低电平
result = [c.value() for c in cols] # 读取所有列的状态
# 如果某列被拉低,说明该行该列的按键被按下
if 0 in result:
pressed_btn = cols[int(result.index(0))]
# 进行消抖处理,确认按键确实被按下
if pressed_btn.value() == 0 and debounce(pressed_btn):
# 根据行列索引查找对应的按键字符
key = key_map[i][int(result.index(0))]
rows[i].value(1) # 恢复当前行的高电平
return key
rows[i].value(1) # 恢复当前行的高电平
return None
# 按钮消抖函数 - 防止按键抖动导致的误触发
def debounce(button):
reading = button.value() # 读取当前按键状态
sleep(0.02) # 短暂延时(20ms)以过滤抖动
return reading == button.value() # 确认两次读取的状态一致
# 更新显示状态 - 在OLED上显示指定的消息
def update_display(message):
oled.fill(0) # 清屏
oled.text("Electronic Lock", 0, 0) # 显示标题
oled.text(message, 0, 32) # 显示指定消息
oled.show() # 更新OLED显示
# 验证密码 - 检查输入的密码是否正确
def verify_password(input_password):
return input_password == CORRECT_PASSWORD # 比较输入密码与预设密码
# 锁定系统 - 将系统切换到锁定状态
def lock_system():
global lock_status
lock_status = True # 更新锁定状态标志
led_lock.value(1) # 锁定LED亮
led_unlock.value(0) # 解锁LED灭
update_display("look on") # 锁定时显示"look on"
sleep(1) # 延时1秒
# 解锁系统 - 将系统切换到解锁状态
def unlock_system():
global lock_status
lock_status = False # 更新锁定状态标志
led_lock.value(0) # 锁定LED灭
led_unlock.value(1) # 解锁LED亮
update_display("look off") # 解锁时显示"look off"
sleep(1) # 延时1秒
# 主程序 - 系统的核心控制逻辑
def main():
init_system() # 初始化系统
password_input = "" # 存储用户输入的密码
# 主循环 - 持续运行系统
while True:
key = keypad_read(R, C) # 读取键盘输入
# 处理按键输入
if key:
# 锁定状态下处理密码输入
if lock_status:
# 数字键输入密码
if key in "0123456789":
password_input += key # 添加输入的数字到密码
# 显示星号代替实际密码,保护密码安全
update_display("*" * len(password_input))
# 清除键 (*)
elif key == "*":
password_input = "" # 清空已输入的密码
update_display("") # 清屏
# 确认键 (#)
elif key == "#":
if password_input: # 确保有输入密码
if verify_password(password_input): # 验证密码
unlock_system() # 密码正确,解锁系统
password_input = "" # 清空密码输入
else:
update_display("Wrong!") # 密码错误提示
sleep(1) # 延时1秒
password_input = "" # 清空密码输入
update_display("look on") # 恢复锁定状态显示
# 解锁状态下处理菜单选择
else:
# 锁定系统 (D键)
if key == "D":
lock_system() # 锁定系统
password_input = "" # 清空密码输入
sleep(0.05) # 短暂延时,减少CPU占用
# 程序入口点
if __name__ == "__main__":
try:
main() # 启动主程序
except KeyboardInterrupt:
# 处理Ctrl+C中断,优雅退出
oled.fill(0) # 清屏
oled.text("Program Stopped", 0, 20) # 显示停止信息
oled.show() # 更新OLED显示
led_lock.value(0) # 关闭锁定LED
led_unlock.value(0) # 关闭解锁LED