Search code examples
arduinobatteryesp32batterylevel

How do I convert battery voltage into battery percentage on a 4.15V Li-Ion Battery in an Arduino IDE? (I am making some kind of LED Battery Indicator)


I know that battery discharge on a 4.15V Li-Ion is not linear, so I would like to have some equation that I can apply in my code to show the correct battery percentage.

I can't find any good resources on doing this in an Arduino IDE. (Help with link if you guys have)


Solution

  • Actually, you can't do much about nonlinear behavior; you can measure your max and min voltages and calculate the battery percentage based on that. Below I created a function that returns the percentage of battery level. Remember to edit battery_max and battery_min based on your battery voltage levels.

    Also, I recommend you create a resistor divider circuit to reduce the voltage level because if your input power supply drops down, the Arduino will feed directly from Analog input which is undesirable.

    int battery_pin = A3;
    
    float battery_read()
    {
        //read battery voltage per %
        long sum = 0;                   // sum of samples taken
        float voltage = 0.0;            // calculated voltage
        float output = 0.0;             //output value
        const float battery_max = 4.20; //maximum voltage of battery
        const float battery_min = 3.0;  //minimum voltage of battery before shutdown
    
        for (int i = 0; i < 500; i++)
        {
            sum += analogRead(battery_pin);
            delayMicroseconds(1000);
        }
        // calculate the voltage
        voltage = sum / (float)500;
        // voltage = (voltage * 5.0) / 1023.0; //for default reference voltage
        voltage = (voltage * 1.1) / 1023.0; //for internal 1.1v reference
        //round value by two precision
        voltage = roundf(voltage * 100) / 100;
        Serial.print("voltage: ");
        Serial.println(voltage, 2);
        output = ((voltage - battery_min) / (battery_max - battery_min)) * 100;
        if (output < 100)
            return output;
        else
            return 100.0f;
    }
    
    void setup()
    {
        analogReference(INTERNAL); //set reference voltage to internal
        Serial.begin(9600);
    }
    
    void loop()
    {
        Serial.print("Battery Level: ");
        Serial.println(battery_read(), 2);
        delay(1000);
    }