如何获取锂电池的电压、电流、电量等信息呢?本文基于ESP8266 + INA219 实现电池监测。喜欢就收藏吧!
设备清单esp8266INA219模块18650锂电池5v充电模块0.96Oled屏幕设备清单线路连接连接类别
设备/引脚端
连接至
esp8266-INA219
GPIO4 OLED (D2)
INA219 SDA
esp8266-INA219
GPIO5 OLED(D1)
INA219 SCL
esp8266-INA219
3.3V
INA219 VCC
esp8266-INA219
GND
INA219 GND
锂电池连接
18650 正极
INA219 (vim -)
锂电池连接
18650 负极
esp8266 (GND)
充电模块
正极
INA219 (vim +)
充电模块
负极
锂电池负极
用电器(负载)
设备正极
INA219 (vim +)
用电器(负载)
设备负极
esp8266 (GND)
效果类似电流表,可实时测量电池的电压,电流、容量、充放电状态等。
后期改进后期,我们可以通过MQTT协议,将电池信息通过json发送。这样我们便可以远程查看电池的信息了。
源码代码语言:javascript复制#include
#include
#include
Adafruit_INA219 ina219;
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
const float BATTERY_CAPACITY = 3.5;
const float FULL_VOLTAGE = 4.15;
const float EMPTY_VOLTAGE = 3.0;
const float CURRENT_THRESHOLD = 5.0;
const int FILTER_WINDOW_SIZE = 10;
float batteryVoltage = 0.0;
float shuntVoltage_mV = 0.0;
float current_mA = 0.0;
float filteredCurrent = 0.0;
float power_mW = 0.0;
float batterySOC = 50.0;
float totalCharge = 0.0;
String batteryState = "";
float currentBuffer[FILTER_WINDOW_SIZE];
int filterIndex = 0;
unsigned long lastTime = 0;
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(1);
}
Serial.println("ESP8266 + INA219 电池监测系统启动中...");
if (!ina219.begin()) {
Serial.println("INA219初始化失败!请检查接线");
while (1);
}
ina219.setCalibration_32V_2A();
u8g2.begin();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB10_tr);
u8g2.setCursor(20, 35);
u8g2.print(F("Starting..."));
u8g2.sendBuffer();
delay(2000);
for (int i = 0; i < FILTER_WINDOW_SIZE; i++) {
currentBuffer[i] = 0.0;
}
lastTime = millis();
Serial.println("INA219初始化成功!");
Serial.println("使用滑动窗口滤波 + 库仑计法");
Serial.println("----------------------------------------");
Serial.println("电压(V) | 分流电压 | 电流(mA) | 功率(mW) | 电量(%) | 状态");
Serial.println("----------------------------------------");
}
void loop() {
unsigned long currentTime = millis();
float deltaTime = (currentTime - lastTime) / 3600000.0;
readBatteryData();
filteredCurrent = filterCurrentValue(current_mA);
calculateSOC(deltaTime);
determineState();
displayData();
displayOnOLED();
lastTime = currentTime;
delay(1000);
}
void readBatteryData() {
batteryVoltage = ina219.getBusVoltage_V();
shuntVoltage_mV = ina219.getShuntVoltage_mV();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
}
float filterCurrentValue(float newValue) {
currentBuffer[filterIndex] = newValue;
filterIndex = (filterIndex + 1) % FILTER_WINDOW_SIZE;
float sum = 0.0;
for (int i = 0; i < FILTER_WINDOW_SIZE; i++) {
sum += currentBuffer[i];
}
return sum / FILTER_WINDOW_SIZE;
}
void calculateSOC(float deltaTime) {
if (deltaTime > 0) {
float chargeChange = (filteredCurrent / 1000.0) * deltaTime;
totalCharge += chargeChange;
float voltageSOC;
if (batteryVoltage >= 4.15) {
voltageSOC = 100.0;
} else if (batteryVoltage <= 2.7) {
voltageSOC = 0.0;
} else {
voltageSOC = ((batteryVoltage - 2.7) / (4.15 - 2.7)) * 100.0;
}
float estimatedSOC = (totalCharge / BATTERY_CAPACITY) * 100.0;
if (batteryVoltage >= 4.1) {
batterySOC = voltageSOC;
} else if (batteryVoltage <= 3.2) {
batterySOC = (estimatedSOC * 0.1) + (voltageSOC * 0.9);
} else {
batterySOC = (estimatedSOC * 0.2) + (voltageSOC * 0.8);
}
batterySOC = constrain(batterySOC, 0.0, 100.0);
if (batterySOC >= 99.5) {
batterySOC = 100.0;
}
}
}
void determineState() {
if (filteredCurrent > CURRENT_THRESHOLD) {
batteryState = "充电中";
} else if (filteredCurrent < -CURRENT_THRESHOLD) {
batteryState = "放电中";
} else if (filteredCurrent > 1.0 && batteryVoltage >= 4.0) {
batteryState = "充电中";
} else {
batteryState = "待机";
}
}
void displayData() {
Serial.print(batteryVoltage, 2);
Serial.print("V | ");
Serial.print(shuntVoltage_mV, 1);
Serial.print("mV | ");
Serial.print(filteredCurrent, 0);
Serial.print("mA | ");
Serial.print(power_mW, 0);
Serial.print("mW | ");
Serial.print(batterySOC, 1);
Serial.print("% | ");
Serial.println(batteryState);
}
void displayOnOLED() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(0, 10);
u8g2.print(F("Voltage: "));
u8g2.print(batteryVoltage, 2);
u8g2.print(F(" V"));
u8g2.setCursor(0, 24);
u8g2.print(F("Current: "));
u8g2.print(filteredCurrent, 0);
u8g2.print(F(" mA"));
u8g2.setCursor(0, 38);
u8g2.print(F("Power: "));
u8g2.print(power_mW, 0);
u8g2.print(F(" mW"));
u8g2.setCursor(0, 52);
u8g2.print(F("SOC: "));
u8g2.print(batterySOC, 1);
u8g2.print(F(" %"));
u8g2.setCursor(0, 64);
u8g2.print(F("Status: "));
if (batteryState == "充电中") {
u8g2.print(F("Charging"));
} else if (batteryState == "放电中") {
u8g2.print(F("Discharging"));
} else {
u8g2.print(F("Idle"));
}
u8g2.sendBuffer();
}相关计算公式容量(mAh) = \sum |I(t)| \times \Delta t(h) ----
版权属于:逍遥子大表哥
本文链接:https://cloud.tencent.com/developer/article/2629638
按照知识共享署名-非商业性使用 4.0 国际协议进行许可,转载引用文章应遵循相同协议。