如何获取锂电池的电压、电流、电量等信息呢?本文基于ESP8266 + INA219 实现电池监测。喜欢就收藏吧!
设备清单
- esp8266
- INA219模块
- 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发送。这样我们便可以远程查看电池的信息了。
源码
#include <Wire.h>
#include <Adafruit_INA219.h>
#include <U8g2lib.h>
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)$