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)
Asked Answered
F

3

6

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)

Feretory answered 23/5, 2019 at 1:12 Comment(0)
H
5

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);
}
Heroic answered 26/5, 2019 at 20:5 Comment(0)
D
5

I am working with this table:

4.2 volts 100%
4.1 about 90%
4.0 about 80%
3.9 about 60%
3.8 about 40%
3.7 about 20%
3.6 empty for practical purposes.

This means that if that cell had dropped to 60% capacity, the voltage would have dropped to below 3.9 volts.

The table is from a german site, so I guess the link won't help.

Edit: I've found this english link:Battery charge

Dulosis answered 23/5, 2019 at 5:50 Comment(0)
H
5

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);
}
Heroic answered 26/5, 2019 at 20:5 Comment(0)
F
1

I wanted to figure out the percentage from the range 4.2 (fully charged, 100%) to 3.6 (dead, 0%) and this is the solution I came up with.

Working example on TinkerCad

void loop() {
  float vPow = 5.0;
  float r1 = 100000;
  float r2 = 10000;

  float v = (analogRead(A0) * vPow) / 1024.0;
  float v2 = v / (r2 / (r1 + r2));
  
  float top = 4.2;
  float bottom = 3.6;
  float range = top - bottom;
  float rangeVolts = v2 - bottom;
  int percent = (rangeVolts / range) * 100;
  
  if(percent > 100){
    percent = 100;
  }
  if(percent < 0) {
    percent = 0;
  }
  
  Serial.print("percent ");
  Serial.println(percent);
  
  delay(1000);
}
Fib answered 27/7, 2022 at 1:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.