Approximating SoC of a Lithium Ion battery using atan

I recently deep-dived into a topic of look up tables and interpolation simply because I wanted to have relatively simple representation of State of Charge for one of my projects. The difficulty I found is that the LiFePO4 batteries have a very flat discharge curve and are really hard to approximate.

The complexity was added because I wanted to do such approximation using micropython (which lacks scipy library). The only tool I had available is the micropython math library.

After spending hours on coming up with a reasonable interpolation algorithm I decided to look into a mathematical solution by finding a curve that fits into the discharge curve published for cells in question.

The curve awfully looks like a sigmoid (S-shaped). So I tried various implementation and found that atan(x) was the simples to manipulate to fit most of the data points.

For LiFePO4:

soc = round(100 * (0.38 * atan(17 * v_cell - 56) + 0.58),1)
if soc < 0:
    soc = 0
if soc > 100:
    soc = 100

For LCO (aka as Li-Ion):

soc = round(100 * (0.44 * atan(4.3 * v_cell - 16.5) + 0.55),1)
if soc < 0:
    soc = 0
if soc > 100:
    soc = 100

Note: I round to a single decimal simply because approximation is hardly accurate.

The numbers are of course are fudged to fit best, one could manipulate it further to make it more accurate.

Of course this algorithm should not be used as part of a charging strategy (unless you are making an incendiary device).

SoC/Volts graph for both atan() approximations
Volts/SoC graph (commonly seen in a battery data sheet).

For curious types – I have devised this algorithm to decide the microcontroller sleeping strategy.

Leave a Reply

Your email address will not be published.