摘要:使用ESP32C5开发板、Timer-PWR供电模块实现的具有锂电池 / 设备功耗等状态监控的web面板,并通过web界面可实时监控锂电池充放电以及设备控制、功耗等相关功能;
一、硬件介绍
1、主控开发板
使用的是XIAO ESP32C5开发板,集成ESP32C5 32位双核处理器芯片,最高运行频率240MHz,板载8MB PSRAM和8MB FLASH;

功能引脚示意图

2、Unit TimerPWR 供电模块
Unit TimerPWR是一款定时供电单元,具备 “充放电 + 定时开关 + 屏幕显示 + 升压输出” 等主要功能;
内置STM32微控制器,用于实现RTC及整体控制,设置自动开机与关机时间;
通过Grove接口为外部设备提供 5V/800mA的电源输出;
主要特性
内置INA3221传感器,可实时监控电源输入输出的电流和电压;
板载0.66英寸OLED显示屏以及2个侧按钮,用于查看实时状态并修改设置参数;
可以使用接入Grove接口的I2C总线,通过I2C指令来设置开关机参数等;
待机电流:DC4.2V@36.67uA;

二、功能实现
1、硬件搭建
将1200mAh锂电池连接到Unit TimerPWR模块,并通过模块的Grove接口给ESP32C5提供供电,并连接I2C引脚到开发板对应的引脚上;
实物搭建效果:

2、功能效果
通过Unit TimerPWR模块给ESP32C5提供供电,并通过I2C读取模块采集到的电池电压 / 电流、输出电压 / 电流、充放电状态等数据并显示到Web界面上;
Web界面具有以下功能:功能开关控制、单次与循环运行定时设置、锂电池状态与输出负载信息显示、电池续航 / 充电时间估算、功耗变化曲线等功能;
整体界面效果
开关控制: 设置OLED屏幕背光、Grove接口 5V输出、定时模式的开启与关闭;
定时设置:支持单次 / 循环两种运行定时模式,可分别单独设置运行与停止时长(最长255小时);
电池状态:实时显示当前锂电池电压、电流及充放电状态;
输出负载:实时显示输出端的电压、电流及供电设备的实时功耗;
续航 / 充电时间:根据输入电池的实际容量,以及当前电池充/放电电流,自动计算放电状态下的续航时间 / 充电状态下充满电所需的时间;
功耗曲线:绘制最近30秒功耗变化趋势曲线,同时记录设备上电以来的最大、最小及平均功耗数据;

功能开关控制
OLED 屏幕:控制模块的OLED屏幕的背光开启 / 关闭;
5V输出:控制模块的5V输出(输出供电)开启 / 关闭;
定时模式:控制 `定时功能` 开启 / 关闭;

定时设置
可设置单次 / 循环两种运行模式,并分别单独设置运行与停止时长参数(最长可设置255小时);

输出负载
实时显示输出端的电压、电流及供电设备的实时功耗;

电池充放电(充电 / 续航)
充电时:显示当前的锂电池电压以及充电的电流大小;
同时在充电时,显示预估充满所需的时间;

放电时:显示当前的锂电池电压以及整体放电的电流大小;
同时在放电时,显示预估续航的时间;

功耗曲线图
显示最近30s内的功耗变化趋势;
同时显示当前设备运行时的最大、最小、以及整体的平均功耗情况;

三、代码编写
主要相关代码
#include "Wire.h"
#include "m5_unit_timerpwr.hpp"
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#define PWR_SDA D4
#define PWR_SCL D5
#define RGB_BLUE D7
M5UnitTimerPWR timer_pwr;
const char* ssid = "WIFI_SSID";
const char* password = "WIFI_PASS";
AsyncWebServer server(80);
// 开关状态
bool oledState = true;
bool outputState = true;
bool timerMode = false;
bool userCycleMode= false;
// 定时参数
uint8_t g_on_h=0, g_on_m=0, g_on_s=10;
uint8_t g_off_h=0, g_off_m=0, g_off_s=10;
// 电池信息
float batV,batI,groveV,groveI;
bool isCharge;
// 功耗统计
float totalPower = 0;
float maxPower = 0;
float minPower = 999999;
uint32_t sampleCount = 0;
...
HTML 部分
...
void setup(){
Serial.begin(115200);
pinMode(LED_BUILTIN,OUTPUT);
pinMode(RGB_BLUE,OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
digitalWrite(RGB_BLUE, HIGH);
WiFi.begin(ssid,password);
while(WiFi.status()!=WL_CONNECTED){ delay(500);Serial.print("."); }
Serial.println();
timer_pwr.begin(&Wire,TIMERPWR_ADDR,PWR_SDA,PWR_SCL,400000U); //模块I2C初始化 400khz
delay(800);
// 默认关闭定时模式
timer_pwr.set_cycle_sleep(false);
oledState = timer_pwr.get_oled_backlight();
outputState = timer_pwr.get_grove_5v_output();
userCycleMode = false;
timerMode = false;
...
// web相关数据显示
server.on("/data", HTTP_GET, [](AsyncWebServerRequest *req){
String onTimeStr = formatDuration(g_on_h,g_on_m,g_on_s);
String offTimeStr = formatDuration(g_off_h,g_off_m,g_off_s);
String json = "{";
json += "\"charge\":"+String(isCharge?"true":"false"); // 充放电状态
json += ",\"batV\":"+String(batV,2); // 电池电压
json += ",\"batI\":"+String(batI,2); // 电池电流
json += ",\"groveV\":"+String(groveV,2); // 输出电压
json += ",\"groveI\":"+String(groveI,2); // 输出电流
json += ",\"maxPower\":"+String(maxPower/1000,2); // 最大功耗
json += ",\"minPower\":"+String(minPower>99999?0.0f:minPower/1000,2); // 最小功耗 W
json += ",\"avgPower\":"+String(sampleCount>0?totalPower/sampleCount/1000:0.0f,2); // 平均功耗
json += ",\"oled\":"+String(oledState?"true":"false"); // OLED状态
json += ",\"output\":"+String(outputState?"true":"false");// 5V输出
json += ",\"timerMode\":"+String(timerMode?"true":"false"); // 定时开关
json += ",\"cycleMode\":"+String(userCycleMode?"true":"false"); // 单次 / 循环
json += ",\"onTime\":\""+onTimeStr+"\""; // 运行时间
json += ",\"offTime\":\""+offTimeStr+"\""; // 停止时间
json += "}";
req->send(200, "application/json", json);
});
...
server.begin();
Serial.print("web地址: http://");
Serial.println(WiFi.localIP());
}
void loop(){
int16_t t_batV = timer_pwr.get_battery_voltage();
int16_t t_batI = timer_pwr.get_battery_current();
int16_t t_groveV = timer_pwr.get_grove_voltage();
int16_t t_groveI = timer_pwr.get_grove_current();
// 数据获取
if(t_batV != -1) batV = (float)t_batV / 100.0f;
if(t_batI != -1) batI = (float)t_batI / 100.0f;
if(t_groveV != -1) groveV = (float)t_groveV / 100.0f;
if(t_groveI != -1) groveI = (float)t_groveI / 100.0f;
isCharge = timer_pwr.get_battery_charge_status();
oledState = timer_pwr.get_oled_backlight();
outputState = timer_pwr.get_grove_5v_output();
// 功耗统计
float power = groveV * groveI;
sampleCount++;
totalPower += power;
if(power > maxPower) maxPower = power;
if(power < minPower) minPower = power;
delay(1000);
}四、程序烧录
1、连接USB数据线至开发板;
2、选择端口号对应的开发板;
3、点击 上传 烧录程序到开发板上;

五、效果演示
通过Web网页端可以远程查看当前锂电池状态、设备运行时的相关信息,以及可以控制设备开关 / 设置定时运行模式等;

我要赚赏金
