在信息越来越密集的今天,我们经常在电脑、手机和各种通知之间来回切换。很多时候,并不是我们没有安排任务,而是缺少一个足够安静、足够克制,又能够持续提醒自己的工具。
基于这个想法,我开发了 PaperFocus------一个以 ESP32-S3 为核心、使用 4.2 英寸墨水屏作为主要显示界面的开源专注助手。
PaperFocus 不只是一个番茄钟示例,也不是只负责点亮屏幕的硬件 Demo。当前项目已经实现了番茄钟、健康提醒、任务展示、环境传感器、RTC 时钟、Wi-Fi 校时、数据持久化、USB 上位机配置以及 A/B OTA 升级等功能,并形成了一套相对完整的嵌入式应用架构。
项目地址:https://github.com/willow017/PaperFocus
当前固件版本:0.1.2
当前硬件版本:1.0.0
为什么选择墨水屏
PaperFocus 的核心定位是"安静地陪伴用户完成专注任务",因此显示方案选择了 4.2 英寸、400×300 分辨率的墨水屏。
与普通 LCD 相比,墨水屏非常适合这类低频信息展示场景:
- 静态画面几乎不需要持续刷新;
- 断电后仍可保持画面;
- 阅读体验接近纸张,长时间放在桌面上不刺眼;
- 不会通过高亮动画不断争夺用户注意力;
- 很适合显示时间、今日任务、番茄钟状态和环境信息。
当然,墨水屏也有刷新速度慢、局部刷新容易残影等问题。因此,PaperFocus 在界面层中加入了脏区管理、整屏刷新、局部刷新、旧图同步以及刷新超时恢复机制,而不是简单地按固定周期整屏重绘。
当前已经实现的功能
1. 番茄钟与专注流程
项目内置了完整的番茄钟状态机,支持:
- 开始、暂停、恢复和停止专注;
- 专注与休息阶段切换;
- 短休息和长休息;
- 自动开始下一阶段;
- 番茄钟完成统计;
- 运行状态持久化和断电恢复;
- 番茄钟页面秒级局部刷新。
番茄钟并不是简单地在 UI 任务中递减数字,而是由统一的事件系统驱动状态变化。这样可以让输入、提醒、统计、灯效和界面刷新围绕同一份业务状态协同工作。
2. 健康提醒
PaperFocus 当前支持三类提醒:
- 喝水提醒;
- 久坐提醒;
- 休息提醒。
提醒触发后,可以通过墨水屏页面和 WS2812 灯效向用户反馈,并支持确认、稍后提醒、角标提示等状态。提醒次数和确认情况也会进入当天统计数据。
3. 今日任务与统计
设备可以展示三条今日任务,每条任务支持:
- 自定义标题;
- 完成状态;
- 重要标记。
统计页面会展示当天的专注时长、番茄钟数量、休息情况和提醒数据。项目还实现了跨日检测,日期变化后会更新当天统计和页面状态。
4. 时间、RTC 与网络校时
PaperFocus 支持 RTC 本地时钟,并可以通过 Wi-Fi 和 SNTP 自动校时。
仓库默认使用 ntp.aliyun.com,连接或同步失败时还会尝试其他备用服务器。Wi-Fi 凭据默认不写入仓库,可以通过本地配置或 USB 上位机写入设备 NVS,避免将个人网络信息提交到公开代码仓库。
5. 环境传感器
项目接入了:
- SHT40 温湿度传感器;
- BH1750 环境光照传感器。
传感器通过同一条 I²C 总线连接。设备会周期读取温度、湿度和光照数据,并将其显示在首页。针对传感器异常,代码中也提供了相应的失败处理和降级逻辑。
6. WS2812 状态灯
PaperFocus 默认支持 12 颗 WS2812 灯珠,可以根据不同状态显示专注、休息、喝水、久坐、故障等灯效。
灯效由独立任务周期驱动,不会阻塞业务状态机和墨水屏刷新。
7. USB 上位机与参数配置
为了让普通用户不必修改源码和重新编译固件,项目提供了基于 PySide6 开发的 Windows 图形化上位机,并已经打包为单文件 PaperFocusTool.exe。
上位机支持:
- 自动枚举 PaperFocus USB HID 设备;
- 查看固件版本、硬件版本、序列号和运行状态;
- 配置 Wi-Fi、番茄钟、提醒、灯光和系统参数;
- 编辑三条今日任务;
- 查看和清除升级诊断信息;
- 发送自定义 HID 调试命令;
- 执行固件升级。
USB HID 协议、参数处理和升级逻辑已经直接集成到上位机程序中,用户只需要运行一个 EXE 文件,不需要额外安装 Python。
8. A/B OTA 与升级保护
项目使用 16 MB Flash,并划分了两个 3 MB 的 OTA 应用分区。
升级流程包含:
- 升级会话管理;
- 固件元数据检查;
- 分包传输;
- CRC 与 SHA-256 校验;
- A/B 启动分区切换;
- 升级诊断记录;
- 新固件启动健康检查;
- ESP-IDF 应用回滚支持。
除了项目私有的 HID 管理协议,仓库默认配置还启用了标准 TinyUSB DFU 数据通道。
软件架构
PaperFocus 使用 ESP-IDF 和 FreeRTOS 开发,代码按照职责划分为以下模块:
app:启动流程、全局状态、事件核心、任务创建和页面路由;drivers:墨水屏、RTC、Wi-Fi、SNTP、NVS、I²C、传感器、输入和 LED 驱动;services:事件总线、番茄钟、提醒、统计、时间同步、灯效、USB HID 和 OTA;storage:配置、任务、统计和运行状态持久化;ui:画布、页面模型、布局、脏区合并和刷新调度;utils:CRC、日志和时间格式化等公共功能。
系统整体采用"多任务采集和驱动、单核心事件状态机、独立 UI 渲染"的方式运行。
输入、定时器、传感器、网络和 USB 等模块负责产生事件,task_app_core 统一消费事件并推进业务状态。业务层只标记需要更新的 UI 区域,最终由 UI 任务合并刷新计划并驱动墨水屏。
这种结构可以避免多个任务同时直接修改业务状态,也可以减少没有必要的墨水屏刷新。
默认硬件配置
仓库当前默认使用以下硬件配置:
- 主控:ESP32-S3;
- Flash:16 MB,DIO,80 MHz;
- PSRAM:默认关闭;
- 墨水屏:4.2 英寸,400×300;
- 墨水屏接口:SPI2,默认 4 MHz;
- 旋钮:EC11;
- 灯光:12 颗 WS2812;
- 温湿度:SHT40;
- 光照:BH1750;
- USB:ESP32-S3 原生 USB OTG;
- 存储:NVS、独立诊断 NVS、SPIFFS 和 Coredump 分区;
- 升级:双 OTA 应用分区,每个分区 3 MB。
主要 GPIO 默认分配如下:
- GPIO8:I²C SDA;
- GPIO9:I²C SCL;
- GPIO4:WS2812 数据;
- GPIO16 / GPIO17:EC11 A/B 相;
- GPIO18:EC11 按键;
- GPIO13:墨水屏 SCLK;
- GPIO14:墨水屏 MOSI;
- GPIO15:墨水屏 CS;
- GPIO45:墨水屏 DC;
- GPIO40:墨水屏 RST;
- GPIO35:墨水屏 BUSY;
- GPIO19 / GPIO20:ESP32-S3 原生 USB D- / D+。
所有板级引脚都可以通过 menuconfig -> PaperFocus Driver Config 调整。仓库中的 sdkconfig.defaults 是默认配置基准,本地生成的 sdkconfig 不应提交。
如何编译
项目要求:
- ESP-IDF 5.5.0 或更高版本;
- 目标芯片为 ESP32-S3;
- 已正确安装 ESP-IDF Component Manager 依赖。
主要依赖组件包括:
espressif/esp_tinyusb == 2.1.1;espressif/led_strip ^3.0.3;espressif/knob ^1.0.2;espressif/button ^4.1.6。
进入 ESP-IDF 命令行环境后执行:
bash
git clone https://github.com/willow017/PaperFocus.git
cd PaperFocus
idf.py set-target esp32s3
idf.py build
烧录并查看日志:
bash
idf.py -p <PORT> flash monitor
需要修改引脚、Wi-Fi 或其他板级参数时,可以执行:
bash
idf.py menuconfig
需要注意的是,本地 sdkconfig 一旦生成,就不会自动被后来更新的仓库默认值覆盖。如果希望完全恢复仓库默认配置,应先备份个人配置,再删除本地 sdkconfig 和旧构建目录,然后重新执行 idf.py set-target esp32s3 和 idf.py reconfigure。
适合哪些人
PaperFocus 适合以下开发者和爱好者参考:
- 正在学习 ESP32-S3、ESP-IDF 和 FreeRTOS;
- 希望了解墨水屏整刷、局刷与残影处理;
- 需要一个较完整的事件驱动嵌入式项目示例;
- 正在实现番茄钟、桌面提醒器或低干扰信息终端;
- 希望学习 USB HID 私有协议和上位机配合方式;
- 正在研究 A/B OTA、固件校验与回滚;
- 希望参考 NVS 配置迁移和运行状态持久化实现。
项目当前状态
PaperFocus 目前属于可以在真实硬件上持续调试的集成版本,主要功能链路已经落地,但仍然处于持续开发和完善阶段。
由于不同墨水屏批次、ESP32-S3 模组和外围电路可能存在差异,使用前请根据自己的硬件检查 GPIO、电源、BUSY 电平、SPI 时钟和 Flash 容量等配置。
PSRAM在仓库中默认关闭,固件按片内 RAM 环境设计。如果目标模组带有 PSRAM,可以在本地配置中自行启用,但建议重新验证启动、内存分配、USB和墨水屏刷新稳定性。
写在最后
PaperFocus 是一个持续开发和完善中的开源项目。受限于开发时间、硬件条件和个人经验,代码中难免存在考虑不周、实现不足或文档疏漏之处。
如果你在使用过程中发现问题,欢迎在 GitHub 中提交 Issue;如果你有更好的设计思路、功能实现或代码优化,也欢迎发起 Pull Request。
无论是问题反馈、使用体验、硬件适配记录,还是代码贡献,都会帮助这个项目变得更加稳定、易用和完善。
如果你觉得 PaperFocus 对你的学习或项目有所帮助,也欢迎 Star 项目,让更多对 ESP32-S3、墨水屏和嵌入式开发感兴趣的人看到它。
AI 辅助开发说明
PaperFocus 项目由开发者在 AI 辅助下共同完成。AI 参与了部分代码实现与重构、问题分析、调试思路整理、上位机开发以及文档编写等工作;项目的功能需求、技术路线、硬件适配、实际测试和最终决策仍由开发者负责。
项目公开这一开发方式,希望如实记录 AI 在嵌入式开发流程中的实际应用,也欢迎大家对其中的代码质量、架构设计和实现细节进行审阅、讨论与改进。
项目地址:https://github.com/willow017/PaperFocus
关键词:ESP32-S3、ESP-IDF、FreeRTOS、墨水屏、电子纸、番茄钟、USB HID、TinyUSB、OTA、PySide6、开源项目、嵌入式开发