Arduino UNO Lithium Battery Charge Indicator – Extended Example

This example demonstrates how to estimate the charge level of a lithium-ion battery using an Arduino UNO. The program calculates:

  • Battery Capacity: User-defined in Watt-hours (Wh)
  • Discharge Load: Approx. 10% of capacity rating
  • Estimated Discharge Time: Based on current charge level
⚠️ Critical Lithium Battery Safety Warning

Lithium-ion batteries pose significant fire and explosion risks when improperly charged, discharged, or short-circuited. They must never be connected directly to an Arduino without a proper battery protection circuit.

  • Use a BMS (Battery Management System) for overcharge, over-discharge, and short-circuit protection.
  • Never exceed 4.2 V per cell – overcharging can cause thermal runaway.
  • Avoid deep discharge below 3.0 V – this permanently damages lithium cells.
  • Use protected charger modules such as TP4056 with protection circuitry.
  • Never leave lithium batteries charging unattended.

Failure to follow proper safety practices can result in fire, injury, or property damage.

Detailed Steps
  • Battery Voltage Measurement: Voltage is read using the ADC and scaled.
  • Charge Level Calculation: Voltage is mapped to battery capacity percentage.
  • Discharge Time Calculation: Based on a load equal to 10% of Wh capacity.
Arduino Code

/*
 * Arduino UNO Lithium Battery Charge Indicator
 * Measures battery voltage and estimates charge level and discharge time.
 * Capacity parameter in Watt-hours (Wh) and discharge load based on 10% of Wh rating.
 * © 2024 Peter I. Dunne - All rights reserved
 * Released under the Mozilla Public License
 */

const int batteryPin = A0;        // Battery voltage to A0
const float adcMaxVoltage = 5.0;  // ADC reference voltage
const float maxADCValue = 1023.0; // 10-bit resolution

// Battery parameters
const float batteryCapacityWh = 2.0;   // Example: 2.0 Wh
const float dischargeLoadFactor = 0.20; // Load = 20% of Wh (0.20 = 20%)

void setup() {
    Serial.begin(115200);
}

void loop() {
    // Read voltage
    float batteryVoltage = analogRead(batteryPin) * (adcMaxVoltage / maxADCValue);

    // Charge estimation (needs calibration for real use)
    float minVoltage = 3.0;
    float maxVoltage = 4.2;
    float chargeLevel = ((batteryVoltage - minVoltage) / (maxVoltage - minVoltage)) * 100.0;

    if (chargeLevel < 0) chargeLevel = 0;
    if (chargeLevel > 100) chargeLevel = 100;

    // Power load
    float dischargeLoadWatts = batteryCapacityWh * dischargeLoadFactor;

    // Remaining time
    float totalHours = (batteryCapacityWh * (chargeLevel / 100.0)) / dischargeLoadWatts;
    int hours = (int)totalHours;
    int minutes = (totalHours - hours) * 60;

    Serial.print("Voltage: ");
    Serial.print(batteryVoltage, 2);
    Serial.print(" V, Charge: ");
    Serial.print(chargeLevel, 2);
    Serial.print(" %, Load: ");
    Serial.print(dischargeLoadWatts, 2);
    Serial.print(" W, Time Left: ");

    if (hours < 10) Serial.print("0");
    Serial.print(hours);
    Serial.print(":");
    if (minutes < 10) Serial.print("0");
    Serial.println(minutes);

    delay(1000);
}
        
How It Works
  • Voltage Measurement: ADC scales the measured voltage.
  • Charge Percentage: Linearly based on calibrated min/max voltage.
  • Discharge Time: Battery capacity ÷ calculated load.