ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

ESP32墨水屏手表低功耗实战:Deep Sleep+RTC唤醒实现7天续航

ESP32墨水屏手表低功耗实战:Deep Sleep+RTC唤醒实现7天续航 做墨水屏手表这个念头多半是从“墨水屏省电”四个字开始的。静态显示不耗电、阳光下看得清、还有一种纸质手表的质感听起来太适合手表了。但真把ESP32和墨水屏拼到一起很多人会碰到一个尴尬局面屏幕上时间确实显示得很漂亮电池却肉眼可见地往下掉一个星期都撑不到更别提那些“几个月不充电”的美好想象。问题出在哪其实不在墨水屏而在主控。ESP32虽然性能强、上手快却是出了名的“能吃电”如果让它一直醒着待机哪怕不刷屏电流也是几十毫安级别电池当然扛不住。这篇文章要讲的就是一套用硬件级休眠、配合RTC唤醒来抠续航的实战方案——最终在150mAh电池下跑出7天续航。如果你正在做低功耗手表、桌面气象站、电子价签这类设备或者家里还有一堆吃灰的ESP32想榨干最后一滴电这篇应该能给你一些直接抄作业的思路。1. 这个项目到底在解决什么问题1.1 墨水屏并没有解决所有省电问题先说个容易被带偏的认知墨水屏省电指的是“显示”阶段几乎不耗电。墨水屏属于双稳态显示器件屏幕上那些小墨滴一旦被电场推到指定位置即使完全断电画面也能保持住。这跟LCD背光常亮、OLED像素自发光完全是两码事。所以很多人第一反应是我把屏幕换成墨水屏手表的耗电问题不就解决了吗真去做了才发现完全不是那么回事。墨水屏省的是“显示”的电但主控芯片还得一直跑着。ESP32哪怕不连Wi-Fi、不刷屏光是在循环里空转电流就是30到50mA如果还开着Wi-Fi等着联网对时瞬时功耗能冲到150mA以上。这种状态下一块150mAh的小锂电池半天就见了底。换句话说把屏幕从LCD换成墨水屏只是在省电这条路上解决了一半问题另一半问题——主控怎么活——才是真正的硬骨头。我当时拆解整个系统的功耗发现时间轴上有三个大头刷屏瞬间、唤醒后的初始化过程、以及睡眠期间的漏电。前两个是必要开销砍不掉太多但第三个是可以优化到极致的。整块手表真正需要“醒着”的时间其实只有刷屏那一两秒钟剩下99%的时间屏幕都是静置显示ESP32完全没必要通电。于是整个项目的核心思路就变成了一句话让芯片在没活干的时候彻底睡死到点再自己醒过来干完活继续睡。1.2 ESP32到底有多“耗电”坦白讲ESP32不是做低功耗设备的第一选择。业内做低功耗手环、传感器节点通常首选nRF52系列或者MSP430休眠电流能到μA级别甚至更低。但现实问题是很多人手里最多的开发板就是ESP32Arduino环境熟资料多再加上墨水屏驱动库随手就能用没必要为了一个手表项目再买一套新工具链。那ESP32到底有多“耗电”分几种状态看正常运行CPU跑着没连Wi-Fi30~50mAModem SleepWi-Fi/蓝牙关闭CPU运行20~30mALight SleepCPU暂停外设暂停0.5~1mA左右Deep Sleep大部分电路断电只留RTC最低能到10μA以内前三种状态放手表上都是灾难真正能用的只有Deep Sleep。好消息是ESP32的Deep Sleep做得相当彻底只要配置正确功耗完全可以压到两位数μA。这也就意味着续航的钥匙不在“换芯片”而在“学会休眠”。1.3 续航目标怎么定做任何低功耗项目第一步不是写代码而是算账。先把目标定下来反推每个环节允许的电流窗口否则就是盲人摸象。我当时定的参数很简单电池150mAh锂聚合物电池目标续航7天两者一除平均电流预算大约是0.89mA这个0.89mA是全部开销包括睡眠漏电、唤醒后的活跃电流、刷屏功耗、LDO静态损耗甚至电池自己放掉的电。长期目标一定要定得比预算更保守一点比如按0.7mA去设计留出裕量。这样一天下来实际耗电约17mAh7天约120mAh电池容量还剩一点余量不会跑到亏电。有了这个预算后面每个环节就有依据了睡眠电流必须压到20μA以下每天刷屏次数不能太密唤醒后的初始化代码必须精简LDO不能选静态电流大的型号。每一条决策都可以回到这个预算上验证。这就是工程化做低功耗和“碰运气式”改代码的核心区别。2. 硬件级休眠把ESP32变成“能睡死过去”的芯片2.1 四种睡眠模式谁才是续航的关键ESP32的睡眠模式经常被混着说新手很容易搞混。实际上一共分四档模式谁还活着唤醒方式典型电流Active全部-30~200mAModem SleepCPUWi-Fi/蓝牙关闭定时器/中断20~30mALight SleepCPU暂停RTC外设常开定时器/GPIO/触摸0.5~1mADeep Sleep仅RTC域和ULP协处理器RTC定时器/EXT0/EXT1/触摸/ULP10~100μA大多数教程把重点放在Light Sleep和Deep Sleep的代码区别上但我更关注的是“硬件级”这三个字。Light Sleep只是把CPU时钟停了整个芯片还在低压供电RTC外设、一部分SRAM都在工作1mA虽然比运行状态低了一个数量级对手表来说还是太高。只有Deep Sleep会把主系统电源域直接切断CPU、内存、大部分外设全部失电只留下RTC域那一条小血管维持心跳。唤醒后芯片并不是“恢复现场”而是像重新开机一样走一遍启动流程只是保留了RTC内存里的一点数据。这个特性特别重要决定了代码该怎么组织你不能指望原来栈上的变量还在所有关键状态都得显式存到RTC内存里。2.2 用代码让芯片进入深度睡眠Arduino环境下进入Deep Sleep的代码短得让人意外#define TIME_TO_SLEEP_SEC 60ULL void setup() { // 初始化外设、刷屏、然后…… esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP_SEC * 1000000ULL); esp_deep_sleep_start(); }esp_deep_sleep_start()一旦调用芯片会直接断电下面不会再有代码执行。等唤醒后整个芯片会从setup()第一行重新开始跑——对Arduino框架来说Deep Sleep本质上就是“断电重启”只不过RTC域还留着计时器和少量内存。这跟很多人想象中的“暂停继续”完全是两码事刚上手的时候可能会被这个行为迷惑调试以为变量丢了其实只是没存对地方。关于时间单位这里有个经典坑esp_sleep_enable_timer_wakeup的参数是微秒不是毫秒而且底层是64位数值。60秒就是60 * 1000000ULL后面的ULL不能省。如果你写成60 * 1000芯片每60毫秒就醒一次刷屏电流直接让续航崩盘。我见过不止一个人在这行代码上栽跟头。2.3 睡眠时GPIO和外设的处置Deep Sleep期间CPU已断电但GPIO引脚并不全部保持原状。ESP32的引脚分成RTC GPIO和普通GPIO两类普通GPIO在Deep Sleep里状态不受控可能出现浮动RTC GPIO可以通过esp_deep_sleep_gpio_reset或gpio_hold_en保持关机前的电平。实战里不要指望这些机制最稳妥的办法把所有外设的电源彻底关掉。我的方案是给墨水屏模块、传感器、气压计每个外设都单独加一颗MOS管负载开关比如AO3401做高端P-MOS用GPIO控制栅极。进入睡眠之前把外设电源脚拉高关闭P-MOS栅极低电平导通高电平断开再把I2C总线的SCL/SDA拉低防止悬空导致传感器处于半供电状态。这样即使某个外设有漏电也只会出现在睡眠前的最后一次GPIO配置里不会在整个睡眠周期内持续消耗电池。注意系统卷写的“省电”不是让代码里少干点活而是让没必要的电路直接断电。凡是睡眠时不需要工作的芯片都要保证它一点电都吃不到。这是硬件级休眠和软件调优最大的区别。3. RTC唤醒让手表在指定时间自己醒来3.1 RTC域是什么为什么它还能醒Deep Sleep这么彻底那怎么定时醒过来靠的就是RTC域。ESP32的RTC域是一块独立的小供电区域主电源域断电时它还在运行里面有RTC定时器、RTC GPIO、触摸传感器、ULP协处理器还有一小块RTC内存。这颗“永不熄灭”的小芯片就是整个低功耗系统的秒表。RTC定时器本质上是一个计数器以RTC慢速时钟通常是外部32.768kHz晶振没有则用内部ROM RC振荡器为基准计数。配置好目标时间后计数器到达设定值会产生一个唤醒事件把芯片电源重新打开。对7天续航的手表来说这个定时器就是“闹钟”负责在每分钟或每小时准点把人叫起来干活。要注意的是如果板子没有外部32.768kHz晶振用的是内部RC振荡器它的精度大概在±5%左右换算成一天可能差几分钟。手表这种对时间敏感的设备长期跑下去靠内部RC漂移会很夸张后面我会专门讲怎么解决。3.2 定时器唤醒和外部唤醒怎么搭配手表不能只有定时闹钟还得处理按键、翻腕这类即时事件。ESP32唤醒源有几种定时器唤醒到点自动醒适合刷时间EXT0唤醒一个RTC GPIO从指定电平唤醒EXT1唤醒多个RTC GPIO任意一个满足条件唤醒触摸唤醒RTC触控引脚检测到触摸ULP唤醒协处理器监测到特定条件我的实际组合是定时器负责周期性刷屏EXT1接按键和加速度计中断。翻腕时加速度计产生中断信号把芯片从Deep Sleep里叫醒执行快速亮屏墨水屏其实不用亮屏就是立即刷一次时间按按钮则翻页显示秒表或日历。两种唤醒源可以同时启用所以不存在冲突。EXT1代码示例esp_sleep_enable_ext1_wakeup( GPIO_SEL_33 | GPIO_SEL_32, ESP_EXT1_WAKEUP_ANY_LOW );这里用的是“任一引脚拉低就唤醒”。注意EXT1不能指定具体引脚状态只能是“集合里的任意引脚”所以唤醒后要自己轮询判断到底哪个引脚被触发。如果只有一颗按键用EXT0更简单但EXT0只能用RTC GPIO选引脚的时候要对着芯片手册确认。3.3 唤醒原因判断与RTC内存唤醒后第一件事不是刷屏而是搞清楚自己为什么醒的。主动刷屏、按键唤醒、误触发三者的处理方式完全不一样esp_sleep_wakeup_cause_t cause esp_sleep_get_wakeup_cause(); switch (cause) { case ESP_SLEEP_WAKEUP_TIMER: // 定时器到点更新时钟显示 refresh_time_only(); break; case ESP_SLEEP_WAKEUP_EXT1: // 按键或手势唤醒 if (digitalRead(KEY_PIN) LOW) { next_page(); } break; default: // 不明原因什么都不做直接睡回去 break; } refresh_time_only() 里刷完屏立刻调用 esp_deep_sleep_start()不要做任何多余的事情。为什么说default分支也要保留因为ESP32某些电源波动、调试器连接、甚至GPIO毛刺都可能导致意外唤醒。如果不做处理芯片会莫名其妙地醒了又睡、睡了又醒每一次唤醒都伴随一段开机电流日积月累对续航的损害相当可观。我实测过多一次无意义的唤醒平均功耗就损失大约0.02mA一天多几十次续航直接少一天。跨睡眠周期保存数据用RTC_DATA_ATTR宏RTC_DATA_ATTR int page_index 0; RTC_DATA_ATTR uint32_t last_boot_count 0;这些变量存放在RTC内存里Deep Sleep期间不会被清掉重新开机后依然有效。普通全局变量在Deep Sleep后全部归零因为内存断电了。我当时犯过一个低级错误把时间戳存在普通全局变量里醒来后看到的全是0折腾了很久才发现应该用RTC_DATA_ATTR。这种问题在调试时尤其诡异因为你看上去代码逻辑完全正确。提示RTC_DATA_ATTR 变量不会像普通变量那样在每次启动都初始化它只在上电/硬复位时清零。如果你在程序里给它赋了初值从Deep Sleep唤醒时这个初值赋值不会生效保留的是上次写入的值。这个特性既是坑也是宝用好了可以省掉很多状态保存代码。4. 墨水屏不能只当屏幕用还要当功耗管理的一部分4.1 墨水屏怎么看功耗墨水屏的省电逻辑跟大众直觉不太一样。它省的是“静态显示”的电而不是“刷新”的电。刷新墨水屏时要在像素两端的电极上按压差把墨滴从白色推到黑色或者反过来这个过程需要十几伏甚至几十伏的驱动电压所以屏幕上要有一颗升压芯片刷屏瞬间的电流通常在20到50mA。刷完之后像素保持住这时候即便断开屏幕电源画面也不会消失。用生活的话说墨水屏像墙上贴的便利贴贴上去要花点力气但贴好之后你站在那里看多久都不费电。所以省电的核心策略很明确屏幕刷得越少越好刷完就立刻让屏幕和驱动电路断电。我做的是1.54寸墨水屏分辨率为200x200来自合宙那款经典模块。整屏刷新一次大约需要2秒左右电流峰值40多mA局部刷新快得多大约0.3~0.5秒但残影严重。所以手表这种界面最合适的策略是大部分时间只更新数字区域做局部刷新每天固定一次整屏刷新清掉残影让字体保持干净。4.2 刷新策略决定续航下限刷屏次数是续航账本上的最大变量。直观算一下每小时刷1次一天24次每次刷屏加上唤醒初始化的总耗电按0.02mAh算2秒x平均40mA / 3600 0.022mAh一天约0.48mAh每5分钟刷1次一天288次同样算法一天约6.4mAh同样是墨水屏手表刷新频率不同续航差出十几倍。所以续航目标定下来之后刷新频率基本就被锁死了要想7天续航每天刷屏总电量不能超过1mAh也就是最多刷40~50次整屏。我最后折中选择了整屏每小时刷一次平时显示静态时间按键翻页时才局部刷新秒表。还有一个容易忽略的点显示内容尽量别全屏闪烁。墨水屏驱动库里会有“刷新时画面先反色再恢复”的动画效果手表上这种翻转动画非常耗电而且没有必要。要关闭全刷时的中间过渡帧直接走干净的驱动波形。驱动库一般都有参数控制找不到就改代码跳过中间调色步骤。4.3 把墨水屏的电源彻底断掉很多人的设计是墨水屏模块直接接在3.3V上Deep Sleep时主控断了电但屏幕还挂在电源轨上。这其实有两个隐患。第一墨水屏驱动板上有一颗升压芯片和电平转换电路即使不刷新只要VCC有电驱动芯片就是在工作的静态电流虽然不高几十μA但乘以24小时一天也吃掉0.5~1mAh直接吃掉续航预算一大块。第二如果屏幕数据线悬空可能出现总线浮空导致的寄生刷新轻则闪屏重则烧升压芯片。我的做法是屏幕VCC通过一颗AO3401 P-MOS管控制GPIO控制栅极平时断开每次刷新前先把屏幕电源打开延时50ms等驱动芯片稳定再初始化并刷屏刷完立即关闭电源。代码套路如下void power_screen(bool on) { digitalWrite(SCREEN_PWR_PIN, on ? LOW : HIGH); // P-MOS低电平导通 delay(on ? 50 : 10); }显示保持阶段靠的是墨水屏的双稳态特性跟驱动板有没有电毫无关系。VCC断掉后显示内容依然清晰但整颗模块一点电都不吃。这个细节是整个项目能把平均功耗压到1mA以内的关键一步。5. 实测功耗与续航推算7天是怎么算出来的5.1 测量工具与测法光靠理论计算还不够必须实测。我当时用的工具分三个级别。第一日常快速测量用万用表串联电流档量程选mA档不要选μA档因为μA档内阻很大睡眠电流本身只有几μA串进去之后会产生分压导致测出来的电流值偏低、状态异常数据失真。第二想要精确记录唤醒脉冲用INA219或INA226电流监测模块接I2C配合另一块开发板做主机记录采样率调到最高这样能抓到整个唤醒周期从上升到刷屏再到跌落的电流曲线。第三想看波形细节的话在电源回路里串一个0.1Ω采样电阻示波器测电阻两端电压再除以阻值就是电流。特别注意一点测量Deep Sleep电流时要等芯片完全进入睡眠状态通常要在调用esp_deep_sleep_start()后等3秒以上再读数因为引脚放电、外设关断有延迟很多人一调完就盯着万用表看读数偏高误以为是自己优化不到位。5.2 实测数据长什么样我调完一轮后拿到的实测数据大致如下状态实测电流说明Deep Sleep仅RTC定时器8.2μA外设全部断电GPIO全部下拉Deep Sleep含触摸唤醒使能约20μA触摸灵敏度开到高档会略多吃电唤醒初始化读RTC约25mA持续80ms主要是电源域重新上电的浪涌整屏刷新200x200平均38mA持续2s峰值能到45mA局部刷新时间数字区域平均25mA持续0.4s省电效果非常明显用这些数字去算每天的平均功耗才有意义。拿我做调试的那版配置来算账每小时整屏刷新1次一天24次单次2秒平均38mA24 × 2s × 38mA / 3600 0.51mAh每天偶尔按键翻页按额外刷20次局部刷新每次0.4秒x25mA20 × 0.4s × 25mA / 3600 0.056mAh睡眠漏电24小时 × 8.2μA 0.197mAh0.0082mA × 24h 0.197mAh唤醒时的初始化浪涌每次唤醒大约0.1mAs一天40次 4mAs / 3600 0.001mAh几乎忽略再加上LDO静态电流选了个2μA的和DIY板子上一些漏电按0.1mAh一天估四项加一起一天的合计功耗大约是0.86mAh。用150mAh电池算150 / 0.86 ≈ 174天看起来夸张但那是每小时刷一次的方案如果追求更好的观感改成每5分钟刷新一次每天288次单日功耗直接跳到6.9mAh续航只剩22天左右。而且实际使用还有电池自放电、老化、低温按打六折算7天续航非常稳妥。这也是“抠出7天续航”这句标题的由来——不是靠单个天才操作而是每个环节都节约十几mA的累积结果。5.3 代码层面的“醒来之后立刻睡回去”原则还差一块看不到的省电大蛋糕唤醒后到再次沉睡之间的处理时间。很多人的逻辑是既然醒都醒了就顺手把传感器读一遍、把数据算一遍、把界面整理一下结果芯片在几十毫安的电流下白白跑了十几秒甚至几十秒。这些时间攒起来一天很可能多出几mAh的消耗。我的铁律是唤醒后只做“必须做的事”。定时唤醒就只刷新时间不做任何额外处理按键唤醒就翻一页不超过三个函数调用如果唤醒原因不明连屏都不刷直接睡回去。要实现这个需要在setup()里用最短路径分流而不是把所有初始化都跑一遍。比如把I2C初始化、外设驱动加载这些耗时操作放到一个init_all()里只有当检测到最近一次唤醒原因是按键时才执行定时器唤醒则只初始化墨水屏GPIO和UART打印时间戳其他模块一律不碰。实测这样优化后每次定时唤醒从20mA×5秒约0.028mAh降到了38mA×2秒的刷屏电0.021mAh一天下来又能省出约0.17mAh。看似不起眼但对低功耗项目来说每一μA都是积少成多。6. 采坑记录与工程化方法从能跑到跑得久6.1 电池电压监测和分压电阻的漏电问题手表得有电量显示。锂电池电压范围大约3.0V到4.2VESP32的ADC参考电压是3.3V直接测电池电压会超量程必须分压。最常见的方案是两个电阻分压然后接ADC引脚。但这里有一个被绝大多数人忽略的低功耗陷阱分压电阻在睡眠期间一直通电两个典型100kΩ100kΩ的电阻2.5V电池电压下就是12.5μA的漏电比整个芯片的Deep Sleep电流还大。辛辛苦苦压到8μA结果被两颗电阻全毁掉。解决办法是把分压电阻的地端接到一个GPIO控制的地开关上或者用一个P-MOS管控制分压电路的通断。只在唤醒后开机测量时打开分压电路测量完毕立刻关掉。测量时用ADC多次采样取平均等电池电压稳定后立即关闭然后读到的值再用于点亮屏幕上的电量图标。6.2 LDO待机电流是续航的第一杀手很多DIY玩家喜欢用现成的AMS1117-3.3V降压模块这东西便宜、到处有卖但静态电流高达5mA左右。换句话说就算ESP32睡死到几μA整块板子还在被LDO额外抽着5mA的血一天什么都不干就吃掉120mAh续航直接归零。这个坑太深了可以说是低功耗项目翻车的第一原因。换一颗静态电流小的LDO就立竿见影。我当时用的是HT7833静态电流2μA在淘宝上几毛钱一颗输出能力300mA足够带动ESP32和墨水屏刷新。如果你的电池电压在3.3V以上也可以考虑直接让电池给ESP32的VIN供电开发板上的3.3V LDO只给逻辑芯片用进一步降低损耗。但注意ESP32的供电电压范围是2.3V到3.6V直接电池供电的话电池电压到4.2V时已经超了上限所以要么加LDO要么选带使能引脚的DCDC。提示市面上很多“ESP32手表”方案其实是用开发板改的板载的USB转串口芯片如CH340、CP2102在睡眠时也在工作静态电流几百μA到几mA不等。量产手表必须把USB芯片拆掉或者设计成不用它否则续航永远上不了台面。我测试过拆掉CP2102之后整机睡眠电流从700μA直接降到20μA以下差别就这么大。6.3 I2C传感器复位休眠后被锁死的总线手表里如果接了温湿度传感器比如SHT30、HDC1080这类会遇到一个特别恶心的问题每次Deep Sleep唤醒后I2C总线可能直接锁死读取永远返回失败。原因在于传感器在睡眠期间被动断电了但I2C引脚还挂在ESP32上如果ESP32的引脚输出高电平就可能通过总线给传感器供电导致传感器进入“半上电”状态或者传感器内部状态机卡在一个错误时序里正等着一个停止条件才能恢复。这时候单纯重新初始化I2C没用因为SCL和SDA的电平不对它一直在那个错误循环里。我的解决方法是唤醒后如果发现I2C通信失败把手动复位函数跑一遍。先复用I2C引脚为普通GPIO把SCL和SDA都拉高然后做了9次时钟翻转再发一个停止信号最后重新初始化I2C。这套操作基本能把绝大多数传感器从锁死状态救回来。代码大概长这样void reset_i2c_bus() { pinMode(SDA_PIN, OUTPUT); pinMode(SCL_PIN, OUTPUT); digitalWrite(SDA_PIN, HIGH); digitalWrite(SCL_PIN, HIGH); for (int i 0; i 9; i) { digitalWrite(SCL_PIN, HIGH); delayMicroseconds(5); digitalWrite(SCL_PIN, LOW); delayMicroseconds(5); } digitalWrite(SCL_PIN, HIGH); digitalWrite(SDA_PIN, HIGH); Wire.begin(); }这套代码在我的SHT30上屡试不爽。从那以后我的所有低功耗I2C项目都会默认带上这几十行复位代码作为硬防坑机制。6.4 RTC时间的精度与补偿最开始我直接用ESP32内部RTC来计时每天晚上跑完一天下来实际时间和标准时间能差出几分钟戴在手上当手表根本没法用。原因在于开发板普遍不带外部32.768kHz晶振内部RC振荡器受温度和电压影响非常明显。解决思路有三条路外接RTC芯片如DS3231自带温度补偿晶振精度极高但多了一颗芯片的功耗除非你选择低功耗版本否则就要权衡电量和精度用ESP32的外部32.768kHz晶振引脚不少定制的PCB上会预留精度比内部RC高一个量级一天误差大概只有几秒定期对时手表在充电时开一次Wi-Fi用NTP协议同步时间。这是最省电的方案——充电时本来就不担心功耗同步完后继续用内部RC跑接受它每天跑慢几分钟的误差但至少能在下一次充电前保持“能看”的状态我最后选的是第三套方案充电时联网对时日常跑内部RC。每次启动时读RTC时间再乘以一个从上次对时到现在经过的秒数做一个线性漂移补偿。效果就是7天里误差控制在30秒内虽然不够精准但对日常手表应用足够了。如果你对时间精度要求苛刻比如做打卡机、计时器那就上DS3231省不了那个电。6.5 按键消抖与快速回睡EXT1唤醒之后最怕的就是GPIO抖动导致误判定。墨水屏刷新一次要2秒按一次键只为了翻页如果因为抖动连续翻了两页或者误唤醒后刷新了一次一天下来白白吃掉好几mAh。我给按键做了软件消抖唤醒后读取按键状态如果确认拉低延时20ms再读一次两次都为低才认定为有效按键否则直接回到睡眠。睡眠钱都算到毫安时了几毫秒的延时也值得抠。另外如果用了加速度计做翻腕唤醒注意加速度计的中断引脚在睡眠前要配置成上升沿或下降沿触发而且得选择RTC GPIO才能作为唤醒源。我当时用了MPU6050的INT引脚接到ESP32的GPIO_NUM_33在Deep Sleep前设置esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0)翻腕时中断脚拉低唤醒芯片醒来后我再只做一次快速局部刷新整个过程不到400ms又省又灵敏。做这个项目最大的感受是续航不是某一颗芯片或者某一个函数的功劳而是整个系统里每一毫安都被抠出来的结果。每一处细节——LDO选型、分压电阻通断、唤醒后别跑多余代码、屏幕刷完就断电——单独看好像都只是几μA的改进堆在一起就把150mAh的电池跑出了7天。最后再分享一个小技巧把每天的唤醒总数和平均睡眠电流实时打印到墨水屏的开发者调试页里哪怕只是一个小角落它也能帮助你立刻发现哪几天的唤醒数异常偏高。毕竟低功耗这种东西看不见就没法管理只有把它量化出来你才有机会把它压得更低。
返回列表