☰
基于ESP32-C3的开源墨水屏智能手表:低功耗设计与30天续航实践
2026/10/13 5:35:46 网站建设 项目流程

作为一个常年跟电池续航较劲的嵌入式玩家,我一直想搞一块真正能戴一个月不充电的智能手表。研究了很久之后,我最终把目标锁定在“墨水屏 + Arduino 编程 + 低功耗蓝牙/Wi-Fi”这个组合上。墨水屏静态显示零功耗,Arduino 生态开发门槛低,再加上开源社区里现成的表盘渲染思路,这套方案的可行性比我预想中高很多。这篇内容就是我基于这个思路完整落地的一块开源墨水屏智能手表——它支持自定义表盘、蓝牙连接手机接收通知、Wi-Fi 定时拉取实时天气、内置番茄闹钟和指南针,整机待机续航可以做到 30 天以上。

如果你手上刚好有 ESP32-C3 或者类似的低功耗无线 MCU,想低成本做一个能戴出去的手表,又不想在水群和教程之间反复横跳,那这篇东西应该能帮你省下不少弯路。我会把硬件选型、电源设计、固件架构、表盘自定义逻辑、校准方法以及踩坑记录全部拆开讲一遍,尽量让不同基础的爱好者都能照着做出来。

1. 项目初衷与整体思路拆解

1.1 为什么是墨水屏,而不是 OLED 或 LCD

做可穿戴设备,屏幕选型基本决定了续航上限。OLED 虽然对比度高、色彩艳丽,但它的像素自发光原理决定了只要屏幕亮着就在耗电,哪怕只是显示一个静态表盘,驱动电流也维持在毫安级别。LCD 更不用说了,背光一开,电池就刷刷往下掉。智能手表又是全天佩戴的设备,屏幕点亮时间累积下来非常可观。

墨水屏的原理完全不同,它是靠电场驱动双色微胶囊颗粒翻转来成像,画面一旦显示出来,即使完全断电,颗粒位置也会保持不变。这意味着手表显示时间的时候,屏幕驱动电路和 MCU 可以进入深度休眠,真正做到了“显示不耗电”。市面上的电子价签、电子书阅读器能够做到数月续航,靠的就是这个特性。

在对比 OLED、LCD、墨水屏三种方案时,我最终选择墨水屏的核心理由有三点:

  • 静态画面功耗为零,非常适合表盘这种长时间不变的显示场景。
  • 黑白/黑红黄的显示风格辨识度高,强光下阅读舒适,户外看时间完全没问题。
  • 驱动芯片成熟,像 SSD1680、UC8151 这类墨水屏控制器都有现成的 Arduino 库,开发成本低。

当然墨水屏也有缺点,比如刷新速度慢、局部刷新有残影、彩色方案刷新更慢且价格高。但对一个以看时间和看通知为主的手表来说,黑白屏的刷新速度完全够用,残影问题也可以通过合理的表盘设计和刷新策略来抑制。

1.2 功能定位:六个核心功能,不堆料

这个项目最终确定的功能清单是:时间显示、自定义表盘、蓝牙通知、Wi-Fi 天气、番茄闹钟、指南针。没有加计步、心率、语音助手这些花哨功能,原因很简单——每多加一个传感器,功耗和体积就会失控,开发周期也会成倍拉长。

功能取舍有一个重要原则:凡是需要持续工作的模块,都要尽量降低其工作频率。比如 Wi-Fi 连通性,我做的不是长连接,而是定时唤醒拉取天气;蓝牙也不是一直广播,而是主要作为从机被动等待手机连接,平时保持睡眠状态。番茄闹钟和指南针属于本地功能,完全不依赖网络,在深度睡眠下靠 RTC 定时唤醒或按键中断触发即可。

下表是六个核心功能模块的实现方式和功耗占比预估:

功能模块实现方式功耗特征
时间显示外部 RTC + 墨水屏静态显示静态显示零耗电,RTC 微安级
自定义表盘表盘渲染引擎 + Flash 字体库仅刷新时耗电
蓝牙通知BLE 从机 + 自定义 GATT 服务被动等待,连接后毫安级
Wi-Fi 天气定时唤醒 + 天气 APIWi-Fi 开启瞬间几十毫安
番茄闹钟RTC 闹钟 + 本地计时软件逻辑,几乎无额外功耗
指南针I2C 磁力计 + 校准算法测量瞬间毫安级

这种“以低功耗为最高优先级”的功能裁剪思路,保证了整机待机时间足够长。整个系统的功耗预算我在后面会详细算给大家看。

1.3 主控、屏幕和传感器选型对比

主控方面我重点比较了三款:ESP32-C3、nRF52840、RP2040。RP2040 是纯 MCU,没有无线功能,直接排除;nRF52840 的低功耗性能非常强,蓝牙协议栈成熟,但它的 Wi-Fi 需要外挂芯片,体积和成本都会增加,而且 Arduino 生态支持不如 ESP32 系列完善。ESP32-C3 是 RISC-V 内核,集成 Wi-Fi 和 BLE,深度睡眠电流可以做到个位数微安级别,价格便宜,开发板也容易买到,最适合这个项目。

屏幕方面我最初试过 2.9 英寸三色屏,刷新一次要两三秒,残影也明显,后来换成了 2.13 英寸黑白屏。分辨率 212x104,显示时间、日期、天气图标、通知文字都够用,刷新速度大概一秒左右,功耗更低。驱动芯片是 SSD1680,大部分 Arduino 库都原生支持,不用自己折腾底层时序。

指南针模块选的是 QMC5883L 磁力计,I2C 接口,价格低,驱动简单。还有一个选项是 LIS3MDL,灵敏度更高,但校准起来稍微复杂一点。对于只需要看大致方位、配合手机地图使用的手表来说,QMC5883L 足够。外部 RTC 选的是 PCF85063A,带闹钟功能,可以输出中断唤醒 MCU,功耗在微安级别,这一点对低功耗设计至关重要。

1.4 30 天续航到底是怎么算出来的

很多朋友看到“30 天续航”第一反应是吹牛,其实这个数字是有明确计算依据的。关键点在于墨水屏的静态显示不耗电,所以手表绝大多数时间都处于“显示着时间、但芯片在睡觉”的状态。

我用 300mAh 的软包锂电池举一个例子。系统深度睡眠时,MCU 消耗约 5μA,RTC 约 0.7μA,电源管理电路漏电约 2μA,合计约 8μA 左右,一天下来就是 0.19mAh。假设每 15 分钟通过 RTC 闹钟唤醒一次,刷新表盘显示最新时间,每次唤醒到刷新完成大约 200ms,平均电流约 25mA,这部分日均消耗约 0.8mAh;每天早晚各一次 Wi-Fi 同步天气,每次 Wi-Fi 连接加 HTTP 请求约 5 秒,平均电流约 90mA,日均约 0.25mAh;再加上偶尔的蓝牙通知和指南针使用,我实测整机日均平均电流大概在 1.5mA 左右,300mAh 电池算下来理论续航 200 小时,也就是 25 天左右。如果只开半小时蓝牙同步、减少 Wi-Fi 天气同步次数,把日均平均电流压到 1mA 以下,做到 30 天并不困难。

要特别注意,这个计算的前提是芯片必须真正进入深度睡眠,而不是用 delay 假装休眠;屏幕驱动电路的电源也需要在非刷新状态下彻底切断,否则升压电路的漏电就能把续航砍掉一半。这一点我在电源设计部分还会展开讲。

2. 硬件选型与电路搭建

2.1 核心器件清单

除了主控和屏幕之外,硬件设计里最容易被低估的其实是电源管理和 RTC 电路。墨水屏手表不是一堆模块插杜邦线就能解决的,为了续航和体积,我最终把大部分器件集中在了一块小板上。下面是我整理的核心器件清单:

器件型号/方案作用
主控ESP32-C3 模组运行固件、蓝牙、Wi-Fi
墨水屏2.13 寸黑白,SSD1680表盘显示
外部 RTCPCF85063A时间保持、闹钟唤醒
磁力计QMC5883L指南针
电池3.7V 软包锂电池,300mAh整机供电
充电TP4056 类线性充电 + 保护板锂电池充电管理
LDO低静态电流 LDO,3.3V 输出稳压供电
按键三个轻触开关菜单、翻页、确认
振动马达扁平纽扣马达可选通知提醒

这里要特别说明外部 RTC 的必要性。ESP32-C3 内部没有内置 RTC 是不可能的,它确实有内部时钟,但精度一般,而且主芯片一旦深度睡眠,想定时精确唤醒还是依赖外部 RTC 更可靠。PCF85063A 这类芯片在备用电池模式下功耗极低,使用 32.768kHz 晶振,日误差可以控制在几秒以内,并且能够通过 INT 引脚输出闹钟信号唤醒 MCU,这是我整个低功耗状态机的核心基础。

2.2 电源架构与低功耗设计细节

电源架构决定了整机能不能真正做到长续航。我第一版电路图简单粗暴,直接把电池接到 MCU 的供电引脚,结果待机功耗非常高,后来才发现是显示器驱动电路的漏电在作怪。

正确做法是给屏幕单独做一个电源开关,用 MOSFET 或负载开关芯片控制 VDD 到墨水屏驱动电路的通断。墨水屏在不刷新时,驱动芯片虽然不显示画面,但它的内部升压电路和逻辑电路依然在消耗电流,如果始终保持供电,待机电流会多出几百微安甚至更高。这在低功耗设计里是致命问题。

电源链路是这样的:锂电池 -> 保护板 -> 充电芯片 -> 电池节点 -> 低静态电流 LDO -> 3.3V -> MCU、RTC、磁力计、屏幕电源开关。LDO 选型的重点是低静态电流,普通 AMS1117 这类 LDO 静态电流达到 5mA 左右,完全不能用于电池设备,要选静态电流在微安级别的型号。MCU 的 ADC 还要用来监测电池电压,通过两个电阻分压后接到 ADC 引脚,注意分压电阻阻值要尽量大,比如 1MΩ+1MΩ,减少漏电。

屏幕电源控制引脚接到 MCU 的 GPIO 上,每次需要刷新时先开电源,等 100ms 稳定之后再执行刷新命令,刷新完成后立即关闭屏幕电源。这套操作看起来简单,但能把待机电流从几百微安降到 10μA 以内,是续航倍增的关键。

2.3 引脚分配与接线参考

我把核心引脚分配整理成一个表格,方便大家布线和写代码时对照:

功能引脚(ESP32-C3)说明
墨水屏 SCKGPIO4SPI 时钟
墨水屏 MOSIGPIO5SPI 数据
墨水屏 CSGPIO6片选
墨水屏 DCGPIO7数据/命令选择
墨水屏 RSTGPIO8复位
墨水屏 BUSYGPIO9忙检测
屏幕电源开关GPIO10高电平开启
RTC INTGPIO3外部唤醒中断
磁力计 SDAGPIO1I2C 数据
磁力计 SCLGPIO2I2C 时钟
按键 K1/K2/K3GPIO0、GPIO18、GPIO19带外部上拉

这里有两个容易踩坑的地方。第一,墨水屏的 SPI 总线不要和 SD 卡或其他外设共享片选,因为墨水屏刷新时对时序要求比较高,总线干扰会导致花屏或刷新失败。第二,接线时要注意屏幕 FPC 排线的方向,排线引脚顺序每一家屏幕厂都可能不一样,最好用万用表或对照屏幕 datasheet 确认 VCC、GND 以及 SPI 引脚顺序,插反了轻则屏幕不亮,重则烧驱动芯片。我自己就因为排线方向问题烧过一块屏幕,后来学乖了,每次焊接前先对照规格书核对一遍。

2.4 电池、充电与外壳组装技巧

电池用的是 300mAh 软包锂电,尺寸大概 35mm×25mm×5mm,可以塞进 42mm 表壳内部。充电采用 TP4056 线性充电方案,充电电流设置为 100mA 左右,因为手表电池容量小,太大电流会让电池发热降压快。TP4056 模块外围元件少,但要注意板上自带的电池保护电路和实际电池保护板不能冲突,一般情况下不再额外加保护板,模块自带即可。

外壳方面我最初用 3D 打印 PLA 做了第一版,整体太厚,表带连接件也比较脆弱,后来改成了光固化树脂打印。树脂的防水性和表面质感比 PLA 好很多,但要注意树脂在高温下容易变形,不能长时间暴晒。表壳内部需要给 FPC 排线留出折弯空间,硬塞容易导致排线内部断裂,这是墨水屏设备最常见的隐性故障。

按键的防水处理也要提前考虑。我用了加了硅胶垫圈的轻触开关,外壳开孔处打了一圈密封胶。虽然不能说完全防水,但日常洗手、淋雨短时间接触没有问题。如果追求真正的防水等级,那就要考虑全密封结构加感应按键了,复杂度会高一个量级。

3. 固件架构与关键代码实现

3.1 软件分层与低功耗状态机

固件架构如果一开始不规划好,后面加功能就会越改越乱。我采用的是典型的分层结构:UI 渲染层、功能逻辑层、硬件驱动层,最底层是 Board Support Package。UI 层只管表盘绘制和菜单交互,不关心数据从哪来;功能逻辑层处理天气解析、番茄钟状态、指南针数据;硬件驱动层封装屏幕、RTC、磁力计、BLE 和 Wi-Fi。

整个固件运行的核心是一个低功耗状态机,状态切换逻辑大致如下:

  1. 启动初始化:外设上电、读取 RTC 时间、读取上次保存的表盘配置和天气缓存。
  2. 进入休眠前:关闭屏幕电源、关闭 Wi-Fi、配置好 BLE 广播参数,然后调用深度睡眠模式。
  3. 唤醒事件:包括 RTC 闹钟定时唤醒、按键 GPIO 唤醒、BLE 连接事件唤醒。
  4. 唤醒后处理:根据唤醒源执行对应任务,比如刷新时间、拉取天气、进入菜单、接收 BLE 数据。
  5. 任务完成后重新回到底层睡眠,循环往复。

在 Arduino 环境下,ESP32-C3 可以使用 esp_sleep_enable_ext0 或 ext1 来设置外部唤醒源。我的代码里把 RTC 闹钟中断和三个按键都配置为唤醒源,深度睡眠用的是 ESP_SLEEP_MODE_DEEP_SLEEP。注意在深度睡眠前,一定先把 UART 和屏幕电源关掉,否则芯片会一直认为外设还活着,电流降不下去。

3.2 表盘渲染引擎与自定义表盘

表盘是这个项目最好玩的部分,也是最容易做崩的部分。我的思路是把表盘定义成一个可解析的数据结构,存到 Flash 里,而不是写死一串绘制代码。这样后续想要换表盘样式,只需要修改配置数据再烧录,甚至可以通过蓝牙 OTA 远程更新。

表盘数据结构大致可以这样定义:

typedef struct { uint8_t hour; // 小时指针角度 uint8_t minute; // 分钟指针角度 uint8_t second; // 秒钟指针角度 bool showDate; // 是否显示日期 bool showWeather; // 是否显示天气图标 bool showBattery; // 是否显示电量 int timeX; // 时间文字的中心 X 坐标 int timeY; // 时间文字的中心 Y 坐标 } WatchFaceConfig;

显示时间时,先用“清屏刷新”画一个全白背景,再绘制表盘元素,最后用“局部刷新”把变化的内容刷上去。这里有一个粗浅但很重要的经验:时间变化时不要全屏刷新,只需要用局部刷新窗口更新时分数字区域,全局刷新和局部刷新的交替使用可以大幅减少残影,同时延长屏幕寿命。

自定义表盘可以通过一个简单的上位机网页工具生成配置,也可以直接改配置文件里的坐标值。我在开源固件里给了一个现成的表盘 JSON 配置示例,固件解析 JSON 后自动绘制。注意墨水屏幕的分辨率是 212x104,字体要用取模软件预先转换好,否则中文和数字显示会乱码。

3.3 蓝牙服务与手机联动设计

蓝牙模块主要用来接收手机通知、同步时间以及发送表盘配置。我定义了一个自定义 GATT 服务,包含三个 Characteristic:一个用于手机下发命令、一个用于手表上报状态、一个用于通知数据下发。协议格式用二进制,每条消息包含消息类型、长度、数据字段。

手机端我用的是自己写的一个轻量配置 App,界面比较简陋,但核心功能都能满足:扫描设备、连接配对、下发通知、同步时间、编辑表盘参数。BLE 连接时最需要注意的问题是 MTU 大小,默认 MTU 只有 23 字节,如果一次下发完整的表盘配置会非常慢,需要在连接后协商 MTU 到 247 字节左右。

手表在蓝牙连接期间功耗会有所上升,但只要手机没有发数据,设备大部分时间可以保持在 connection interval 很长、不唤醒主控的状态。我把 connection interval 设置成 400ms,这样既能保持连接,又不会太耗电。通知到达时,手表通过 BLE 回调把内容存入 RAM,之后唤醒 UI 刷新屏幕,并触发马达震动提醒。

3.4 Wi-Fi 天气同步实现

Wi-Fi 是这个项目里最耗电的部分,所以我把它设计成“只在需要拉取天气时打开”。每次开机后,系统先检查距上次同步的时间,如果超过间隔(一般设置 3 小时或 6 小时),才打开 Wi-Fi 连接路由器,向天气服务发送 HTTP GET 请求。

请求的天气信息我采用的是常见的开放天气 API,通过解析 JSON 获取温度和天气代码。响应数据我会先做一个精简,只需要温度和天气描述字符串,然后把解析后的结果存到 RTC 的 RAM 或者外部 Flash 中,等下次刷新表盘时直接读取,不需要每次开机都联网。

这里有一个我踩过的坑:天气 API 返回的温度数值是开尔文单位,经纬度参数如果设置错了,可能拿到其他城市的天气。更常见的问题是网络里的 5GHz 频段路由器,很多低功耗 Wi-Fi 模块并不支持 5GHz,只支持 2.4GHz,所以配网时一定要确保手机和手表连的是 2.4GHz 网络。中文 SSID 也可能导致连接失败,最好把路由器 SSID 改成英文或数字。

Wi-Fi 同步的代码结构大概是这样的:

bool syncWeather() { if (!connectWiFi(ssid, password, 10)) return false; int httpCode = httpGetWeather(); if (httpCode == 200) { parseWeatherJson(); saveWeatherToFlash(); } disconnectWiFi(); return true; }

要注意 HTTP 请求超时时间不能设太长,我一般设置 8 秒,超过就返回失败,避免长时间卡在 Wi-Fi 重试上耗电。

3.5 番茄钟、指南针与通知提醒的实现细节

番茄钟功能本质上是一个基于 RTC 的软件定时器。用户通过按键进入番茄钟模式,设定 25 分钟或自定义时长,倒计时结束后 RTC 闹钟触发中断,MCU 被唤醒,然后驱动屏幕显示“时间到”,同时启动马达震动。这里的核心是学会使用 RTC 闹钟寄存器和中断引脚,而不是用软件 delay 倒计时,后者在深度睡眠下根本无法工作。

指南针功能的实现稍微复杂一点。QMC5883L 输出三轴磁力数据,原始数据需要经过校准才能得到较准确的角度。校准方法是拿着手表在空中画“8”字,让三个轴都能遍历最大最小磁场强度,然后保存 offset 和 scale 参数。校准完成后,根据 atan2 函数计算方位角,再减去当地磁偏角得到地理北方向的角度。

通知提醒的流程是:手机端 App 获取通知权限,把通知标题和内容通过 BLE 发给手表。手表接收后写入滚动显示缓存,在表盘上方弹出一个半透明黑底白字的提示区域,2 秒后自动收起。需要注意的是,通知内容可能包含敏感信息,手表接收时不会超过多少条就自动清空。另外,远程同步手机通知这个功能比较容易出现丢包,如果屏幕刷新太频繁,会导致表盘闪烁严重,所以我设置了通知显示之后的 5 分钟内不刷新表盘,避免干扰。

4. 完整组装与 Arduino 编程实操

4.1 在 Arduino IDE 中配置 ESP32-C3 开发环境

我建议先用开发板把固件跑通,再考虑焊接整体电路。ESP32-C3 在 Arduino IDE 中的安装并不复杂,只需要在“开发板管理器地址”里添加对应的 JSON 链接,然后在开发板列表中选择 ESP32C3 Dev Module。安装完成后,设置上传速度为 921600,烧录模式选择默认即可。

首次烧录前,按住开发板上的 BOOT 键不松,再点击上传,等串口提示连接成功后再松开。很多人第一次烧录失败就是因为没进 bootloader 模式。烧录完成后,打开串口监视器,设置波特率 115200,能看到固件启动日志,如果日志里出现 normal boot,说明系统启动正常。

新板子拿到手,我习惯先单独点亮墨水屏。用示例库里的 SSD1680 测试代码,把屏幕排线插好,上传一个显示“Hello”的简单固件,确认屏幕能正常刷新。如果白屏,优先检查 SPI 引脚是否和代码一致,尤其是 DC 和 BUSY 两个引脚,这两个最容易搞错。另外,墨水屏的 BUSY 引脚如果不接或者接错,刷新会一直卡死在等待状态。

4.2 烧录表盘配置与首屏显示

固件里我内置了一个默认表盘,基于前文提到的 WatchFaceConfig 结构体。如果只是改个表盘样式,不需要重新编译整个固件,只需要把配置文件放到 microSD 卡或者通过 BLE 下发。这里推荐直接通过 BLE 下发,因为不需要拆表。

下面是一段表盘配置的 JSON 示例:

{ "face": "analog", "showDate": true, "showWeather": true, "showBattery": true, "theme": "black_bg_white_line", "font": "Roboto_28", "timeX": 85, "timeY": 28 }

解析这个 JSON 后,固件会调用对应主题的表盘绘制函数。如果你想让表盘支持更多图形元素,比如心率曲线或天气动画图标,可以在配置结构体里增加布尔标记和坐标字段,再在绘制函数里对应处理。这个架构扩展起来很方便,也是我把表盘做成“可配置”而不是“硬编码”的最大原因。

首屏显示务必先做“显示时间”一个功能,确认 RTC 时间、屏幕刷新和电源控制都正常后,再逐步加入天气和 BLE 通知。分层调试可以避免同时出现大量 bug 时不知道问题出在哪里。

4.3 指南针校准与时间同步实操

指南针校准是整机调试中最需要耐心的一步。我写了一个校准模式,长按确认键进入后,屏幕上会显示当前磁力数据的最大值和最小值,你拿着手表在空中画“8”字循环,直到数值变化范围趋于稳定,最后按键保存校准参数。

时间同步方面,最简单的方式是连接手机 App 后一键同步。App 发送当前 Unix 时间戳,手表把它写入 RTC。由于 RTC 晶振有温差漂移,我建议每 2-3 天通过蓝牙同步一次时间,或者依赖 Wi-Fi 拉取天气时顺便从网络时间服务器获取准确时间。这个项目里我很依赖网络自动校准,省去了手动调时间的麻烦。

4.4 从零开始烧录项目的完整流程

为了方便复现,我把整个组装和烧录流程按顺序列一下:

  1. 焊接核心板、RTC、磁力计、按键、电源管理模块到 PCB 或洞洞板。
  2. 连接电池,用万用表确认 VCC 和 GND 没有短路,测量整机待机电流应该在 μA 级别。
  3. 下载固件源码,在 Arduino IDE 中选择 ESP32-C3 开发板,编译并烧录。
  4. 打开串口监视器,确认启动日志正常,测试墨水屏刷新。
  5. 将手表靠近手机,用 BLE App 连接配对,同步时间和表盘配置。
  6. 进入指南针校准模式,完成 8 字校准。
  7. 配置 Wi-Fi SSID 和密码,触发一次天气同步,确认显示温度和天气图标正确。
  8. 戴上手腕实测一整天,观察电量曲线和实际续航。

按照这个流程,一个有一定焊接基础的爱好者,大概在一个周末能完成从散件到可佩戴手表的全部调试。

5. 常见问题与排查技巧实录

5.1 故障排查速查表

我把这个项目在开发和实测过程中遇到的典型问题整理成了一张速查表,方便大家遇到类似情况时快速定位:

现象可能原因解决办法
屏幕纯白无显示屏幕电源未开启或 SPI 引脚接错检查屏幕电源 GPIO 输出,核对 DC/BUSY/CS 引脚
屏幕刷新闪烁严重全局刷新频率过高改为局部刷新,减少非必要全刷次数
待机电流大于 10μA屏幕电源未切断、LDO 静态电流过大增加负载开关,换用低静态电流 LDO
Wi-Fi 连接失败路由器使用 5GHz 频段或中文 SSID配置 2.4GHz 网络,SSID 使用英文数字
BLE 配对失败广播名称冲突或配对模式未开启重启手表,清除手机端旧配对信息
指南针角度偏移未校准或靠近金属物体重新执行 8 字校准,远离手表表带磁扣
天气图标不更新Wi-Fi 超时或 API Key 失效检查网络、更换 API Key,延长超时时间
番茄钟到点不提醒RTC 闹钟中断未配置检查 INT 引脚和唤醒源注册

5.2 白屏和烧板子:我踩过的两个大坑

第一版电路我犯过一个大错:把墨水屏的电源直接接到系统 3.3V 上,没有做负载开关。结果整机待机电流始终有 0.8mA 左右,300mAh 电池最多撑 15 天,远远达不到 30 天目标。后来加上负载开关并修改固件在刷新后关闭屏幕电源,待机电流直接降到 8μA,续航翻了快两倍。

第二个坑是屏幕 FPC 排线方向。某天晚上我焊接完一块屏幕,上电后反复白屏,排查了半天才发现 FPC 排线插反了。墨水屏排线虽然有金手指区分正反,但有些柔性排线的定义并不是常规顺序,不仔细看 datasheet 就插,轻则显示错乱,重则驱动芯片发热烧毁。后来我每次焊接前都会用万用表量一下排线的某一个引脚和驱动板丝印是否对应,再上电测试。

5.3 残影控制与表盘使用寿命

墨水屏手表的残影问题是很多人的劝退点。残影本质上是微胶囊颗粒没有完全翻转到位,导致上一帧的图案出现在新画面上。解决办法有三个思路:第一,减少刷新次数,表盘变化时用局部刷新窗口更新小的区域,比如分钟变化只刷新数字区域;第二,设计表盘时不要大面积使用反色,黑白交替边缘容易产生明显残影;第三,每隔一段时间强制做一次全局刷新,把颗粒状态完全重置。

墨水屏的寿命和刷新次数有一定关系,所以我在固件里加入了刷新频率限制,连续刷新之间至少间隔 5 秒。对于一些需要频繁变化的元素,比如秒针,我就干脆不显示秒,只显示时和分,既保持了表盘简洁,也减轻了屏幕压力。这也是墨水墨手表和普通智能手表在使用体验上需要适应的一个差异点。

6. 后续可扩展的方向与个人体会

最后分享两个我觉得最值得玩的扩展方向。第一个是 OTA 固件升级。ESP32-C3 支持通过 Wi-Fi 下载固件更新,这意味着手表不需要拆机就能更新表盘渲染逻辑和新增功能。我目前已经实现了基础版本号检查和固件写入流程,后面打算把表盘配置的下发也搬到 OTA 通道里,彻底摆脱 USB 线。第二个方向是给手表增加体动传感器,比如用一颗低功耗加速度计实现抬腕亮屏和计步,同时也能辅助指南针做倾角补偿。

个人经验来说,这个项目让我最深切的体会是:低功耗设计从来不是某一个器件的功劳,而是硬件电源架构、固件状态机、刷新策略和用户习惯共同作用的结果。我第一版的手表之所以连两周都撑不到,并不是因为主控不够省电,而是因为屏幕电源常开、LDO 选型失误、Wi-Fi 频繁连接这些“小问题”累积起来,把电池的每一毫安都吃掉了。

如果你也想复刻这个项目,我的建议是先不要急着追求所有功能全上,先把“时间显示 + 长待机”这个核心跑通,再去扩展天气、通知和指南针。每加一个功能,都要重新看一下它的功耗占比和唤醒逻辑是否合理。开源项目的意义就在于你不需要从零踩一遍坑,但把这些代码和电路亲手调通一遍之后,你对嵌入式低功耗设计、蓝牙协议栈、墨水屏驱动这些知识的理解,会是看书完全比不了的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询