超长续航DIY:低功耗MCU与能量收集技术实战解析
1. 项目缘起:当“长续航”成为执念
作为一名玩了十几年开源硬件和DIY的“老鸟”,我发现自己对“续航”这件事的执念越来越深。从早期的Arduino小车跑半小时就得换电池,到后来各种物联网设备为了省电绞尽脑汁,我逐渐意识到,真正的“智能”和“便利”,其根基是“无感”的能源供给。你不需要时刻惦记着充电,设备就在那里,默默工作,这才是科技融入生活的理想状态。
最近,我手头正好有几个闲置的低功耗芯片、太阳能板和电子墨水屏,于是萌生了一个想法:能不能把几个关于“超长续航”和“环境信息”的脑洞,做成一套可以实际把玩甚至日常使用的设备?这就是标题里提到的三个小玩意儿:一个目标是10年续航的“伪”智能手表、一个靠太阳能驱动的口袋收音机/天气站,以及一个怀旧风格的桌面天气卡片。它们的技术核心高度一致——极致的低功耗设计与环境能量采集。这不是商业产品的复刻,而是一次关于功耗边界的工程探索,看看用最普通的元件,续航的极限能到哪里。
2. “10年续航”智能手表:概念与现实的碰撞
“10年续航智能手表”听起来像是个营销噱头,但在DIY的语境下,我们追求的是无限接近这个目标。它不是一个功能齐全的智能手表,而是一个高度特化的“信息看板”。
2.1 核心定位与功能取舍
商业智能手表续航短,根源在于其“全天候感知”与“实时交互”的设计:常亮的触摸屏、持续的心率监测、蓝牙连接、频繁的消息推送。我们要反其道而行之。
我的设计目标是:一块只显示最基本信息(时间、日期)、通过物理按钮交互、仅在需要时刷新的设备。它更像一块电子怀表,或者一个戴在手腕上的“日程提醒器”。核心功能规划如下:
- 主显示:时间、日期、星期。
- 次级功能(通过按钮切换):简易计时器、自定义文字提醒(如“多喝水”)。
- 交互:两颗物理按钮(模式切换、内容切换/确认),彻底抛弃触摸屏。
- 连接:无蓝牙,无无线连接。时间校准通过USB连接电脑完成(一年可能只需要一次)。
2.2 硬件选型:一切为了μA级待机
硬件的每一个选择都直接决定了最终的功耗基线。
主控MCU:TI MSP430FR系列或STMicroelectronics STM32L0系列。它们是超低功耗领域的标杆。我最终选择了STM32L071CBT6,原因有三:其STOP模式下的电流可低至0.4μA(典型值);它内置了RTC(实时时钟),即使在深度睡眠下也能保持计时;我对STM32的生态系统更熟悉。MSP430同样优秀,但开发环境对我个人而言稍显陌生。
显示屏:电子墨水屏(E-Ink)是唯一选择。它只有在刷新画面时才消耗电能,静态显示时功耗为零。我选用了一块1.54英寸、200x200分辨率的三色(黑、白、红)墨水屏。红色可以用来显示重要提醒或电量警告。关键点在于驱动方式:必须使用支持局部刷新的控制器,并且要大幅降低全局刷新频率。我设定为:每次按钮操作后局部刷新,每24小时进行一次全局刷新以消除残影。
电源管理:
- 电池:一枚CR2032纽扣电池。其标准容量约为220mAh。这是我们计算续航的基准。
- 电源路径设计:这是容易被忽略的细节。MCU和屏幕的供电不能直接接电池,中间需要一道低压差稳压器(LDO)。我选择了TPS7A02,它在轻负载下的静态电流仅25nA,几乎可以忽略不计。同时,必须在LDO的使能引脚(EN)上做文章,由MCU的一个GPIO控制。当MCU进入深度睡眠前,会拉低这个GPIO,彻底关闭LDO,切断除MCU自身RTC和唤醒电路外所有外围器件的供电,实现真正的“断电”。
外围电路:所有不用的GPIO口必须在软件中设置为模拟输入模式(上拉/下拉电阻关闭),这是STM32低功耗配置的基本功。连接按钮的GPIO配置为外部中断唤醒模式,并启用内部上拉电阻,省去外部电阻。
2.3 软件架构:沉睡的艺术
软件的逻辑不再是“运行-等待”,而是“唤醒-处理-沉睡”。
// 伪代码逻辑示意 void main() { hardware_init(); // 初始化时钟、GPIO、RTC、屏幕 display_welcome(); // 上电显示一次logo while(1) { enter_STOP_mode(); // 进入STOP模式,电流<1μA // 程序在此停止,等待中断唤醒 // 被唤醒后(按钮中断或RTC闹钟中断) if (wakeup_source == BUTTON) { handle_button_press(); // 处理按键,更新显示(局部刷新) } else if (wakeup_source == RTC_ALARM) { update_time_display(); // 每小时RTC闹钟唤醒,更新一次时间显示(局部刷新) } // 判断是否需要深度全局刷新(例如每24小时一次) if (need_full_refresh()) { perform_full_display_refresh(); } // 处理完成后,立即重新配置所有外设为低功耗状态,准备再次进入STOP prepare_for_sleep(); } }功耗估算与“10年”的可行性分析:
我们来做一个粗略的“信封背面”计算:
静态功耗(睡眠):MCU的STOP模式 + RTC运行 + LDO静态电流 ≈1.2 μA。
动态功耗(事件):假设每天用户按键操作10次,每次唤醒MCU全速运行(4MHz)处理50ms,电流约3mA。每小时RTC唤醒刷新一次时间,每次运行20ms。
- 按键日均能耗:10次 * 3mA * 0.05s = 1.5 mAs
- 定时刷新日均能耗:24次 * 3mA * 0.02s = 1.44 mAs
- 日均动态总能耗 ≈ 2.94 mAs
屏幕刷新功耗:局部刷新电流较大,假设每次10mA,持续2s。全局刷新每24小时一次,电流15mA,持续4s。
- 日均屏幕能耗:(10次按键+24次定时) * 10mA * 2s + 1次全局 * 15mA * 4s = 680 mAs + 60 mAs = 740 mAs
日总能耗估算:
- 静态:1.2 μA * 24h = 1.2e-6 A * 86400 s ≈103.7 mAs
- 动态:2.94 mAs
- 屏幕:740 mAs
- 合计 ≈ 846.64 mAs / 天
CR2032电池总容量:220 mAh = 220 * 3600 =792,000 mAs。
理论续航:792,000 mAs / 846.64 mAs/天 ≈935天,约合2.56年。
看,即使在这种极端简化的模型下,距离10年还有很大差距。我们的计算揭示了主要耗电大户:屏幕刷新。E-ink刷新时的高电流短脉冲,累积起来非常可观。要实现更长的续航,必须:
- 进一步减少刷新次数:能否将时间刷新从每小时一次降到每天数次?这牺牲了实用性。
- 寻找更低功耗的屏幕或驱动方案:有些段码式液晶屏(LCD)在加上反射式背板后,静态功耗也极低,且刷新电流远小于E-ink。
- 使用更大容量的电池:例如CR2450(550mAh),但会增大体积。
所以,“10年”在目前这个1.54寸E-ink方案下是一个理想化的目标,但它指引我们走向了功耗的极限。实际做出一个能稳定运行2-3年的“免维护”手表,已经是一个巨大的成功。这个计算过程本身,就是最有价值的经验。
实操心得:低功耗设计是一个系统工程,硬件选型是基础,软件策略是灵魂。一定要用万用表的电流档(μA级)实际测量各个状态下的电流,数据手册的参数是在理想条件下得出的。我实测发现,初期版本因为一个上拉电阻未禁用,睡眠电流多了5μA,这对纽扣电池来说是致命的。
3. 太阳能口袋收音机与天气站:环境能量的利用
如果说手表是在“节流”,那么这个项目就是在尝试“开源”。我想做一个完全由太阳能供电,能收听FM广播,同时也能显示当地天气信息的小设备。它应该像一个小巧的“生存工具”,在户外、停电时也能提供信息和娱乐。
3.1 系统架构与能量流设计
这个项目的核心矛盾在于:FM收音机和天气信息获取(需要网络)都是耗电相对较高的功能,而太阳能板在室内或阴天功率极低。解决方案是“间歇性工作”和“功能优先级”。
能量流核心:一块小尺寸的单晶硅太阳能板(例如5V 60mA)负责给一个小型锂聚合物电池(例如200mAh)充电,电池再为整个系统供电。主控MCU(依然选用STM32L0系列)持续监测电池电压。
工作模式:
- 模式A(能量充足):电池电压高于3.8V。设备全功能运行:每30分钟尝试通过Wi-Fi模块(如ESP-01S,仅在需要时上电)获取一次天气信息,并驱动一个低功耗的OLED或段码LCD显示;FM收音机功能可随时通过按钮开启。
- 模式B(能量警告):电池电压在3.5V-3.8V。关闭耗电的Wi-Fi天气获取功能,仅保留FM收音机功能和时钟显示。屏幕刷新率降低。
- 模式C(能量匮乏):电池电压低于3.5V。设备进入深度睡眠,仅维持RTC计时。所有外设断电,屏幕关闭。直到太阳能充电使电压回升到安全值以上。
3.2 关键模块的低功耗集成
FM收音机模块:选择了RDA5807FP这类数字芯片。它可以通过I2C控制,在待机模式下电流可以降到几μA。只有用户按下“收音机”按钮时,MCU才通过I2C唤醒它,并打开音频功放。音频输出使用一个微型扬声器,并在软件中设置默认音量较低以省电。
天气信息获取:这是最耗电的部分。ESP-01S Wi-Fi模块在工作时峰值电流可达70mA。策略是“快进快出”。
- MCU在需要获取天气时,才给ESP-01S的VCC引脚供电。
- MCU通过串口发送AT指令,控制ESP-01S连接预设的Wi-Fi(信息硬编码在MCU中,不安全但对于个人项目可行)。
- 连接成功后,向一个免费的天气API(如心知天气、和风天气)发送HTTP请求。
- 获取到JSON数据后,MCU解析出温度、湿度、天气状况图标代码,存入Flash。
- 立即断开Wi-Fi,并切断ESP-01S的电源。 整个流程必须优化到20秒内完成。获取一次天气,可供显示很长时间。
显示单元:为了在户外可见,放弃了OLED(强光下看不清),选择了一块反射式LCD屏,类似电子计算器那种,它需要背光时才耗电,显示内容本身不耗电。在白天,依靠环境光反射就能看清;在夜晚,可以手动开启背光(LED),此时会显著增加耗电。
3.3 太阳能充电电路设计要点
太阳能充电不是简单地把太阳能板接在电池上,那样会过充或无法充电。
我使用了一颗专为微小电流充电设计的芯片TP4056的改进方案。标准的TP4056适合500mA以上的充电电流,对于这种微型太阳能板(最大60mA)效率不高。我选择了BQ25570这类能量收集专用芯片,它具备最大功率点跟踪(MPPT)功能,能从低光照的太阳能板中榨取出更多电能,并且集成了超低功耗的升压和电池管理功能,非常适合本项目。
电路连接:太阳能板 -> BQ25570 (MPPT & 升压) -> 锂聚合物电池。BQ25570同时输出一个“电量良好”的信号给MCU,MCU据此判断系统可用的能量等级,决定进入哪种工作模式。
踩坑记录:最初我用的是TP4056,发现在阴天或室内灯光下,太阳能板输出电压低于电池电压,TP4056完全无法工作,设备很快就没电了。更换为BQ25570后,即使太阳能板只有2V电压,它也能将其升压到给电池充电的电压,系统在窗台上的存活能力大大增强。教训:对于环境能量收集,专用的能量收集管理芯片是必需品,不能省。
4. 怀旧风格桌面天气卡片:信息呈现的美学
第三个项目更偏向于装饰和静置信息显示。我想做一个看起来像老式收音机或仪表盘上镶嵌的“天气卡片”,放在书桌上,一眼就能看到温度、湿度和天气图案,风格要复古。
4.1 “怀旧感”的硬件实现
怀旧感来自材质、形态和显示方式。
外壳:使用胡桃木或深色亚克力激光切割出一个小相框的外壳。表面可以贴一层仿皮革纹理的贴纸,边缘做旧处理。
显示核心:依旧使用电子墨水屏,但这次选择一款较大的黑白屏,比如4.2英寸或7.5英寸。大屏幕可以显示更丰富的图形化信息。
显示内容设计:这是软件和艺术的结合。我使用Python + Pillow库在电脑上生成天气图片。
- 字体:选用复古的衬线字体,如Times New Roman或Courier。
- 布局:模仿老式电报或仪表盘的布局。温度数字可以做得很大,天气状况(如SUNNY, CLOUDY, RAIN)用文字标签。可以画一个简单的、线条式的天气图标(如太阳、云朵、雨滴)。
- 边框:在图片的边缘画上装饰性的刻度线或花纹。 生成一张960x540像素的黑白二值图,通过串口或SD卡传输到墨水屏显示控制器。
4.2 低功耗与网络同步策略
这个设备插在书桌上,可以由USB供电,但我依然想让它能独立工作。所以内部集成了一块小电池和Wi-Fi模块(如ESP8266)。
工作逻辑:
- 设备绝大多数时间处于深度睡眠,ESP8266和墨水屏控制器全部断电。
- 内置的RTC闹钟每2小时唤醒一次主控MCU。
- MCU唤醒后,给ESP8266上电,连接Wi-Fi,获取天气数据(流程同口袋天气站)。
- MCU将新获取的天气数据与Flash中存储的上一次数据对比。只有天气状况发生变化(如晴转雨),或者时间到了预设的强制刷新时间(如每天凌晨4点),才会启动墨水屏控制器进行刷新。
- 刷新完成后,MCU控制电源管理芯片,切断ESP8266和墨水屏控制器的供电,然后自己再次进入深度睡眠。
这样一来,在天气稳定的日子里,这块墨水屏可能好几天才刷新一次,耗电极低。电池仅用于维持RTC和应对偶尔的刷新操作,续航可以长达数月。USB供电则保证了永不断电。
4.3 软件上的“复古细节”
为了让体验更完整,我在MCU固件里加了一点小彩蛋。当设备启动或完成一次天气更新时,它会通过串口(如果连接了电脑)输出一段模拟老式电传打字机效果的信息:
[2023-10-27 14:30:00] SYSTEM BOOT... CONNECTING TO WX-SERVER... OK. FETCHING DATA... DONE. LOCAL: BEIJING CONDITION: SUNNY TEMPERATURE: 18 C HUMIDITY: 45% DISPLAY UPDATE... COMPLETE. ENTERING STANDBY.这种无用的“仪式感”,恰恰是DIY项目的乐趣所在。
个人体会:这个项目让我意识到,DIY的终点往往是“个性化”和“情感化”。技术指标(功耗、精度)是骨架,而美学设计和交互细节才是血肉。用一个复古的界面来显示现代的网络天气数据,这种时空交错的感觉非常奇妙。在调试时,我花了最多时间反而不是在电路上,而是在用Python调整字体间距和图标线条的粗细上,只为找到最“对味”的那一种感觉。
5. 三项目共通的深入问题与调试经验
把这三个项目放在一起做,我遇到了许多共性的挑战,也积累了一些跨项目的低功耗调试经验。
5.1 电源噪声与MCU异常唤醒
在太阳能收音机项目中,当太阳能板在树荫下(光照快速变化)时,电源电压会有微小的纹波。这导致了一个幽灵般的问题:MCU有时会莫名其妙地从STOP模式被唤醒,日志里显示是“非法唤醒源”。
排查过程:
- 最初怀疑是软件配置问题,检查了所有外部中断引脚,未发现异常。
- 用示波器观察MCU的供电引脚(VDD),发现在光照变化时,确实有几十毫伏的、频率不规则的毛刺。
- 根因:虽然BQ25570芯片输出已经比较干净,但为了进一步降低成本,我在其输出端只使用了一个10μF的陶瓷电容。对于对电源极其敏感的MCU低功耗模式来说,这不够。
- 解决方案:在MCU的VDD引脚最近处,增加一个1μF + 100nF的电容组合(分别滤除低频和高频噪声)。同时,在太阳能板输入端增加一个更大的电解电容(如100μF)作为缓冲。修改后,异常唤醒现象消失。
经验:超低功耗电路对电源纯净度的要求比普通电路高一个数量级。去耦电容的容量、类型和布局非常关键,必须严格按照芯片手册推荐,并预留调试余量。
5.2 电子墨水屏的“残影”与“鬼影”战斗
E-ink屏幕刷新时,如果波形不对或刷新不完整,会在新画面中留下旧画面的浅影,这就是“鬼影”。而长时间显示静态画面后,像素点会产生“残影”,即使刷新后也难以完全消除。
应对策略:
- 遵循官方刷新流程:必须严格按照屏幕驱动芯片手册的时序,进行“全刷”(Full Refresh)和“局刷”(Partial Refresh)。全刷耗时长、闪烁明显,但能彻底清除残影;局刷快、无闪烁,但多次局刷后会累积残影。
- 制定刷新策略:我的策略是,在显示内容变化不大时(如只变几个数字),使用局刷。但每进行N次局刷(例如32次)后,必须强制插入一次全刷。这个N值需要通过实验确定,在显示质量和功耗间取得平衡。
- “闪屏”的必要性:全刷时屏幕会先全黑再全白最后显示内容,这个“闪屏”过程是物理特性,无法避免。在软件上,可以尝试在深夜或设备无人看管时自动进行全刷,提升用户体验。
5.3 环境能量收集系统的“饥饿循环”
在太阳能口袋收音机项目中,最危险的系统状态是“饥饿循环”:电池电量低 -> 系统进入睡眠 -> 太阳能板在弱光下产生微量电能 -> 电量刚达到唤醒阈值,系统启动 -> 启动瞬间电流较大,导致电压被拉低 -> 系统复位或再次休眠 -> 如此循环,设备永远无法完成一次有效的工作。
解决方案:
- 设置硬件启动电压阈值:使用BQ25570这类芯片,它们有可配置的“电池欠压锁定”和“系统使能”电压阈值。将“系统使能”电压(VBAT_OK)设置得比MCU的最低工作电压高一些,确保系统只有在能量足够完成一次完整任务时才会被唤醒。
- 软件启动迟滞:在软件中,当MCU被唤醒后,首先不是立即执行任务,而是快速检测当前电池电压。如果电压仅略高于唤醒阈值,则MCU只进行最低限度的操作(比如记录一下日志),然后迅速返回深度睡眠,等待积累更多能量。只有当电压足够高时,才执行获取天气、刷新屏幕等耗电任务。
- 增加储能电容:在电池旁边并联一个法拉电容(如1F)。它可以提供瞬间的大电流,缓冲系统启动时的电压跌落,大大降低进入“饥饿循环”的概率。
这三个项目从构思到实现,断断续续花了近两个月的时间。它们没有改变世界,但极大地满足了我的技术探索欲和创造欲。最大的收获不是做出了某个可用的设备,而是在与μA级电流、变幻莫测的环境光、以及各种芯片的古怪脾气“斗智斗勇”的过程中,对“能量”和“信息”有了更物理层面的理解。当你看到一块小小的太阳能板在台灯下,就能让一个系统生生不息地运行时,那种感觉,比写出最优雅的代码更让人着迷。如果你也对硬件和低功耗感兴趣,不妨从一个简单的纽扣电池供电的LED闪烁实验开始,一步步挑战更长的续航时间,这个过程本身就是最好的教程。
