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)
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
Actually, you can't do much about nonlinear behavior, you just need to measure your max and min voltages and calculates the battery percentage based on that. Below I created a function which returns the percentage of battery level. Remember to edit battery_max
and battery_min
based on your battery voltage levels.
Also, I recommend you to create a resistor divider circuit to reduce the voltage level because if your input power supply drops down, the Arduino would 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);
}
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.
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);
}
Someone on https://electronics.stackexchange.com/a/551667 wrote a simple mathematical function to calculate percentage on volt level for 3.7 liOn battery. Have a look there.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.