ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

零知ESP32--4×4 矩阵键盘智能密码锁

零知ESP32--4×4 矩阵键盘智能密码锁 项目概述本项目是一套基于 ESP32 的双通道智能密码锁门锁侧用 4×4 矩阵键盘本地输入密码手机侧通过低功耗蓝牙BLE远程开锁。锁舌由 SG90 舵机带动ST7789 彩屏显示中文状态无源蜂鸣器给出按键与结果提示。固件以有限状态机组织界面与业务上电欢迎 → 锁定待机 → 输密 / 改密 / 菜单 / 记录 / 访客 → 开锁成功与自动上锁 → 防暴力破解锁定。主密码与开锁记录写入 ESP32 片内 NVSFlash断电后仍保留。手机可用浏览器打开tools/ble_test.html或按docs/app-inventor.md用 MIT App Inventor 自制 App。设备广播名为SmartLock。适用场景是课程设计与功能演示强调可复现的硬件、可拆分的代码和可操作的协议而不是商用级加密门锁。项目亮点双通道开锁本地键盘与 BLE 远程共用同一套校验与锁定策略访客另有 6 位一次性密码24 小时有效、用过即废。中文图形界面自生成 16×16 点阵字库FontCN.h锁屏、倒计时、菜单、记录、访客密码均在 240×240 屏上完成不必依赖串口。防暴力破解连续 5 次错误进入锁定初始 30 秒再次触发时间加倍最长 300 秒剩余次数与倒计时同步推到屏幕和手机。记录可追溯最近 64 条事件本地 / 远程 / 访客开锁、失败、上锁、生成访客密码环形写入 NVS屏幕分页浏览手机可拉取并导出 CSV。低功耗取向CPU 80 MHz、仅开 BLE、发射功率 −3 dBm、空闲约 20 秒关屏、舵机到位后断开 PWM适合演示供电。模块化固件键盘、蜂鸣器、舵机、安全、显示、蓝牙、日志各自独立头文件主文件只负责状态机与协议分发。手机友好协议16-bit UUIDFFF0/FFF1/FFF2命令为短 ASCII 文本兼顾网页 Web Bluetooth 与 App Inventor。项目难点及解决方案1. 输出脚选错导致舵机、蜂鸣器“完全没反应”ESP32 的 GPIO3439 只能输入不能输出 PWM。早期若接到 34/35现象是程序在跑、屏幕正常锁和声音却毫无动作。解决办法舵机固定 GPIO21、蜂鸣器 GPIO22并在config.h用编译期#error拦住再次误用。2. 键盘列脚与屏幕 SPI 冲突ST7789 走 VSPI时钟 18、MOSI 23。若键盘占用 GPIO19MISO或 GPIO5部分板卡默认 CS会出现花屏、键值乱跳或上电异常。列脚改到 27、14、16、17避开 VSPI 占用脚。3. ST7789 旋转后画面左移、右侧留白240×240 模组内部 CGRAM 往往带偏移。setRotation(4)时若colstart不对有效像素会偏出可视区。正确做法是在 TFT_eSPI 的ST7789_Rotation.h中240×240 的 rotation 4 分支设colstart 80; rowstart 0并开启CGRAM_OFFSET。该类库里colstart为私有成员无法用子类可靠改写必须改驱动头文件。4. 倒计时全屏重绘导致闪烁开锁 8 秒倒计时与锁定倒计时若每秒fillScreen闪烁明显。显示层增加脏标记界面切换全刷倒计时仅markPartial()只重画数字行。5. 屏幕没有现成中文字库TFT_eSPI 默认不含本项目文案。用tools/gen_font.py从黑体截取所需汉字生成FontCN.h点阵显示层按 UTF-8 查表绘制。6. BLE 回调与主循环并发手机写入发生在蓝牙协议栈任务中。用临界区把命令拷入缓冲主循环takeCommand()再处理避免在回调里驱动舵机、写 NVS、刷屏。7. 记录要断电仍在又没有 RTC事件以打包结构体环形存 NVS时间戳用累计秒开机后累加重启后接上次末条屏幕显示为MM:SS。这不是墙钟时间但能保证离线后再上电仍能翻看历史。一、硬件系统部分1.1 硬件清单序号名称规格 / 说明数量1零知ESP32 开发板3.3 V 逻辑需引出 5 V 给舵机12零知ESP32 扩展板有引出接口方便接线13ST7789 彩屏240×240SPIVCC 接 3.3 V144×4 矩阵键盘硬按键15SG90 舵机信号可接 3.3 V PWM电源必须 5 V16无源蜂鸣器默认固件BUZZER_PASSIVE1有源需改宏11.2 接线方案屏幕引脚写在 TFT_eSPI 的User_Setup中固件不再重复定义。其余外设集中在SmartLock/config.h。键盘、舵机、蜂鸣器键盘金属面朝下、按键朝操作者时排针从左到右一般为C1 C2 C3 C4 R1 R2 R3 R4。器件线序ESP32键盘行 R1R4行输出GPIO32、33、25、26键盘列 C1C4列上拉输入GPIO27、14、16、17SG90 橙 / 黄PWM 信号GPIO21SG90 红电源5 VSG90 棕地GND必须与 ESP32 共地蜂鸣器信号PWM / 电平GPIO22蜂鸣器地地GND接线要点舵机不要接 3.3 V电流不足会拖垮芯片表现为复位或舵机抽动。列线不要用 GPIO19、GPIO5避免与 VSPI 冲突。舵机、蜂鸣器不要用 GPIO3439。数字乱序时对调行/列线或改KeypadScan.h中的map表。1.3 硬件连接图数据流键盘 / BLE 产生“开锁或上锁”请求 → 主循环校验 → 舵机转到解锁角或锁定角 → 屏幕与蜂鸣器反馈 → 事件写入 NVS并经 BLE Notify 回传手机。1.4 实物连接图二、软件架构设计固件是单任务循环外加 BLE 协议栈任务。业务全部在loop()中串行执行模块之间通过对象方法交互不使用操作系统队列。手机 App / 网页 4×4 键盘 │ │ │ 写 FFF1 │ 行扫列读 ▼ ▼ BleLock::onWrite KeypadScan::read │ │ └────────┬────────────┘ ▼ SmartLock.ino 状态机 handleBleCommand / handleKey │ ┌───────────┼────────────┬─────────────┐ ▼ ▼ ▼ ▼ Security ServoLock Buzzer EventLog (NVS 密码) (LEDC PWM) (LEDC 音调) (NVS 环形) │ ▼ DisplayUI ← UiModel每圈填充按脏标记刷新核心状态Mode包括Splash、Locked、Input、Fail、Success、Unlocked、Lockout、改密三步、Info、Logs、GuestView、Notice。显示层用平行的UiScreen枚举由mapScreen()映射避免 UI 直接依赖业务枚举。2.1 系统初始化setup()按依赖顺序启动外设避免未初始化就刷屏或发蓝牙setCpuFrequencyMhz(80)降频减功耗。串口 115200打印SmartLock boot便于确认固件已跑起来。ui.begin()TFT 初始化、setRotation(4)、清屏。keypad.begin()行脚输出高、列脚上拉输入。buzzer.begin()无源则配置 LEDC占空比先置 0。servoLock.begin()转到锁定角延时后断开 PWM。eventLog.begin()从 NVS 命名空间evlog恢复环形缓冲与序号。security.begin()从smartlock读主密码与访客密码非法长度则写入默认1234。ble.begin()设备名SmartLock服务FFF0写特征FFF1通知特征FFF2开始广播。记录启动时刻清空密码缓冲标记全屏重绘。上电后先停留在欢迎页SPLASH_MS2200 ms再进入锁定待机。2.2 主循环逻辑loop()每一圈完成六件事顺序固定BLE 维护ble.loop()在断开后重新开始广播。取命令有写入则handleBleCommand()状态查询、上锁、日志、访客、纯数字开锁、U:/C:。取按键有键则handleKey()按当前mode解释0-9 * # A B C D。定时状态迁移欢迎超时进锁定失败/成功/提示页到时切走锁定倒计时结束恢复待机开锁满 8 秒自动上锁输密超过 15 秒清空并返回锁定。休眠与心跳无操作满 20 秒且不在锁定中/已开锁/记录/访客等关键页时关屏约每 400 ms 给倒计时页局部刷新已连接时约每秒主动OK:STATUS:…。渲染fillModel()汇总密码掩码、剩余次数、倒计时、日志四行、访客码等交给ui.render()。仅脏标记为真时才画。自动上锁路径会转舵机、响锁定音、记一条上锁事件、通知OK:LOCKED并弹出「已自动上锁」。蓝牙连上瞬间会OK:READY并立刻推一次状态方便 App 刷新剩余次数。三、代码拆分讲解工程入口是SmartLock/SmartLock.ino其余均为头文件模块便于课程按文件讲解。文件职责config.h引脚、舵机角度、蜂鸣器类型与音调、密码策略、BLE UUID、界面色、编译期引脚检查KeypadScan.h自行扫描 4×4去抖并等松手不依赖第三方 Keypad 库Buzzer.h无源 PWM 音调 / 有源高低电平点击、成功三音、失败、报警、上锁ServoLock.h50 Hz、0.52.5 ms 脉宽映射 0180°到位可detachSecurity.h主密码 NVS、失败计数与分级锁定、访客码生成/核销/过期EventLog.h64 条环形日志、序号连续、格式化屏幕行与 BLE 行DisplayUI.h中文绘制、状态栏、锁形图标、局部倒计时、睡眠命令FontCN.h点阵字库由tools/gen_font.py生成BleLock.hGATT 服务、写回调入队、Notify、断开再广播SmartLock.ino状态机、开锁/上锁、键盘与 BLE 协议、UiModel 组装3.1 键盘模块逐行拉低读列是否为低。确认按下后等待释放再返回字符避免连发。键位表与实体键盘一致时A上锁、B改密、C菜单、D清空才与说明书相符。3.2 安全模块verify()成功清零失败次数失败累加满 5 次按LOCKOUT_BASE_SEC level进入锁定封顶 300 秒。改密必须旧密码正确错误同样计入失败。访客码用esp_random()生成 6 位数字且避开主密码consumeGuest()成功后置已用并写 NVS。注意访客剩余时间以本次开机的millis()起算重启后若密码尚未使用会重新按 24 小时计算。3.3 日志模块结构体含序号、累计秒、来源、类型、成败。缓冲区满则丢掉最旧一条。formatLine供屏幕如#001 00:12 本地开锁formatBle供手机OK:LOG:序号,时间,来源,动作,结果。3.4 显示模块markDirty()全刷markPartial()只更新倒计时。睡眠发送 ST7789 的DISPOFFSLPIN唤醒SLPOUTDISPON。按键或 BLE 活动会activity()唤醒。3.5 蓝牙模块FFF1 支持 Write 与 Write Without Response兼容部分手机 GATT。FFF2 带 2902 描述符以便订阅通知。命令最长约 47 字节。主文件协议摘要手机写纯数字或U:密码开锁L上锁S状态H倒日志G/GQ/GX生成、查询、作废访客C:旧:新改密。设备通知OK:STATUS:LOCKED|UNLOCKED|LOCKOUT:剩余次数:锁定秒OK:UNLOCKED:远程OK:GUEST:ACTIVE:密码:剩余秒以及ERR:WRONG等。四、操作过程及数据展示4.1 操作步骤编译与烧录用 零知派 打开SmartLock/SmartLock.ino。开发板选 零知ESP32上传后打开串口应看到SmartLock boot。有源蜂鸣器把BUZZER_PASSIVE改为0无源蜂鸣器把BUZZER_PASSIVE改为1。锁舌方向反了则对调SERVO_ANGLE_LOCKED与SERVO_ANGLE_UNLOCKED。本地开锁 / 上锁屏幕显示锁定与「蓝牙未连接 / 已连接」。输入 48 位数字*删一位#确认。正确则舵机转到开锁角提示成功来源「本地」进入已开锁页并显示剩余秒数。满 8 秒自动上锁或按A/#立即上锁。输错会减剩余次数5 次后进入锁定页倒计时结束才能再试。修改主密码键盘锁定界面按B→ 旧密码#→ 新密码#→ 再输入一次#。两次不一致会提示并回到新密码步。旧密码错误计入失败次数。菜单、记录、访客键盘按键作用C进入菜单1开锁记录*较旧页D较新页#返回菜单2访客页再按2生成D作废#返回D输入页清空已输入数字手机开锁推荐网页用支持 Web Bluetooth 的浏览器打开tools/ble_test.html扫描并连接SmartLock。输入主密码或访客码点开锁可一键上锁、刷新状态。页面会解析OK:STATUS显示门锁状态、剩余次数、锁定倒计时。可生成 / 查询 / 作废访客密码拉取记录并导出 CSV。App Inventor 制作步骤见docs/app-inventor.md。Android 扫描 BLE 通常需打开定位并授予附近设备权限。忘记密码零知派工具菜单擦除 Flash 后重新烧录主密码恢复为DEFAULT_PIN。只改代码里的默认值而不擦除NVS不会覆盖已经存过的密码。4.2 数据展示屏幕与协议屏幕典型信息顶部蓝牙状态锁定页密码圆点错误时变红已开锁页自动上锁秒数锁定页剩余秒记录页每行#序号 MM:SS 来源动作访客页 6 位数字与剩余时间。串口KEY: 5、BLE: 1234等便于对照操作。状态通知示例OK:STATUS:LOCKED:5:0表示已锁定、还可试 5 次、未在惩罚锁定。OK:STATUS:UNLOCKED:5:0为已开锁。OK:STATUS:LOCKOUT:0:28为惩罚锁定还剩 28 秒。日志 BLE 流OK:LOG:BEGIN:条数→ 多条OK:LOG:…→OK:LOG:END。网页可将记录与通信日志分别导出 CSV。4.3 演示视频零知ESP32--4×4 矩阵键盘智能密码锁五、技术原理5.1 工作原理矩阵键盘行作输出、列作上拉输入。某一键按下时对应列被拉到该行的低电平扫描到「行 r、列 c」后查表得到字符。去抖延时约 25 ms并等待释放保证一次按键只产生一个事件。舵机50 Hz 周期 20 ms。脉宽约 0.5 ms 对应 0°、2.5 ms 对应 180°。固件默认锁定 0°、开锁 90°。转到目标角后断开 LEDC引脚拉低减轻抖动与功耗。无源蜂鸣器LEDC 输出方波频率决定音调。有源蜂鸣器则只拉高/拉低忽略频率宏。密码校验开锁时先看访客码是否匹配且未过期、未使用再比主密码。访客优先避免与主密码冲突时的歧义生成时已尽量避开主密码。失败写入日志并可能进入 lockout。BLE GATT手机对 FFF1 写入 UTF-8 文本设备对 FFF2 Notify。未做配对加密附近设备理论上可嗅探明文仅适合教学。连接后固件周期性推送状态网页用 1 秒轮询S也可达到同样效果。NVSPreferences命名空间smartlock存pin、gpin、gusedevlog存二进制环形数组、条数与序号。擦除整片 Flash 会清空二者。显示局部刷新已开锁与惩罚锁定页数字每约 0.4 s 变化一次。若屏幕未变且仅秒数变化只重绘倒计时区域避免整屏闪烁。5.2 工作模式配置全部策略在config.h按演示需求修改后重新编译即可。宏默认值含义PIN_MIN_LEN/PIN_MAX_LEN4 / 8主密码长度DEFAULT_PIN1234仅 NVS 为空或非法时写入MAX_FAIL_ATTEMPTS5连续失败次数上限LOCKOUT_BASE_SEC30首次锁定秒数LOCKOUT_MAX_SEC300锁定上限AUTO_RELOCK_SEC8开锁后自动上锁INPUT_TIMEOUT_MS15000输密超时回锁定DISPLAY_SLEEP_MS20000无操作关屏LOG_CAP64日志容量GUEST_PIN_LEN6访客密码位数GUEST_TTL_MS24 小时访客有效期CPU_FREQ_MHZ80CPU 频率BLE_TX_POWER−3 dBm广播发射功率BLE_DEVICE_NAMESmartLock扫描名称SERVO_ANGLE_LOCKED/UNLOCKED0 / 90锁舌角度SERVO_DETACH_AFTER_MOVE1到位断开 PWMBUZZER_PASSIVE11 无源0 有源TFT_ROTATION4屏幕方向BLE UUID 亦可在 App Inventor 中填短形式FFF0、FFF1、FFF2。改设备名后需重新烧录手机端按新名称扫描。六、常见问题指引现象可能原因与处理花屏、偏色TFT_eSPI 中开关TFT_INVERSION_ON确认ST7789_DRIVER且宽高为 240。旋转后画面左移、右侧空白打开CGRAM_OFFSETrotation 4 的 240×240 分支使用colstart80不要改成 0。键盘无响应或乱码检查排针左右顺序确认列脚不是 19/5GPIO5 被按住可能影响启动可上电后再接键盘。舵机抽动、ESP32 反复复位5 V 供电不足改外部 5 V 并共地勿用 3.3 V 供舵机。舵机、蜂鸣器完全没反应禁止 GPIO3439改回 21 与 22。有源蜂鸣器一直响或不响BUZZER_PASSIVE 0低电平触发再设BUZZER_ACTIVE_HIGH 0。手机搜不到串口须有SmartLock boot,建议用EDGE浏览器打开开手机蓝牙与定位本设备是 BLE不能用经典蓝牙串口助手。能连不能开锁UUID 改完整 128 位写入 UTF-8 且utf16falseApp Inventor 的WriteStrings必须传列表可先发纯数字密码。改密后忘记密码擦除 Flash 再烧录恢复DEFAULT_PIN。只改了代码里的1234仍是旧密码密码已在 NVS需擦除或用改密流程覆盖。访客时限重启后变回 24 小时未使用的访客码会保留计时基准在开机时重置。
返回列表