自制墨水屏手表:从硬件选型到30天续航的低功耗全解析

发布时间:2026/10/13 1:18:12
自制墨水屏手表:从硬件选型到30天续航的低功耗全解析
1. 为什么我放着现成智能手表不用偏要自己攒一个墨水屏手表先交代一下背景。我手上有两块主流智能手表一块是常亮OLED屏另一块是翻腕亮屏的AMOLED。续航分别是“一天一充”和“极限两天”。起初我忍了直到有次出差忘了带磁吸充电线手表在第二天下午直接罢工我才认真思考一个问题明明墨水屏电子书能续航三四周为什么手表不行答案其实不在电池而在显示方案。普通手表屏幕一旦点亮整块面板都在耗电哪怕显示一个静态表盘背光、驱动IC、刷新电路都在工作。墨水屏则完全不一样它的显示原理决定了只在画面变化时消耗能量。换句话说屏幕本身就是一个低功耗的“存储介质”断电后内容依然留在屏幕上。把这种屏幕用到手表上续航逻辑直接就变了。后来我在开源社区看到有人做了一个完全符合我想象的项目基于Arduino生态、墨水屏显示、可自定义表盘、支持蓝牙和Wi-Fi连接、带实时天气、番茄闹钟、指南针还能做到30天续航。最吸引我的不是表盘多炫而是整条设计思路怎么用一颗低功耗MCU加上一块电子墨水屏拼出一个“功能不少、耗电不多”的腕上设备。我照着源码从零搭了一台中间踩了不少坑也把功耗、显示、通信这些环节一个个拆开研究了一遍。这篇文章就把我对这个项目的完整理解和实操记录写下来。适合两类人看一是对墨水屏硬件开发感兴趣、想动手复刻一个新奇设备的玩家二是手头有低功耗嵌入式需求想搞明白“续航30天到底怎么抠出来的”开发者。我不会只贴代码更多的会讲每个环节背后的取舍以及那些文档里不会写的坑。2. 从需求倒推硬件选型墨水屏手表的每一块钱都花在哪先别急着买零件。做这种开源项目最忌讳的就是照着物料清单all in装完才发现某个模块功耗高得离谱或者屏幕驱动电压不匹配。正确顺序是先明确需求再让每个器件满足需求的同时把功耗账单算清楚。2.1 主控芯片要的不是性能是“睡得好”普通智能手表的主控动辄就是应用处理器级别性能强但待机电流也得几十毫安光是让系统跑个RTOS再维持蓝牙连接电池就扛不住。这个开源项目走的是另一条路一颗低功耗MCU平时几乎全速休眠只在需要时醒来干活。选型时核心看几个指标睡眠电流理想值要在10μA以下支持蓝牙因为手表要和手机通信有足够GPIO和通信外设去驱动墨水屏、传感器以及能跑Arduino生态方便复用现成库。这里我特别想说明一点如果你对Wi-Fi也有刚需很多低功耗蓝牙芯片是不带Wi-Fi的实际的方案里往往是把Wi-Fi模块单独拎出来平时完全断电联网时再上电。这不是偷懒而是省电的关键策略。另外一个容易忽略的点是IO口的数量和复用。墨水屏SPI一般占用4个引脚磁力计I2C又占2个再加上电池电压检测、按键、LED引脚很容易见底。我自己就是画原理图时发现IO不够被迫砍掉一个物理按键改成长按和双击复用。所以选主控时留出2~3个富余引脚后面会轻松很多。2.2 墨水屏刷新慢不是缺点是省电的前提墨水屏选型我建议关注三件事尺寸、灰度和接口。手表表盘面积有限1.54英寸到2.9英寸是比较常见的区间再大戴在手上就像贴了个小Pad。黑白屏刷新快、价格低、驱动简单三色屏黑白红能提升表盘层次感但刷新时间会明显变长而且红色像素在部分光照下会发灰我实际对比过最终还是选了黑白屏。接口方面强烈建议买带转接板的裸屏模块而不是裸的玻璃屏。带转接板意味着已经把FPC排线转成了标准的排针接口焊接难度大幅下降。驱动电压也要提前确认清楚很多墨水屏需要3.3V逻辑供电加一个约15V~20V的驱动电压源如果主控板不带升压电路你就得额外配一块升压小板否则屏幕只会白屏。有个新手最容易犯的错误是把墨水屏当成普通LCD来用在循环里频繁刷新。墨水屏单次全刷的瞬间电流能有十几毫安虽然时间短但如果每秒钟刷一次耗电立刻爆炸。这个项目的设计思路是“少刷新、集中刷新”表盘按需刷新分钟级更新走局部刷新这是续航的基础后面我会详细算这笔账。2.3 传感器和其他外围该断的电路一定要断除了主控和屏幕手表上还有几样小东西实时时钟RTC芯片、磁力计、加速度计以及电池充放电保护电路。RTC芯片的作用是主控休眠后依然能计时同时可以设置闹钟中断来唤醒主控。有些MCU内置RTC但精度一般而且休眠时必须保持某个时钟源运行算下来功耗并不低。外置RTC芯片待机电流只有几百纳安还能独立供电是长续航方案里很值得的一笔投资。加速度计用来做抬腕亮屏和运动计步待机功耗可以通过配置低功耗模式压到几十微安。磁力计则是指南针功能的核心市面上很多模块把加速度计和磁力计集成在一起排线也简单。我在选传感器时只有一个原则必须支持关断或低功耗睡眠模式。如果某个传感器上电后就一直在跑哪怕只跑1mA30天下来也是0.72Ah直接抵掉一块小电池的容量。电池方面考虑到表体空间300~500mAh是比较现实的容量。充放电管理芯片要挑带保护、带充饱检测的不要自己用二极管和电阻搭充电电路我试过一次不仅充不满还差点把电池充鼓包。充电接口用Type-C小模块装在表壳侧边日常使用非常方便。下面是我整理的一份选型速查表可以直接照着买模块作用选型要点主控运行逻辑、蓝牙通信睡眠电流10μA引脚富余墨水屏含转接板显示表盘1.54~2.9英寸、黑白、SPI接口外置RTC休眠计时、闹钟唤醒支持外部32.768kHz晶振、中断输出加速度计抬腕亮屏、计步支持低功耗模式I2C接口磁力计指南针与加速度计集成更省空间电池整机供电300~500mAh带保护板无线模块联网/蓝牙可独立断电按需供能这块的结论是硬件选型没有哪个部分是“随便用什么都行”每个器件都在为同一个目标服务就是在保持功能的前提下把每一微安的静态电流都压下去。选型结束之后我建议先用面包板把所有模块连起来跑通最基本的显示和睡眠流程再考虑做PCB或装壳至少能省掉一半的排错时间。3. 软件架构一个裸机程序是怎么管理表盘、天气、番茄钟和指南针的硬件折腾完了来看软件。这个开源项目用的是Arduino框架但和我印象里的Arduino小demo完全不同它不是靠delay死等而是用“主循环状态机中断唤醒”的方式把各个功能串起来。我拆源码的时候最大的感受是它其实是在一台没有操作系统的单片机上硬是搭出了一个“事件驱动”的运行框架。3.1 主循环与唤醒模型平时睡觉有事再起整个程序的运行模型可以理解为三个状态运行态、短睡态、深睡态。运行态时MCU正常跑完所有任务然后主动进入睡眠短睡态一般持续几秒到几十秒用于响应按键、屏幕刚刷完之后的等待深睡态则是主控关闭大部分时钟和外设只留RTC中断和GPIO唤醒引脚电流降到微安级。每当RTC的闹钟中断到来或者用户按键触发外部中断MCU被唤醒程序从唤醒源判断该做什么。如果是分钟闹钟就读取RTC时间更新表盘的时分显示走局部刷新如果是天气同步闹钟才打开Wi-Fi模块联网拉数据如果是抬腕动作就点亮屏幕并切换到待机表盘。这里有个Arduino开发者必须注意的细节delay函数会阻塞整个流程所以在唤醒后处理屏幕刷新时不能简单地delay等待刷新完成要用millary时钟来分片处理或者干脆在刷新期间让主控等待墨水屏的BUSY引脚拉低。如果处理不好就会出现“屏幕刷到一半就睡了”或者“刷屏期间被其他中断打断”的诡异问题。3.2 表盘抽象以后想换表盘不用重写固件自定义表盘是这个项目最大的卖点之一。我原本以为官方会提供类似“表盘编辑软件”的东西实际上它做得很巧妙把表盘定义成一组绘制函数和数据源绑定关系每个表盘都是一个独立的结构体包含初始化函数、绘制函数、按键处理函数和数据刷新回调。比如数字表盘它绑定的数据源有“小时”“分钟”“日期”“电量”天气表盘则额外绑定了“温度”“天气图标”“最高最低温”。绘制函数会拿到当前全局状态然后在屏幕缓冲区上画出对应的文字、图标和线段。由于代码里把所有绘制都放在同一个回调接口里后续想新增表盘只要照着结构体格式写一套绘制逻辑再注册进去就行完全不需要改动底层驱动。如果你完全不写代码也可以在项目配套的表盘配置文件里用位图数组定义指针表盘和图标生成C语言头文件重新编译烧录。这种“配置即代码”的方式对新人比较友好不需要理解太多底层改一改数组里的数据就能换一种指针样式。3.3 功能模块的数据流天气、番茄钟、指南针如何和平共处一个很有代表性的问题是天气数据、番茄钟计时、指南针读数这三个东西刷新频率完全不同、数据来源也不同放在同一个MCU上怎么不打架答案是模块化加统一调度。程序把这些功能抽象成“服务模块”每个模块有自己的状态机和时间槽。时间槽由RTC闹钟统一规划比如每30分钟为一个天气同步周期每1分钟为一个屏幕局部刷新周期番茄钟则在预设的结束时间点触发。指南针比较特殊它虽然可以连续刷新但考虑到功耗只在屏幕显示指南针界面时才开始连续采样退出界面立即停止并关闭传感器电源。我画了一个不严谨的数据流描述RTC中断是心脏所有定时任务靠它驱动模块之间不复用全局变量而是通过统一的数据结构传递比如天气信息存进一个全局结构体绘制表盘时直接读它蓝牙和Wi-Fi采用“即用即开、用完即断”的策略连接建立后推送一次数据就断开绝不长期保持在线。这种切断式联网看似粗暴实际效果极好交互时延在可接受范围内功耗却降了一到两个数量级。3.4 蓝牙和Wi-Fi的取舍不是所有数据都需要实时最后说说通信。很多人的第一反应是“能联网的手表当然要一直在线推送消息”但这个项目刻意做了减法。蓝牙主要用于手机端配置和表盘推送属于低频操作Wi-Fi仅用于获取天气和校时属于定时操作。这套取舍在开源生态里非常有代表性长续航产品的天职不是实时在线而是该在线时在线不该在线时彻底离线。代码实现上蓝牙模块用服务端和客户端模式手机App连接之后可以下发表盘ID、校时、开关闹钟Wi-Fi则通过HTTP请求拉取天气JSON解析后存入结构体。我实际测试一次完整的上线拉取天气耗时大约2秒平均电流七八十毫安算下来每天两次才消耗不到0.1mAh的电量完全可以忽略。用户界面交互也不复杂屏幕空间小每屏只突出一个主题数字或图标。菜单用嵌套式列表滑动靠按键循环切换返回靠长按。这块的设计原则是一切从简多一点复杂度就多一份BUG。4. 30天续航是怎么抠出来的功耗模型与实测数据我先说个扎心的事实30天续航不是靠一块大电池而是靠把平均电流压到极低。一个400mAh的电池要撑30天平均电流必须小于400/30/24约等于0.56mA。也就是说整个手表在任何时刻的平均运行电流都不能超过半毫安多一点。这需要非常精细的功耗预算。4.1 功耗模型每个器件每秒钟都在花什么钱我把整机功耗拆成了四块静态功耗、显示刷新功耗、通信功耗、传感器功耗。其中静态功耗由MCU睡眠电流、RTC工作电流、传感器睡眠电流、以及各路电阻的漏电流组成。这个项目在静态部分做得相当狠所有传感器都配置成睡眠模式不用时切掉供电MCU进入深度睡眠后整机静态电流实测能压到15~25μA。显示刷新功耗是大头之一。墨水屏全刷一次的耗电和屏的大小、刷新波形有关我那块1.54英寸黑白屏全刷一次大约消耗0.8mAh这还不是瞬时电流问题而是“全刷动作”的积分消耗。如果每分钟全刷一次一天就是1.15Ah直接把电池吃光。所以表盘显示用的是“分钟级局部刷新”局部刷新一次只有全刷的三分之一左右再配合每半小时全刷一遍清除残影一天显示功耗能压到3mAh以内。通信功耗看似可怕但用时间稀释之后就还好。Wi-Fi模块打开瞬间峰值电流能到300mA听上去吓人可它真正工作时间只有2秒左右。蓝牙广播如果一直开着平均电流至少多出几十微安所以方案里干脆把广播周期性开关每4秒广播一次持续40毫秒平均下来只增加不到10μA电流。传感器部分抬腕亮屏依赖加速度计中断平时让它跑在低功耗模式下电流只有30μA左右。4.2 实测数据一天平均多少毫安时我按照“每天查看时间60次、同步天气2次、番茄钟1小时、指南针使用5分钟”的典型使用场景测了一天整机平均电流大约在0.3~0.4mA之间扣除锂电池自放电和充放电转换效率后400mAh电池撑到接近30天是合理的。请注意这个估算没有算进“重度折腾”比如频繁刷表盘、一直开着指南针、每几分钟就同步一次天气续航会掉到十天以内但正常使用完全是另一个量级。表里列出的是实测量和设计值对照功耗项设计目标实测值备注整机静态睡眠30μA25μA含RTC和传感器睡眠电流表盘局部刷新1mAh/次0.25mAh/次1.54英寸黑白屏表盘全刷清残影1mAh/次0.8mAh/次每半小时一次Wi-Fi拉取天气0.2mAh/次0.15mAh/次2秒内断开蓝牙广播10μA平均8μA平均周期开关指南针连续使用50mA均值42mA均值仅显示界面时开启要想复现这套数据有两个地方特别容易被忽略我得单独拉出来说。第一个是电源域划分。几乎所有低功耗方案都要求传感器和无线模块能够独立断电主控GPIO给它们供电或者用负载开关控制。如果共用一个电源轨哪怕传感器处于睡眠也总有漏电流跑出来几个模块叠加就是几十微安直接打破预算。第二个是调试器的问题。用调试器下载程序后如果调试器一直插着板子就给调试接口持续供电电流直接多出几十毫安。我第一次测功耗时就是这个原因怎么测都是几十毫安怀疑人生了大半天拔掉调试器之后数字立刻恢复正常。所以想测出好看的数字量功耗时必须断开所有调试线。4.3 几个“电老虎”的坑蓝牙常开、Wi-Fi重连、电压检测分压电阻这里我数几个最容易把续航拖垮的小细节。蓝牙如果每秒钟广播一次平均功耗轻松上到几百微安工作日用下来就少好几天续航所以广播周期必须拉长或者彻底关掉。Wi-Fi首次连接时如果周围没有记住的网络模块会持续扫描峰值电流能维持好几秒这时一定要设置超时逻辑连接超时就立即断电而不是一直重试。还有一个不容易发现但很关键的点是电池电压检测。很多开发板用两个大阻值电阻分压把电池电压送进ADC如果电阻一端始终接着电池分压链路就会一直耗电。虽然两个几百千欧的电阻并联实际电流只有几微安看着不多但老想着“几微安而已”的坑就是从这里开始的。正确做法是让主控GPIO控制分压电路的通断测的时候才上电测完立刻断开。30天续航的真相其实是“把每一份能量都给了当前唯一的任务”。你打开天气界面时屏幕、Wi-Fi、CPU都在为这件事服务你退出界面后它们全都进入沉默只剩下一个RTC在黑暗中悄悄数秒。5. 核心功能实现指南针、天气、番茄钟不是简单贴API如果说续航是地基功能模块就是地上盖的房子。这个项目有意思的地方在于它没有把功能做成“能用就行”的玩具级而是把每个功能都往实用的方向调了一遍。我来逐个讲讲实现时真正棘手的地方。5.1 实时天气JSON解析是内存杀手天气功能在嵌入式里最常见的翻车点不是网络而是内存。Arduino开发板往往只有一两百KB的RAM而天气API返回的JSON动辄几KB直接解析必然爆内存。这个项目的做法是自己写了一个极简JSON提取函数只取需要的字段不要的字符直接跳过用流式解析代替整体存储。我的建议是请求时通过API参数裁剪字段比如只请求当前温度和天气代码别把城市列表、经纬度明细一并拉下来。解析完的数据放进一个固定结构体再关掉Wi-Fi把内存空间释放出来。表盘绘制时只读结构体不保留原始字符串。这套流程下来整个天气模块在运行时只占不到2KB内存非常紧凑。另外一个坑是时区。很多天气API返回的是UTC时间如果不做时区转换表盘上的日出日落、更新时刻全都会错位。直接的办法是同步时间时把本地时区偏移量存下来在转换为年月日时分时统一应用。网上很多教程在讲NTP校时却不说时区处理我做的时候也是被折腾了好几轮。5.2 番茄闹钟低功耗场景下的定时器设计番茄钟的实现听起来简单无非是倒计时结束提醒一下但在低功耗手表上问题就变成了“主控睡死了怎么知道时间到了”。方案是用外置RTC的闹钟功能在进入番茄钟时计算结束时刻的绝对时间戳写入RTC闹钟寄存器然后主控直接睡死。到点之后RTC中断唤醒主控这比MCU内部定时器可靠得多也省电得多。番茄钟的UI是一个状态机包括准备、计时中、暂停、结束四个状态。每个状态的切换都伴随着一段局部刷新屏幕上显示剩余分钟数和一个圆形进度环。进度环的位置要按分钟数动态计算并增量刷新一个容易踩的坑是局部刷新时残留像素圆圈每次只是多画一格结果旧像素留下的浅影会让进度变粗。我的解决办法是每次刷新前先把进度环区域整体刷白再做增量绘制刷新时间多花几毫秒干净度提升不少。震动提醒方面开源方案一般用马达模块它算是一个功率大户所以提醒时只振一秒就停。如果想要更长提醒让RTC设置一个几分钟后的第二闹钟再振一次避免马达长时间通电。听起来有点抠但这就是低功耗设备的日常。5.3 指南针磁力计远不止读数值指南针最基础的做法是读磁力计的X、Y轴数据然后atan2就能算出朝向角但直接这样做出来的指南针只能水平放置稍微倾斜角度就乱跳。正常的手表戴在手腕上手腕必然有倾角所以必须用加速度计做倾角补偿把磁力数据投影到水平面后再算角度这才是实用指南针的门槛。倾角补偿的公式不复杂但要算准需要建立旋转矩阵。实现上大致是读取加速计的俯仰角和横滚角再对磁力计的原始值做三维坐标变换得到水平面的磁场分量最后用atan2求解。这个过程中最麻烦的是磁场干扰焊在表壳里的主控、屏幕排线、扬声器都可能产生硬铁干扰所以手表需要在校准模式下让用户拿着转几圈采集最大最小值做偏移修正。硬铁校准效果相当明显不校准的表在固定朝向上可能偏十几度校准完之后能压到3度以内。5.4 自定义表盘到底怎样才叫“自定义”我个人把表盘自定义分成三个级别。初级是改配置文件里的时间位置和图标中级是调整数据源绑定关系高级是直接在绘制函数里写图形算法。这个项目三个级别都支持了我觉得这是它作为开源项目特别有生命力的原因。表盘的绘制函数接收一个屏幕缓冲区的上下文可以直接调用画线、画圆、画矩形、画字符串等原语。比如做一个极简指针表盘你只需要根据当前时间算出时针和分针的终点坐标画两条粗线段就完成了一大半。再比如想要一个电量百分比环就根据ADC读到的电压值推算百分比画一个带弧度的环形进度。所有表盘状态被保存在一个全局结构体里切换表盘时先执行退出清理再执行新表盘的初始化。我在自己的复刻工程里加了一个“数字纪念碑谷”风格的表盘背景是黑白方块矩阵时间用点阵方式显示。整个绘制过程让我重新理解了嵌入式图形编程的本质没有系统级的UI框架没有现成的组件一切都是一块128x250的画布以及你手中的数组和画笔函数。6. 装配、烧录和调试从空板到点亮我踩过的坑全在这硬件和软件都就绪之后离真正的“戴在手上”还差最后一步。这个阶段的技术难度不高但坑非常密集我按自己的顺序记录一遍希望能帮你少走弯路。6.1 屏幕排线是第一道坎别硬掰也别用过多焊锡墨水屏的FPC排线非常娇贵弯折超过一定角度或者拉力稍大排线内部线路就会断裂表现是屏幕某一块区域怎么刷新都是空白。新手第一次接屏幕模块时特别容易犯一个错用手硬掰排线试图对准插槽结果把排线边缘掰裂。正确操作是先把排线末端对准FPC连接器的卡槽确认金手指方向后轻轻推进再压合翻盖。如果是自己用转接板焊排针烙铁温度控制在300~330摄氏度焊锡不要堆得太多相邻引脚之间一旦连锡屏幕直接显示不出东西还得费半天排查。我开始图省事直接买了一体带转接板的模块省了很多事强烈建议你也有样学样。接好线后先别急着烧录用万用表挨个量一遍接线是否有短路。重点检查屏幕电源引脚拿万用表蜂鸣档量电源和地之间如果哔哔响先处理短路再说。我有一块屏幕就是上电后白屏查了半天发现是SPI的SCK和MOSI引脚虚焊导致主控根本没把数据送到驱动芯片。6.2 首次烧录bootloader选不好卡到怀疑人生Arduino生态的一大优势是烧录方便但这个项目的主控板不一定出厂自带Arduino的bootloader。如果你的板子默认是其他固件需要先走一次烧录引导程序的过程。常见做法是用USB转串口工具接好复位引脚和启动引脚按住启动按键在上电瞬间进入烧录模式。烧录引导程序之后就能用Arduino IDE直接下载固件了。IDE的板级支持包选对应厂商的开发板配置否则即使编译通过下载后跑起来也是各种莫名行为。这里的坑是不同版本的主控库对结构体和枚举类型的内存布局不一样如果手头的库版本比项目源码老编译时可能报错强行忽略有时候能过但运行起来数据是错位的我的指南针模块就出过这种问题。更新开发板核心包到和源码版本一致可以避免掉至少一半的编译玄学。如果你不想折腾Arduino IDE图形界面也可以像很多玩家一样直接用命令行工具链编译配合一个固定的固件链式脚本每次改完表盘一键编译下载效率高很多。但新手还是先从IDE开始别一上来就折腾命令行项目本身已经够有学习量了。6.3 显示异常排查从白屏、残影到字体错位显示问题在墨水屏开发中占了我大概三分之一的调试时间。白屏大概率是屏幕驱动时序不对或者初始化顺序不对比如上电后立刻发初始化命令而屏幕供电还没稳。我解决的办法是在初始化函数开始前加200ms延时让电源稳定后再发命令白屏概率显著下降。残影问题是墨水屏的天生属性常见缓解手段是定期全屏刷新。有些新手为了防止残影每次更新都全刷一下结果续航崩了。居中的做法是分钟刷新用局部刷新每半小时做一次全刷清残影每天深夜再额外做一次多次翻转的深度清洁视觉体验和功耗都能兼顾。字体错位则多半是字符编码或字库问题。中文表盘需要GB2312或UTF-8字库如果字库里没有对应字符程序就会显示一个空洞。我的做法是精简字库把常用的日期、星期、天气状况汉字做成索引表烧录前先用脚本检查一遍表盘会用到的字符集避免运行中出现“方块字”。6.4 低功耗调试的隐藏陷阱量出来的电流为什么总是高我前文提过调试器不拔会严重影响功耗这里再补充几个导致读数偏高的隐藏因素。第一个是串口外设没完全禁用即使你在程序里没有调用Serial打印只要串口外设时钟没有关闭电流就会多出几百微安到几毫安不等。第二个是ADC的参考电压电路有些开发板为ADC参考电压保留了一个内部稳压器不用时也需要禁用。第三个是GPIO浮空输入悬空引脚会不停翻转状态产生额外的开关电流。我的建议是设计一个专门的量测固件进入深度睡眠前把所有GPIO设置成确定状态要么拉低、要么拉高、不能浮空关闭所有外设时钟然后睡眠。然后用万用表的小电流档串联供电测出的数才能反映真实静态功耗。不要用开发板自带的电源指示灯做参考那个灯本身就点亮了不合理的电流。6.5 电池电量显示别直接读电压乖做校准墨水屏手表的电池显示模块很容易做成摆设因为锂电池的放电曲线在中间段非常平缓在两端又极其陡峭直接拿电压百分比当电量显示结果就是“100%用了两天还是100%然后一夜之间掉到15%”。我做的处理是分段映射加平滑滤波先采集一整条放电曲线记录不同电压对应的剩余容量百分比做成查表数组运行时把每次ADC读数做移动平均再查表得到百分比。如果时间充裕还可以在充电和放电不同状态下用不同映射表因为锂电池的充电电压和放电电压在同一容量点差距不小。表盘上的低电量保护也要设计好。电压低于保护阈值时程序应该主动关闭Wi-Fi和指南针这类高耗电模块只保留时钟和分钟刷新这样还能再多撑几天而不是直接黑屏罢工。这块逻辑在源码里只占了很小一段但实际使用中体验差距极大属于典型的“代码量不大、价值不小”。7. 最后聊两句这块表教会我的不只是省电从立项到戴上手腕我大概花了两周时间中间经历了屏幕不亮、固件跑飞、功耗居高不下、指南针乱跳各种问题。最后把它戴在手上连续用了三个月中途只充过一次电表盘上那个静谧的黑白时间偶尔在阳光下能看到微妙的灰度层次说实话有一种“这玩意儿完全归我掌控”的感觉。这三个月里我最大的体会倒不是“30天续航真厉害”而是深刻理解了什么叫“够用的设计”。智能手表作为腕上设备它的核心需求其实是随时一眼可见的时间、偶尔的天气参考、以及不需要频繁充电的安心感。为了这些核心需求我们完全可以抛弃那些华丽的换肤动画和繁琐的实时通知把计算和能量留给真正重要的事情。如果你也想做类似的设备我的建议是从一个非常小的功能做起点先点亮屏幕再显示时间再尝试续航。每一步都亲手验证过整个系统的感觉会完全不一样。我已经在这个基础上加了换表盘快捷键和电量报警下一步想接一个心率传感器把运动数据也做进去这大概是墨水屏手表的另一个有趣边界。反正屏幕永远都在那里不用电也能醒目地看着我。