I needed tabular values for the dependency of Open Circuit Voltage (OCV) of a Li-Ion battery on Depth of Discharge (DOD), but I couldn't find this data anywhere.
The closest I found was an image of OCV by State of Charge (SOC) in a ResearchGate article. Although the authors provide a formula for modeling these values in the article, I only needed an array of approximate values.
Therefore, I decided to extract them directly from the image.
There is an image:
Source: https://www.researchgate.net/figure/OCV-model-of-a-Li-ion-battery_fig3_363656090
License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
I placed a series of control points and made a spline in a graphic software:
Afterward, I listed the coordinates of the points I had placed, and using these coordinates, I created a spline with Python code:
import numpy as np
from scipy.interpolate import CubicSpline
CONTROL_POINTS = [
(29.1879, 20.1961),
...
]
control_points = np.array(CONTROL_POINTS)
x_points = control_points[:, 0]
y_points = control_points[:, 1]
spline = CubicSpline(x_points, y_points)
# create 1000 evenly spaced points over the range of x-coordinates
spline_x = np.linspace(min(x_points), max(x_points), 1000)
spline_y = spline(spline_x)
Next, convert SOC into DOD by formula: `DOD = 1 - SOC` and map coordinates into real values:
OCV_MIN = 2500
OCV_MAX = 4200
OCV_RANGE_SIZE = OCV_MAX - OCV_MIN
x_min = min(spline_x)
x_max = max(spline_x)
x_range_size = x_max - x_min
y_min = min(spline_y)
y_max = max(spline_y)
y_range_size = y_max - y_min
dod_arr = []
voltage_arr = []
for x, y in zip(spline_x, spline_y):
dod = x - x_min
dod /= x_range_size
dod = 1 - dod # SOC -> DOD
dod_arr.append(dod)
voltage = y - y_min
voltage /= y_range_size
voltage *= OCV_RANGE_SIZE
voltage += OCV_MIN
voltage_arr.append(voltage)
And now I can obtain lookup values of OCV by DOD:
LOOKUP_DOD_POINTS = [
0, # 0 %
1 / 9, # 11.11 %
2 / 9, # 22.22 %
3 / 9, # 33.33 %
4 / 9, # 44.44 %
5 / 9, # 55.55 %
6 / 9, # 66.66 %
7 / 9, # 77.77 %
7 / 9 + (2 / 9 / 7), # 80.95 %
7 / 9 + (2 / 9 / 7) * 2, # 84.13 %
7 / 9 + (2 / 9 / 7) * 3, # 87.30 %
7 / 9 + (2 / 9 / 7) * 4, # 90.48 %
7 / 9 + (2 / 9 / 7) * 5, # 93.65 %
7 / 9 + (2 / 9 / 7) * 6, # 96.83 %
7 / 9 + (2 / 9 / 7) * 7, # 100 %
]
spline = CubicSpline(dod_arr, voltage_arr)
lookup_dod = np.array(LOOKUP_DOD_POINTS)
lookup_voltage = spline(lookup_dod)
These lookup points were chosen to align with Texas Instruments “Theory and Implementation of Impedance Track”:
- From 0% to 77.77% with a step of 11.11% - divide the range [0, 0.7777] into 7 parts
- From 77.77% to 100% with a step of 3.17% - divide the range [0.7777, 1] into 7 parts
As a result I got a lookup table:
DOD0 | OCV ----------------------------------------- 0.0000000000000000 | 4200.0 0.1111111111111111 | 4082.8094819064786 0.2222222222222222 | 4010.3286640965916 0.3333333333333333 | 3903.1651994446183 0.4444444444444444 | 3790.3095936671903 0.5555555555555556 | 3687.8963892386937 0.6666666666666666 | 3614.6922702706906 0.7777777777777778 | 3528.2803746157497 0.8095238095238095 | 3493.3810313832346 0.8412698412698413 | 3456.092442257784 0.8730158730158730 | 426.3134021476235 0.9047619047619048 | 3395.8697031959655 0.9365079365079365 | 3369.4326150781576 0.9682539682539683 | 3219.2335651829885 1.0000000000000000 | 2500.0
Let's generate approximation graph with step 1%:
LOOKUP_DOD_1PERCENT_STEP = np.arange(0, 101, 1) / 100
Experimental Data
I conducted an experiment with periodic battery discharge, where the discharge periods were followed by rest periods to allow the battery voltage to recover to the open circuit voltage.
Obtained data
Relative DOD | OCV --------------------------------------- 0.00000000000000000 | 4169.0000000000000 0.01062720634580555 | 4146.6292976649240 0.10538080563230103 | 4056.3886143905210 0.20030350100523422 | 3960.5229873505280 0.29614236707116864 | 3886.3375806664662 0.39175390322347590 | 3809.5678638454065 0.48825327168229120 | 3699.5836222425996 0.58395262569164350 | 3638.2849280295272 0.67904223727513020 | 3583.8676377591487 0.78466843464981240 | 3518.0839518320770 0.81200594670141190 | 3489.1373938246484 0.83944653574124500 | 3460.7585273699650 0.87091024143059660 | 3419.7036910830890 0.89766510379946140 | 3382.2520399131900 0.92411602918791520 | 3363.1344272002890 0.94982019138064620 | 3343.8997352436120 1.00000000000000000 | 3274.0000000000000
References
- Image “OCV model of a Li-ion battery”: https://www.researchgate.net/figure/OCV-model-of-a-Li-ion-battery_fig3_363656090
- Texas Instruments “Theory and Implementation of Impedance Track”: https://www.ti.com/lit/an/slua364b/slua364b.pdf
Sources
- GitHub Gist: https://gist.github.com/asilichenko/342613acfcdbc697a07831bb4a82d4ea
- Generated data (1000 points): https://docs.google.com/spreadsheets/d/1osN5bf89-xLXIydQKgJzRk5vHEYXHxaP2hoR2wP83jY/edit?usp=sharing
No comments:
Post a Comment