零知派ESP32–基于TM1637 四位数码管模块制作简约番茄钟教程
项目概述
什么是番茄钟?
番茄钟是一种时间管理方法,全称是“番茄工作法”,由弗朗西斯科·西里洛在1980年代创立。简单说,它的核心流程就像这样:专注工作 25 分钟(这25分钟叫“一个番茄”)> 休息 5 分钟。> 每完成 4 个“番茄”后,进行一次 15分钟的较长休息。
基于 ESP32 的桌面番茄钟,集成ST7789 TFT 彩屏(240×240)和 TM1637 数码管,支持双屏同步倒计时显示、休息动画播放、断电记忆保存、可自定义工作时长。
项目文件结构:
PomodoroYueXin/
├── PomodoroYueXin/
│ ├── PomodoroYueXin.ino # 主程序
│ ├── REST_anim.h # 动画帧索引表
│ ├── REST_0.h ~ REST_13.h # 14 帧 RGB565 动画数据
│ ├── WORK.h # 专注模式背景图
├── REST.gif # 休息动画源文件
├── WORK.png # 专注模式背景图源文件
├── convert.cs # GIF 转 RGB565 转换器
└──convert_png.cs # PNG 转 RGB565 转换器
项目亮点
- 双屏同步:TFT 彩屏显示状态与动画,TM1637 数码管同步倒计时
- 断电记忆:关机后自动保存当前状态、倒计时时间、工作周期、自定义时长
- 番茄工作法:25 分钟专注 → 5 分钟短休 × 3 次 → 15 分钟长休 → 循环
- 最后 10 秒提示:专注模式最后 10 秒蜂鸣器急促滴答提醒
- 快捷操作:短按/长按/组合键实现重置、调整、恢复出厂
项目难点及解决方案
| 难点 | 解决方案 |
|---|---|
| 闪存容量有限(约 3MB) | 动画步进=2(14 帧),每帧 ~112KB,合计 ~1.54MB + 背景图 ~115KB + 代码 ~100KB,总 ~1.75MB,留有余量 |
| 双屏同步刷新 | TM1637 用硬件 I²C 模拟,TFT 用 SPI,两者独立,loop 中非阻塞轮询 |
| 动画不遮挡文字 | pushImage 只推送 y=24~216 区域(偏移 24×240),上下各留 24px 给文字 |
| 断电记忆版本兼容 | NVS 存储使用版本号(ver=2),loadNVS() 检查版本,避免旧数据解析错误 |
| 按键消抖与长短按区分 | 200ms 消抖 + 1000ms 长按阈值 + longHandled 标志防止短按误触 |
一、硬件系统部分
1.1 硬件清单
| 硬件 | 数量 | 说明 |
|---|---|---|
| 零知派ESP32开发板 | 1 | 主控,3MB 可用闪存 |
| 零知派ESP32扩展板 | 1 | 自带专属插口和按键 |
| ST7789 TFT 彩屏(240×240) | 1 | 主显示屏幕 |
| TM1637 四位数码管模块 | 1 | 倒计时数字显示 |
| 无源蜂鸣器 | 1 | 响铃提醒 |
| 杜邦线 | 若干 | 接线 |
| 数据线 | 1 | 烧录代码,给ESP32上电 |
1.2 接线方案
| ESP32 引脚 | 连接目标 |
|---|---|
| GPIO16 | TM1637 CLK |
| GPIO17 | TM1637 DIO |
| 3.3V | TM1637 VCC |
| GND | TM1637 GND |
| GPIO2 | 蜂鸣器正极 |
| GND | 蜂鸣器负极 |
1.3 硬件连接图

1.4 实物连接图

二、软件架构设计
2.1 系统初始化
setup() 执行流程:
上电
└→ 串口初始化
└→ 配置按键 GPIO(INPUT_PULLUP)
└→ 配置蜂鸣器 GPIO
└→ bootAnimation()
├→ TM1637 亮度 7,显示 88:88 冒号闪烁(2.5 秒)
└→ TFT 显示 "YueXinMiao / Pomodoro"
└→ loadNVS()
└→ 从 NVS 恢复断电前状态(含版本检查)
└→ showTime(remainingSeconds) → TM1637 显示当前剩余时间
└→ showWorkUI() / showRestUI() → TFT 显示对应界面
└→ 如运行中,设置 lastTick = millis()
改动bootAnimation() 中 tft.setRotation() 设置屏幕旋转方向,可设置为 0,1,2,3。
2.2 主循环逻辑
loop() 每轮执行以下任务(非阻塞轮询):
loop()
├── 工厂重置检测(仅调整模式,S2+S3 长按 3 秒)
├── handleModeButton() ← S3:模式切换 / 调整减
├── handleStartPause() ← S2:开始暂停 / 调整加
├── handleReset() ← S1:重置 / 进入退出调整
├── 倒计时递减(每秒)
│ ├→ 归零时 beepOn() + advanceState()
│ └→ 每 15 秒自动保存 NVS
├── 最后 10 秒急促提示音(专注模式)
├── 蜂鸣器 1 秒后自动关闭
├── TM1637 冒号闪烁(速度按剩余时间变化)
├── 调整模式数字闪烁(500ms 周期)
└── 休息动画帧推进
三、代码拆分讲解
3.1 引脚与全局变量
#define CLK_PIN 16 // TM1637 时钟线
#define DIO_PIN 17 // TM1637 数据线
#define BUZZER_PIN 2 // 蜂鸣器
#define MODE_PIN 27 // S3
#define START_PIN 14 // S2
#define RESET_PIN 12 // S1
状态枚举 enum State { WORK, SHORT_REST, LONG_REST } 定义三种工作模式。
关键全局变量:
remainingSeconds— 当前倒计时剩余秒数workCycleCount— 已完成专注数(0~3),满足 4 次进入长休息adjustMode/adjustSeconds— 调整模式及其分/秒位切换isRunning— 倒计时是否运行中
3.2 NVS 断电记忆
saveNVS() / loadNVS() 使用 Preferences 库存储到 NVS 分区:
存储内容:
ver=2 (版本号)
state (当前状态枚举值)
remain (剩余秒数)
workT (自定义专注时长)
shortT (自定义短休息时长)
longT (自定义长休息时长)
cycle (当前专注周期数)
run (是否运行中)
loadNVS() 中检查 ver >= 2 后才恢复,避免旧版格式数据错误。
3.3 界面绘制
专注模式 showWorkUI():
- 全屏推入
img_WORK(200×200 居中于 240×240 黑底) - 顶部 “WORK”(红色,字号 2)
- 底部 “Pomodoro X/4”(黄色,字号 1)
休息模式 showRestUI():
- 清屏黑色
- 顶部 “S_REST” / “L_REST”(绿色,字号 2)
- 底部专注计数(黄色,字号 1)
- 中间区域留给动画
动画播放 stepAnimation():
- 使用
pushImage(0, 24, 240, 192, &REST_frames[i][24*240])只推送 y=24~216 区域 - 每帧按
REST_delays[]指定延时切换 - 14 帧循环播放
调整模式 showAdjustUI():
- 标题 “ADJ-WORK” / “ADJ-S_REST” / “ADJ-L_REST”
- 5 号字时分显示,被调单位(分或秒)500ms 闪烁隐藏
- 操作提示:S2:+ / S3:- / S1:unit / Hold S1:exit / Hold S2+S3:reset
3.4 按键处理逻辑
三个按键各自独立处理函数,每个函数内部区分"调整模式"和"正常模式"两套逻辑:
| 按键 | 正常模式操作 | 调整模式操作 |
|---|---|---|
| S1(GPIO12) | 短按=重置计时;长按1秒=进入调整模式 |
短按=切换分/秒位;长按1秒=退出调整 |
| S2(GPIO14) | 短按=开始/暂停;蜂鸣时按=关闭响铃 | 短按=加 1 分钟或 1 秒 |
| S3(GPIO27) | 短按=切换到下一阶段 | 短按=减 1 分钟或 1 秒 |
恢复出厂设置:调整模式下同时按住 S2+S3 保持 3 秒,恢复所有默认值并清除 NVS。
按键逻辑使用 bothHeld() 检测 S2+S3 同时按下,避免误触。
3.5 倒计时与双屏同步
- 每秒
remainingSeconds--,归零时onTimerEnd()响铃 + 自动切换状态 - TM1637 每次更新时同步显示
remainingSeconds的 MMSS 格式 - TFT 在状态切换时调用
showWorkUI()/showRestUI()重绘 - 冒号闪烁速度随剩余时间变化:
- 专注模式最后 10 秒:100ms 快速闪
- 专注模式最后 5 分钟:250ms 中速闪
- 其余:600ms 慢速闪
3.6 蜂鸣器
- 倒计时结束时:
beepOn()输出 1kHz PWM,1 秒后自动关闭 - 专注模式最后 10 秒:每 500ms 输出 2kHz 短促音(15ms)
四、操作过程及数据展示
4.1 操作步骤
-
硬件连接:正确连接所有模块。
-
编译与上传:在零知派中选择开发板“ESP32 ”,正确选择端口,编译并上传代码。

4.2 使用说明
初次使用
- 上电 → 开机动画(TFT 显示标题,TM1637 88:88 闪烁 2.5 秒)
- 默认进入专注模式(25:00),倒计时等待启动
- 按 S2 开始倒计时
日常使用
S2(短按) → 开始/暂停倒计时
S3(短按) → 切换阶段:专注→短休→(循环4次)→长休→专注
S1(短按) → 重置当前阶段的计时
自定义时长
S1(长按1秒)→ 进入调整模式
S2(短按) → 加 1 分钟(或加 1 秒)
S3(短按) → 减 1 分钟(或减 1 秒)
S1(短按) → 切换分钟/秒钟(被调单位闪烁)
S1(长按1秒)→ 退出调整
恢复出厂设置
在调整模式下:
按住 S2 + S3 保持 3 秒 → TFT 显示 "Factory Reset" → 自动回到专注模式
断电记忆
- 运行中或暂停中直接断电,下次开机自动恢复断点
- 倒计时每 15 秒自动保存一次
4.3 演示视频
零知派ESP32–基于TM1637数码管模块制作番茄钟
五、技术原理
5.1 工作原理
- TFT 显示(TFT_eSPI 库):通过 SPI 接口驱动 ST7789,240×240 分辨率,RGB565 颜色格式
pushImage()直接推送预转换的 16 位像素数组到 GRAM- 动画帧预处理为
const uint16_t PROGMEM数组,存放在闪存中
- 数码管(TM1637Display 库):I²C 协议模拟驱动 TM1637 芯片
showNumberDecEx()显示 4 位数字 + 冒号(0x40 位控制)
- 断电记忆(Preferences 库):调用 ESP32 的 NVS API,写入 NVS 分区
- 每次状态变化(剩余时间、调整时长、运行状态)都会触发保存
- 保存间隔 15 秒减少擦写次数
- 按键输入(GPIO INPUT_PULLUP):三个按键均为低电平触发
- 软件 200ms 消抖 + 1000ms 长按阈值
5.2 工作模式配置
番茄工作法规则:
专注(25分钟)→ 短休息(5分钟)→ 专注 → 短休息 → 专注 → 短休息 → 专注 → 长休息(15 分钟)
→ 专注 → ...(第 4 次专注结束后)→ 长休息(15 分钟)→ 专注 → ...
模式切换逻辑(advanceState() 函数):
WORK → workCycleCount++
├── 满 4 次 → LONG_REST(清零计数)
└── 未满 4 次 → SHORT_REST
SHORT_REST → WORK
LONG_REST → WORK
- 注意力集中系数(MAX_WORK_CYCLE=4):每完成 4 个专注周期插入一次长休息
- 专注计数在进入长休息时自动归零,在短休息时保持累加
各模式默认时长:
长休息 = SHORT_REST + LONG_REST = 15分钟
| 模式 | 默认时长 | NVS 键名 |
|---|---|---|
| WORK | 25 分钟 | workT |
| SHORT_REST | 5 分钟 | shortT |
| LONG_REST | 10 分钟 | longT |
六、常见问题指引
Q1:编译后闪存不够怎么办?
检查分区设置:工具 → Partition Scheme → 选择 No OTA (Large APP)。如果仍然不够,可在 convert.cs 中将 step 改为 3 或 4 减少帧数。
Q2:屏幕方向不对怎么办?
在 bootAnimation() 中修改 tft.setRotation() 参数:
0:USB 口朝下1:USB 口朝右2:USB 口朝上3:USB 口朝左
Q3:如何更换休息模式动画?
- 将新的 GIF 文件命名为
REST.gif放入PomodoroYueXin目录 - 编译运行
convert.cs重新生成帧数据 - 如帧数变化,需同步修改
REST_anim.h中的REST_frame_count和REST_delays[] - 如果改为其他文件名,需同步修改
convert.cs中的路径
Q4:如何更换专注模式背景图?
- 准备 240×240 的 PNG,命名为
WORK.png放入PomodoroYueXin目录 - 编译运行
convert_png.cs重新生成WORK.h
Q5:TM1637 显示不正常?
- 检查 CLK(GPIO16)和 DIO(GPIO17)接线
- 供电电压应为 3.3V
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)