超长续航DIY:低功耗MCU与能量收集技术实战解析
1. 项目缘起当“长续航”成为执念作为一名玩了十几年开源硬件和DIY的“老鸟”我发现自己对“续航”这件事的执念越来越深。从早期的Arduino小车跑半小时就得换电池到后来各种物联网设备为了省电绞尽脑汁我逐渐意识到真正的“智能”和“便利”其根基是“无感”的能源供给。你不需要时刻惦记着充电设备就在那里默默工作这才是科技融入生活的理想状态。最近我手头正好有几个闲置的低功耗芯片、太阳能板和电子墨水屏于是萌生了一个想法能不能把几个关于“超长续航”和“环境信息”的脑洞做成一套可以实际把玩甚至日常使用的设备这就是标题里提到的三个小玩意儿一个目标是10年续航的“伪”智能手表、一个靠太阳能驱动的口袋收音机/天气站以及一个怀旧风格的桌面天气卡片。它们的技术核心高度一致——极致的低功耗设计与环境能量采集。这不是商业产品的复刻而是一次关于功耗边界的工程探索看看用最普通的元件续航的极限能到哪里。2. “10年续航”智能手表概念与现实的碰撞“10年续航智能手表”听起来像是个营销噱头但在DIY的语境下我们追求的是无限接近这个目标。它不是一个功能齐全的智能手表而是一个高度特化的“信息看板”。2.1 核心定位与功能取舍商业智能手表续航短根源在于其“全天候感知”与“实时交互”的设计常亮的触摸屏、持续的心率监测、蓝牙连接、频繁的消息推送。我们要反其道而行之。我的设计目标是一块只显示最基本信息时间、日期、通过物理按钮交互、仅在需要时刷新的设备。它更像一块电子怀表或者一个戴在手腕上的“日程提醒器”。核心功能规划如下主显示时间、日期、星期。次级功能通过按钮切换简易计时器、自定义文字提醒如“多喝水”。交互两颗物理按钮模式切换、内容切换/确认彻底抛弃触摸屏。连接无蓝牙无无线连接。时间校准通过USB连接电脑完成一年可能只需要一次。2.2 硬件选型一切为了μA级待机硬件的每一个选择都直接决定了最终的功耗基线。主控MCUTI 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。使用更大容量的电池例如CR2450550mAh但会增大体积。所以“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同时输出一个“电量良好”的信号给MCUMCU据此判断系统可用的能量等级决定进入哪种工作模式。踩坑记录最初我用的是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闪烁实验开始一步步挑战更长的续航时间这个过程本身就是最好的教程。