尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

ESP32低功耗锂电池电量检测:从分压电路到固件算法全解析

发布时间:2026/9/25 1:22:44

资讯中心
01
ARTICLE

ESP32低功耗锂电池电量检测:从分压电路到固件算法全解析

ESP32低功耗锂电池电量检测:从分压电路到固件算法全解析
我见过太多做ESP32项目的朋友第一版样机都能跑一到“电池电量显示”这里就翻车要么读数挂着一串乱跳的数字要么满电显示50%更常见的是设备睡了一晚上第二天电池就没电了。这些问题背后其实不是某一个环节出错而是从测量点选择、分压电路设计、ADC引脚配置到低功耗这一整条链路都没理顺。今天我把做过的一个低功耗锂电池电量检测方案从头到尾拆开讲一遍包含引脚选择、完整接线关系和固件算法给正在做ESP32锂电池项目的你一个可以直接抄作业的参考。1. 直接测3.3V引脚先把电压测量点和系统电压的关系搞清楚很多人习惯把锂电池接到ESP32开发板的3.3V引脚上然后打算用ADC去读这个引脚的电压。这个思路有两个致命问题第一锂电池满电4.2V直接进3.3V引脚会烧模块第二就算你接对地方测出来的电压也不能直接代表电池剩余电量。要理解为什么得先看锂电池和ESP32供电之间的关系。1.1 锂电池电压范围与ESP32供电要求常见的3.7V锂聚合物电池和18650电池实际电压范围是3.0V到4.2V。满电时约4.2V标称电压3.7V放电截止电压一般在3.0V到3.3V之间具体取决于保护板设定。也就是说电池电压在3.0V以下时保护板会直接切断输出这时候你测到的不是电池电压而是0V。ESP32模组的工作电压范围以ESP32-WROOM-32为例官方标注是3.0V到3.6V。这就出现一个很尴尬的区间电池在满电4.2V时超过了ESP32最高允许电压不能直接供电电池放到3.4V以下时虽然电池本身还有电但已经接近ESP32的最低工作电压边缘系统随时可能掉电。所以ESP32用锂电池供电中间必须经过稳压或者降压不能拿电池电压直接怼上去。很多开发板上用的是AMS1117-3.3稳压芯片这个东西的压差dropout voltage大约在1V左右就意味着输入电压至少要4.3V以上才能稳定输出3.3V。锂电池4.2V满电时勉强能用一旦放到3.9V以下AMS1117输出就开始往下掉WiFi一开电流一大模块直接重启。这就是为什么那么多用NodeMCU-32S开发板接锂电池的项目总是出现“电压一低就反复重启”的诡异现象。不是固件问题是稳压芯片选错了。1.2 为什么不能在3.3V引脚测电池电压退一步说就算你用的是裸模组或者低压差LDO的方案也不能在3.3V输出引脚上测电压。因为3.3V是稳压后的电压只要LDO还在正常工作范围内输出基本恒定在3.3V附近电池电压从4.2V降到3.6V3.3V输出可能只从3.32V变成3.28V分辨率极差根本无法反映电池剩余电量。正确的测量点只有一个电池经过保护板之后的直接输出端。这个点的电压才是真实的电池电压它随电量的变化才有意义。测量点和供电支路要分开设计供电支路经过稳压给系统用测量支路单独引出到ADC采样电路。这个原则虽然简单但直接决定后面所有算法能不能工作。2. 方案选型分压电阻方案与电量计IC方案怎么选确定测量点之后下一步是选采样方案。目前主流做法就两种高阻值电阻分压直接采ADC或者用电量计IC通过I2C读电量。我两个方案都在实际项目里用过这里把利弊全部摊开说。2.1 分压电阻方案的原理和开销ESP32的ADC输入范围是0到3.3V在11dB衰减档位下理论上限约3.1V而锂电池最高4.2V已经超了。所以需要两个电阻组成分压器把电压按比例缩小后送进ADC。比如两个100K电阻串联分压比就是1/24.2V变成2.1V3.0V变成1.5V全程落在ADC的安全线性区内。用100K级别的电阻而不是10K甚至1K是为了降低静态功耗。两个100K串联在4.2V下流过整个分压回路的电流是4.2V除以200K约等于21uA。这个电流看着不大但在低功耗设备里就是一笔不能忽视的开销。如果换成1M1M电流降到2.1uA但代价是ADC采样误差变大这个问题我在第3节详细讲。分压方案的成本几乎可以忽略两个贴片电阻几分钱不依赖任何专用芯片电路设计也简单。缺点是它只能测电压无法区分电池内阻、老化程度、负载电流这些因素所以精度上限通常在3%到5%左右。对大多数物联网传感器节点、遥控器、小屏幕显示设备来说这个精度完全够用。2.2 电量计IC方案的取舍电量计IC是另一种路线常见的有MAX17048、BQ27441、国产CW2015。这些芯片内部集成了电压检测、库仑计或者基于电池模型的估计算法通过I2C接口直接输出电量百分比。以MAX17048为例它自身静态电流只有3uA左右比分压电阻还省电精度能做到1%到2%。听起来电量计IC完胜但实际工程里有几个坑。第一是成本一颗MAX17048零售价十几块BQ27441更贵对于几十块钱的DIY项目来说成本占比太高。第二是配置库仑计芯片需要烧录电池容量、化学特性等参数换一种电池就要重新配置模型类芯片虽然不用标定容量但启动时长和初始化流程比纯ADC复杂得多。第三是焊接这些芯片很多是BGA或者极小封装的DFN手工焊接难度大不是每个人都有热风枪。2.3 我的建议什么时候用哪个直接给结论做产品、批量出货、预算充足用电量计IC省心且用户感受好。但做DIY项目、学生竞赛、开源硬件、传感器节点老老实实用分压电阻方案。以ESP32的ADC精度配合多点校准完全能满足“显示百分比、低电量报警”这类需求。本篇文章后面所有内容都围绕分压电阻方案展开因为这是门槛最低、最容易复现的做法也是把工程细节讲清楚的最好载体。等你看完分压方案的坑再去看电量计IC的datasheet会顺畅很多。3. 电路设计实操分压计算、引脚避坑与完整接线方案定了开始画电路。这一节是最容易踩坑的地方我从阻值计算、引脚选择、完整接线表、供电设计四个方面把细节全部过一遍。3.1 分压电阻怎么算才合理分压器的核心公式就是V_adc V_bat * R2 / (R1 R2)。选100K100K的对称结构分压比0.5计算简单容易校准。关键问题是能不能为了省电把阻值加大到1M甚至2M这里必须理解ESP32的ADC输入结构。ESP32的ADC不是理想的电压表它的采样本质是开关电容采样瞬间会从外部电路抽取电荷。官方资料给出的ADC等效输入阻抗大约在几十K到几百K的范围内具体数值和衰减档位、采样保持时间有关。当分压电阻只有100K时这个输入阻抗对分压点的影响还比较小一旦分压电阻升到1M级别ADC采样时的电流就会明显拉低分压点电压导致读数比实际值低一大截而且不是线性偏移越到高电压区偏差越大。我曾经用2M2M做过一个低功耗方案想着把漏电流压到1uA实测3.9V的电池电压程序读回来只有3.5V左右差得离谱。换回100K100K之后误差立刻回到正常范围。所以我的经验是分压电阻可以取100K到470K之间再大就要自己验证ADC输入阻抗的影响了。如果你对功耗极其敏感非要大阻值那就在固件里做多点校准补偿不要指望线性系数能救回来。3.2 引脚选择ADC1还是ADC2ESP32的ADC分ADC1和ADC2两个单元。ADC1对应GPIO32到GPIO39ADC2对应GPIO0、GPIO2、GPIO4、GPIO12到GPIO15、GPIO25到GPIO27。很多人在这一步埋了雷如果项目用到了WiFiADC2口会被WiFi驱动占用采样函数直接返回错误或者读出满量程值而且是时好时坏非常难排查。只要你打算用WiFi上报数据就老老实实走ADC1。我个人最推荐的是GPIO34对应ADC1的通道6。它有两个优点第一GPIO34是纯输入引脚没有内部上拉和下拉也不能输出PWM作为ADC输入不会被其他外设复用导致配置冲突第二GPIO34在大多数ESP32开发板上都引出了排针方便飞线不容易因为复用问题产生玄学故障。GPIO35也是同样的输入专用引脚可以作为备选。尽量不要用GPIO36和GPIO39虽然它们也是ADC1通道但在很多量产模块上这两个引脚被Flash或PSRAM占用可能会打架。3.3 完整接线关系对应电路图下面这张接线关系表照着连就等效于一张完整电路图的核心采样部分。我按“电源-分压-采样-滤波”的链路来写。连接点A连接点B说明电池正极保护板输出BAT分压电阻R1左端采样电压输入R1右端R2左端节点A分压中点接ADC引脚R2右端系统GND分压接地节点AGPIO34ESP32 ADC1通道6采样节点A0.1uF陶瓷电容C1正极分压点滤波C1负极系统GND滤波器回路电池负极BAT-系统GND电源地必须共地R1取100KR2取100KC1用0.1uF104就可以。C1的作用非常关键ESP32 ADC采样是开关电容结构每次采样瞬间会抽取一个小的电流脉冲如果没有滤波电容分压点电压会因为电荷抽取而产生微小波动反映到数字上就是最后几位来回跳。并了0.1uF电容后采样瞬间由电容提供电荷电压稳定很多读数跳动明显减少。如果对信号纯净度有更高要求可以再加一级RC低通滤波在R1的输入端对地并一个10uF电解电容让分压点看到的电源纹波更小。但注意大电容会拖慢分压点电压的建立时间测量前要留足够的稳定延时。3.4 供电部分的隐藏坑很多朋友看教程只盯着采样电路结果接完才发现系统根本跑不稳。前面提过AMS1117的压差问题这里说完整。如果你的开发板用的是AMS1117锂电池不适合直接接到USB口的5V输入上因为4.2V输入减去1V压差后输出只有3.2V左右电池一旦放到3.9V以下输出可能只有2.9VESP32就处于欠压状态了。推荐的做法是用TP4056这类充电模块给锂电池充电放电时电池输出先经过一个低压差LDO再接ESP32的3.3V。常见的选择是XC6206P332MR或者ME6211压差只有100到200mV锂电池放到3.5V左右时还能稳定输出3.3V系统一直能工作到电池接近放空。XC6206的静态电流大约1到2uA对低功耗设计非常友好。如果你用的电池容量比较大比如1000mAh以上也可以考虑DC-DC降压方案如TPS62740效率比LDO高在电压差大的时候能省不少能量。但DC-DC的静态电流通常比超低功耗LDO大一些而且外围电路多了电感和反馈电阻DIY复杂度上升。我的原则是小容量电池、长时间待机的设备用LDO大容量电池、频繁工作的设备用DC-DC。4. 固件侧的电量算法从ADC读数到真实百分比硬件链路打通之后固件里要做的事情就是配置ADC、读取电压、滤波、校准、映射到百分比。每一步都有值得优化的细节。4.1 第一步配置ADC衰减Arduino环境下如果你直接用analogRead(34)读GPIO34会发现电压在3V以上时读数一直是4095这是因为默认的ADC衰减档位很低输入电压超过约950mV就直接饱和了。必须通过analogSetPinAttenuation设置11dB衰减把输入范围扩展到3.1V左右分压后的2.1V才能被无失真地采样。下面是基础的采样代码我加了多次采样取平均来抑制随机噪声#define BAT_PIN 34 #define R1 100.0f #define R2 100.0f void setup() { Serial.begin(115200); analogReadResolution(12); analogSetPinAttenuation(BAT_PIN, ADC_11db); } float readBatteryVoltage() { uint32_t sum 0; const int samples 32; for (int i 0; i samples; i) { sum analogReadMilliVolts(BAT_PIN); delay(2); } float vAdc (sum / samples) / 1000.0f; return vAdc * (R1 R2) / R2; } void loop() { float vBat readBatteryVoltage(); Serial.printf(Battery: %.2fV\n, vBat); delay(1000); }analogReadMilliVolts()返回的是毫伏值已经利用了ESP32出厂时烧录的eFuse校准参数比直接读原始ADC值再自己换算要准得多。分压系数是(R1R2)/R2这里就是(100100)/1002即把ADC电压还原为电池电压。4.2 校准让数字变成可信的电压即便用了eFuse校准不同ESP32模组之间ADC的个体差异仍然存在。我实测过几块不同的开发板同一节电池同一时刻读数能差30到50mV这个误差换算成电量百分比就是几个百分点勉强能接受但如果你希望显示比较可靠就必须自己校准。最简单的方法是整体校准用万用表实测电池电压同时让程序打印出计算后的电压值然后算一个补偿系数。比如实测4.00V程序读出3.87V系数就是4.00 / 3.87 ≈ 1.034后续所有读数都乘这个系数。把系数存到EEPROM或者Preferences里以后可以随时调整。更严谨的做法是三点或五点校准因为ESP32 ADC在低电压区和高电压区的非线性不一样。在3.0V、3.3V、3.6V、3.9V、4.2V五个点分别记录程序读数和实测值然后做分段线性插值。对大多数应用来说三点校准低压、中压、高压各取一点已经能获得不错的曲线。校准的时候要使用稳压电源或者可调电源分压模拟电池电压这样比实际放电去凑电压点快得多。4.3 电压到电量百分比的映射拿到准确的电池电压之后不能简单线性映射成百分比。锂电池的放电曲线是典型的“先平后陡”从4.2V放到3.7V大概消耗了总电量的60%到70%从3.7V放到3.3V只消耗剩余电量的20%到30%但电压变化却非常明显。如果做线性映射设备会显示“100%用了半小时就变成50%”给用户一种电量狂掉的错觉。正确做法是用一张电压-电量查表段间线性插值。下面这组数据是我多年用3.7V锂聚合物电池整理出来的近似曲线不同电芯会略有差异但拿来用问题不大电压(V)电量(%)4.201004.10904.00803.92703.84603.78503.72403.68303.60203.45103.3053.000写一个查表函数输入电压输出电量百分比float batteryPercentFromVoltage(float voltage) { const float table[][2] { {4.20, 100}, {4.10, 90}, {4.00, 80}, {3.92, 70}, {3.84, 60}, {3.78, 50}, {3.72, 40}, {3.68, 30}, {3.60, 20}, {3.45, 10}, {3.30, 5}, {3.00, 0} }; const int points sizeof(table) / sizeof(table[0]); if (voltage table[0][0]) return 100; if (voltage table[points - 1][0]) return 0; for (int i 0; i points - 1; i) { if (voltage table[i 1][0] voltage table[i][0]) { float t (voltage - table[i 1][0]) / (table[i][0] - table[i 1][0]); return table[i 1][1] t * (table[i][1] - table[i 1][1]); } } return 0; }这里还有一个工程细节低电量关机的阈值不要卡着电池物理截止电压设。因为ESP32经过LDO供电LDO压差决定了系统最低工作电压比如前面说的XC6206在输入3.3V时输出已经掉得厉害所以电量5%对应的3.30V其实已经是系统濒临崩溃的边缘。建议在3.35V左右就触发“请充电”告警3.20V左右直接进入低功耗深度睡眠这个缓冲能避免系统写到一半突然断电刷坏Flash。4.4 滤波与防抖ADC读数的随机噪声可以通过多次采样取平均解决但真正让人头疼的噪声来自系统自身WiFi开启时ESP32发射电流瞬时可以达到200到300mA锂电池内阻会在这个瞬间产生0.1到0.3V的压降导致电量百分比跳变。我实际遇到过一个很无语的场景设备电量显示还剩15%但只要WiFi一连接电压直接跌到3.2V以下触发低电量报警WiFi一关又恢复到3.6V报警解除来回横跳。后来排查发现就是WiFi发射电流导致的电池电压瞬时跌落和真实的剩余电量没有关系。解决思路有两种。第一种是限幅滤波记录上一次的有效电压值如果当前采样值与上次相差超过一定阈值比如150mV就认为是瞬态干扰采用缓慢逼近而不是直接跳变。第二种更彻底把电压采样放在WiFi关闭的时间段或者采样完成后再开WiFi。如果是定时唤醒测量的设备建议的流程是唤醒、开分压开关、延时50ms等待电压稳定、采样、关分压开关、再决定要不要开WiFi上报。这个顺序能避开绝大多数WiFi引入的压降干扰。5. 低功耗优化把待机电流从mA级压到uA级标题里既然提到低功耗优化这一节是重点。很多人以为用ESP32做低功耗就是进Deep Sleep实际上如果外围电路没处理好Deep Sleep也救不回来。我把完整的低功耗链路拆开讲。5.1 先搞清楚功耗到底花在哪在优化之前先量化各个部分的基础功耗。我根据实际项目测试整理了一个参考表状态电流ESP32正常跑WiFi连接80到100mAESP32正常跑WiFi关闭20到40mALight Sleep0.8mA左右Deep Sleep默认10到20uADeep Sleep RTC定时器4到10uA100K100K分压回路21uAAMS1117静态电流3到5mAXC6206静态电流1到2uAMAX17048电量计3uA左右从这个表能看出两个让人意外的事实第一AMS1117的静态电流比整个ESP32的Deep Sleep功耗还大几百倍低功耗项目里用这种LDO等于自废武功第二100K100K分压回路的21uA看起来小但在Deep Sleep电流只有10uA级别的系统里它反而成了最大的耗电源。所以低功耗优化里最核心的两件事就是换掉高静态电流的电源芯片给分压回路加开关。5.2 分压电阻的偷电问题与MOS管开关100K100K的分压回路在待机时一直消耗21uA如果设备打算待机30天光是分压电阻就吃掉15mAh的电量对100mAh的小电池来说是不可忽视的15%。解决方案就一句话测量的时候才给分压回路供电测完立刻断电。我用的是N-MOS管做低边开关电路连接关系如下连接点说明BAT接到R1左端R1右端接R2左端同时也是分压中点R2右端接N-MOS漏极DN-MOS源极S接GNDN-MOS栅极G接GPIO26控制脚分压中点接GPIO34这里选用N-MOS管比如AO3400它的导通电压VGS(th)大约在0.65V到1.2V之间用ESP32的GPIO输出3.3V高电平就能完全导通。GPIO26输出高电平时N-MOS导通分压回路接地回路完整开始工作GPIO26输出低电平时回路断开BAT到地之间没有电流通路分压电阻零耗电。关键是Deep Sleep期间GPIO状态问题。ESP32进入Deep Sleep后大部分GPIO会保持进入睡眠前的输出状态但也有部分引脚会出现浮动栅极一旦悬空MOS管可能进入半导通状态分压回路变成半开半闭反而更耗电。稳妥的做法是在进入Deep Sleep前先把控制引脚拉低并调用gpio_hold_en()锁定引脚状态#define BAT_PIN 34 #define MEAS_CTRL_PIN 26 void enterDeepSleep() { digitalWrite(MEAS_CTRL_PIN, LOW); // 关断分压回路 gpio_hold_en((gpio_num_t)MEAS_CTRL_PIN); // 锁定引脚状态 esp_sleep_enable_timer_wakeup(30LL * 60 * 1000000); esp_deep_sleep_start(); }唤醒之后要先gpio_hold_dis()释放引脚控制权然后再操作GPIO否则数字写入失效。这个细节我在实际项目中踩过花了半天排查最后发现是GPIO hold功能没释放。5.3 电源芯片静态电流AMS1117是低功耗的大敌如果你用开发板上的AMS1117做供电其他低功耗优化全白做。AMS1117在无负载时静态电流就有好几毫安这等于把设备的待机电流直接拉高了几个数量级。做低功耗必须换掉或者绕过它。我用得最多的是ME6211系列它在3.3V固定输出版本下静态电流大约30到50uA压差只有100到200mV从锂电池取电非常合适。如果希望待机功耗压到极致XC6206系列的静态电流只有1到2uA但最大输出电流只有100到200mA带WiFi发射峰值时可能不够需要加大输出电容来撑过瞬时电流尖峰。如果不想换芯片还有一个偏方给LDO加一个使能脚控制。很多LDO芯片带EN引脚可以把EN接到ESP32的一个GPIO上平时LDO关闭需要工作时再打开。但ESP32自己也需要供电所以EN受控的LDO只能用于给外设供电不能给ESP32本身。对于纯ESP32系统只能是换LDO或者用DC-DC。5.4 Deep Sleep唤醒流程与实测续航把分压开关和Deep Sleep组合起来一个完整的低功耗测量周期是这样工作的void setup() { gpio_hold_dis((gpio_num_t)MEAS_CTRL_PIN); pinMode(MEAS_CTRL_PIN, OUTPUT); digitalWrite(MEAS_CTRL_PIN, HIGH); // 打开分压回路 delay(50); // 等分压点稳定 float vBat readBatteryVoltage(); Serial.printf(Battery: %.2fV\n, vBat); digitalWrite(MEAS_CTRL_PIN, LOW); // 关断分压回路 enterDeepSleep(); // 进入睡眠 }整个测量周期大约耗时60ms工作电流在10mA到20mA左右睡眠期间系统电流约10uA分压回路断开。按30分钟唤醒一次计算持续30天的平均电流大约在10uA到20uA之间200mAh的电池理论上可以支撑超过一年。这里的理论值没有算电池自放电和LDO静态电流实际打折后也能做到半年以上算是一个非常可观的续航能力。如果你还需要WiFi上报那么每次唤醒后不要先采样就睡而是采样、然后开WiFi、连上就发数据、发完立刻关WiFi再Deep Sleep。WiFi连接过程通常要1到3秒平均电流80mA这部分能量开销在30分钟周期内会让平均电流上升到0.1mA左右200mAh电池的续航会缩短到两三个月。这个数值仍然可以接受关键是不要让WiFi长时间保持连接要“用的时候才连用完就断”。6. 实测中的坑WiFi压降、ADC温漂、电池保护板误关断本章把这些年实测中反复遇到的坑集中总结一下这些内容写不进教科书但实操中几乎每个人都躲不开。6.1 WiFi发射瞬间电压大跌低电量误报前面已经提过WiFi发射电流会造成电池电压瞬时跌落实际严重程度远超你想象。我曾经用一块400mAh的小聚合物电池测试WiFi发送数据的瞬间电池电压从3.8V直接掉到3.4V如果此时去判断电量会直接判成“只剩5%”。更糟糕的是电压跌落是毫秒级的普通滤波算法根本来不及平滑。解决方式只有一个电压采样和WiFi工作必须错开时间窗。每次唤醒先采样采样完成后关掉分压开关记录电压值然后才开WiFi传输。传输过程中无论电压显示成什么样都不要用那个数据去更新电量显示。我一般会在固件里维护一个lastStableVoltage变量只有采样完成且分压回路稳定时才会更新它WiFi期间所有ADC读数直接丢弃。6.2 ADC温漂和个体差异校准不能只在室温ESP32的ADC对温度是敏感的尤其在11dB衰减档位下温度变化二三十度读数就可能有几十毫伏的漂移。这意味着你在26度的空调房里校准的参数拿到户外晒一天太阳之后电量百分比可能整体偏了5%以上。不同批次、不同封装的ESP32 ADC一致性也一般。我测过的模组里相同电压下的ADC读数差距在30到80mV之间并不稀奇。如果用大批量生产每一批都要抽样校准最好在固件里留一个校准参数存储区出厂前写入每个设备单独标定的偏移和增益系数。如果只是个人DIY每块板子至少要在正常使用环境下做一次整体校准别直接套用别人发布的参数。6.3 电池保护板误关断这个坑比较隐蔽。锂电池保护板有过放保护、过流保护、短路保护。正常情况下分压回路的电流只有几十微安远远不会触发保护但问题出在系统刚上电的瞬间ESP32的电源输入电容瞬间充电会产生一个很大的电流尖峰如果电池本身已经处于低压区这个尖峰可能让保护板误判为过流或短路直接切断输出。表现是设备刚接通电池时还能启动两三秒后突然断电再插又好了反复无常。排查方法是测保护板输出端的电压如果电池直接测有电压但保护板输出端突然变成0V就是保护板误动作了。解决思路有两个一是选择带大容量电池且保护板质量好的电池组二是给系统供电入口串联一个小阻值的软启动电阻或加一个更大容量的输入电容缓冲。分压采样部分也会遇到类似情况如果保护板切断输出分压点电压瞬间变成0程序可能误以为电池被拔掉。这种情况下固件里可以做“连续多次读到0V才判定异常”的机制避免单次异常导致误报。6.4 充电状态下测电量纯属自欺欺人用TP4056给电池充电时电池端电压会明显高于开路电压。比如电池实际只有3.6V但充电电流还在流动测量点读到的可能是3.9V甚至4.0V。如果你在充电状态下做电量显示屏幕上会魔术般出现“100%”然后拔掉充电器瞬间掉到60%。正确做法是把TP4056的充电状态引脚CHRG通常充电时为低电平接到ESP32的另一个GPIO上固件读到正在充电时不更新电量百分比只显示“充电中”或者“已充满”。或者退一步如果不想接这个引脚至少要在固件里加入“电压持续高于4.1V且持续一段时间”才认为是充满避免充电波动导致的误判。最后再说一个使用习惯上的建议测电压和电量百分比这个功能本质上需要的是“慢变量”而不是“快变量”。别让屏幕上的百分比每秒都跳用滑动平均或者限制每次变化的幅度把更新频率放到10秒或30秒一次既省电又护眼。我做这类项目时的习惯是只在以下几种情况刷新电量显示开机时、按键唤醒时、定时采样周期到达时、发送上报数据之前。其他时间一律用上次的缓存值这个策略对降低功耗和提升体验都很有效。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。