Battery nominal capacity estimation using Coulomb Counting

조회 수: 8 (최근 30일)
slow_hand
slow_hand 2022년 11월 16일
댓글: slow_hand 2022년 12월 5일
Hi all,
I'm trying to estimate the nominal capacity of a PV plant battery pack collecting SOC data from the BMS using current discharge. Once I've collected current, time and SOC data I put those data into matlab and use an optimization algorithm to evaluate the capacity using the following expression (in the attachment) and the following code:
%% Optimization phase
clear all;
clc;
%% Estimation procedure using LSQNONLIN with two possible approach evaluated
% in 'SOCestimation.m': (1) Estimate the C by comparing the REAL SOC (filtered)
% and the one evaluated with CC in each single point till the end; (2) Evaluate C as
% same as before but considering the specific EOD (End of Discharge) point.
% x = C_estimated for battery pack (React) in Ah
x = 5;
x0 = rand*[x];
% Capacity (x stands for unknown) lower and upper bounds
xlb=[1];
xub=[50];
% Setting the optimization alg.
options = optimset('MaxFunEvals',15000,'MaxIter',10,'TolFun',1e-100,'TolX',1e-100,'Algorithm', 'levenberg-marquardt','Display','iter-detailed', 'FinDiffType', 'central'); %'levenberg-marquardt'
[x,resnorm,residual,exitflag,output]=lsqnonlin(@SOCestimation, x0, [xlb], [], options);
---------------------------------------------------------------------------------------------
%% Soc estimation file
function [f] = SOCestimation(x)
%% Loading OCV curve (discharge curves at 200 W during 02/03 november)
%% Filtering the SOC_real from a stepped curve into a linear one (can be commented out)
%
% y = smooth(SOC, 1e100, 'moving');
% filt_len = 1;
% a = 1;
% b = (1/filt_len)*ones(1,filt_len);
% SOC_real_filtered = filter(b,a,y);
%% Evaluate SOC as a function of C in Ah (=x) and the difference between SOC real
% and calculated (Discharge current is negative)
SOC_estim = ((1-(1/(x*3600))*cumtrapz(Time, -Current))*100);
% Estimate the C by comparing the real SOC (filtered or not) with the Coulomb Counting one
% considering also the last SOC value (End of Discharge)
f=SOC_real-SOC_estim;
plot(Time,SOC_real,Time,SOC_estim)
legend({'Real SOC filtered from stepped function','SOC estimated studying the C'})
drawnow
end
The problem is that I'm analyzing different discharge curves (1kW, 200W, 2kW constant power discharge) and I'm obtaining always different nominal capacity:
  • 16.06 Ah for 1kW discharge;
  • 15.9 Ah for 200W discharge;
  • 14.97 Ah for 2kW discharge.
From the datasheet I've got that this battery pack has 4.8 kWh initial capacity and 288V as nominal voltage so nominal initial capacity is 16.8Ah but during lifetime is reported that the nominal capacity is around 4.0 kWh and 4.4 kWh so 13.8Ah - 15.4 Ah.
Please..what is wrong with my code? I'm trying to estimate the maximum capacity of the battery in order to evaluate for example the state of health comparing it to a new battery pack.
Here's the expression used:
  댓글 수: 5
MAHENDRAN A
MAHENDRAN A 2022년 11월 29일
Bro, Im too developing SOC estimation model using coulomb counting and kalman filter method. And based on what you asked, I too have doubt on this.
Can you explain me about this topic Battery nominal capacity estimation using Coulomb Counting
slow_hand
slow_hand 2022년 12월 5일
Hi,
Using the expression presented above the aim is to evaluate that formula in order to match the real SOC (obtained from BMS data) with the one calculated estimating the nominal battery capacity (with CC). When the two plots are in match, the C_max is estimated.

댓글을 달려면 로그인하십시오.

채택된 답변

Askic V
Askic V 2022년 11월 17일
Hello Mateo,
I don't think there is a problem in your code. It seems that you used correct way to perform numerical integration.
I have examined your data with the following script:
clear all
clc
close all
load data_R1_15-11-2022.mat
subplot(3, 1, 1)
plot(Tempo, Corrente);
xlabel('Tempo')
ylabel('Corrente');
title('data\_R1\_15-11-2022');
clear % clear variable from previous load
subplot(3,1,2)
load R1_02_nov.mat
Tempo = Tempo_ext_R1;
plot(Tempo, Corrente);
xlabel('Tempo')
ylabel('Corrente');
title('R1\_02nov');
clear % clear variable from previous load
subplot(3,1,3)
load R1_19_ott.mat
Tempo = Tempo_ext_R1;
Corrente = Corrente_ext_R1;
plot(Tempo, Corrente);
xlabel('Tempo')
ylabel('Corrente');
title('R1\_19\_ott');
and the results are shown in the following figure. It seems that you have an unusual spikes in the current. So the difference can be because of the data you used for estimation.
  댓글 수: 3
Askic V
Askic V 2022년 11월 17일
Just out of curiosity, why do you think this is an error, if you integrate the real measured data?
I have found this info:
If the battery is being discharged very quickly (i.e., the discharge current is high), then the amount of energy that can be extracted from the battery is reduced and the battery capacity is lower.
The source:
So your estimation based on integration of real data confirm this.
slow_hand
slow_hand 2022년 11월 17일
Looking at the SOC formulation, I thought that the nominal capacity is an intrinsic parameter of the battery, so the maximum amount of charge inside the battery itself should be the same in every experiments, or at least I'm not expecting a big change like in this case. For what I've seen, changing the discharge current will change the so called "C-rate" so the amount of time where the battery capacity can be used.
But the text you've linked talks about lower battery capacity in this case, so probably I'm wrong. I'm going to investigate more about this.
Thank you for your time :)

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Askic V
Askic V 2022년 11월 16일
Try to add the following line immediately before lsqnonlin call
rng default
I cannot test it myself, because your function use variable 'Time' that is not defined (perhaps global).
  댓글 수: 1
slow_hand
slow_hand 2022년 11월 16일
Thank you for the answer. I've added the data, sorry for forgetting about it.
I've tried this change, but unfortunately the results are the same..

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Estimators​에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by