├── HPPC_LFP.zip ├── Model_1RC.m ├── Model_2RC.m ├── ObjectiveFunction.m ├── Model_1RCwH.m └── Least_Squares.m /HPPC_LFP.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmtran95/Battery-HPPC-model-fitting/HEAD/HPPC_LFP.zip -------------------------------------------------------------------------------- /Model_1RC.m: -------------------------------------------------------------------------------- 1 | %% A model that takes a single current value and calculates the voltage 2 | % response 3 | % Inputs - current: the current value going into the cell 4 | % - tSample: the time sample for the data points 5 | % - xPrev: The previous state values for Vrc 6 | % - ocvVotlage: The open circuit voltage for the cell. 7 | % - ECM_Parameters: The parameters of the ECM (r1, r2, C, Capacity) 8 | 9 | % Outputs - vModel: The model voltage for the cell at a particular current 10 | % input 11 | % - XTimUp: The updated state values for Vrc 12 | 13 | 14 | function [vModel,XTimUp] = Model_1RC (current, tSample, xPrev, ocvVoltage, ECM_Parameters) 15 | 16 | % Model Parameters 17 | r0 = ECM_Parameters(1); 18 | r1 = ECM_Parameters(2); 19 | c1 = ECM_Parameters(3); 20 | 21 | tau1 = r1*c1; 22 | 23 | %% State Time Update 24 | XTimUp = exp(-tSample/(tau1))*xPrev + r1*(1-exp(-tSample/tau1))*current; 25 | 26 | %% The voltage response from the model 27 | vModel = ocvVoltage-XTimUp-r0*current; 28 | 29 | end -------------------------------------------------------------------------------- /Model_2RC.m: -------------------------------------------------------------------------------- 1 | %% A model that takes a single current value and calculates the voltage 2 | % response 3 | % Inputs - current: the current value going into the cell 4 | % - tSample: the time sample for the data points 5 | % - xPrev: The previous state values for Vrc 6 | % - ocvVotlage: The open circuit voltage for the cell. 7 | % - ECM_Parameters: The parameters of the ECM (r1, r2, C, Capacity) 8 | 9 | % Outputs - vModel: The model voltage for the cell at a particular current 10 | % input 11 | % - XTimUp: The updated state values for Vrc 12 | 13 | 14 | function [vModel,XTimUp1,XTimUp2] = Model_2RC (current, tSample, xPrev1,xPrev2, ocvVoltage, ECM_Parameters) 15 | 16 | % Model Parameters 17 | r0 = ECM_Parameters(1); 18 | r1 = ECM_Parameters(2); 19 | c1 = ECM_Parameters(3); 20 | r2 = ECM_Parameters(4); 21 | c2 = ECM_Parameters(5); 22 | 23 | tau1 = r1*c1; 24 | tau2 = r2*c2; 25 | 26 | %% State Time Update 27 | XTimUp1 = exp(-tSample/(tau1))*xPrev1 + r1*(1-exp(-tSample/tau1))*current; 28 | XTimUp2 = exp(-tSample/(tau2))*xPrev2 + r2*(1-exp(-tSample/tau2))*current; 29 | 30 | %% The voltage response from the model 31 | vModel = ocvVoltage-XTimUp1-XTimUp2-r0*current; 32 | 33 | end -------------------------------------------------------------------------------- /ObjectiveFunction.m: -------------------------------------------------------------------------------- 1 | %% The objective function for the least square algorithm 2 | 3 | function [vModel] = ObjectiveFunction(ECM_parameters, input, ocvVoltage, xNew,model) 4 | 5 | time = input(:,1); 6 | current = input(:,2); 7 | 8 | %% Using the initial terminal voltage as the OCV voltage. 9 | vModel = zeros(length(current),1); 10 | vModel(1) = ocvVoltage(1); 11 | 12 | if model == 1 13 | for i = 2:length(current) 14 | [vModel(i),xNew(i)] = Model_1RC (current(i), (time(i)-time(i-1)), xNew(i-1), ocvVoltage, ECM_parameters) ; 15 | end 16 | end 17 | 18 | if model == 2 19 | for i = 2:length(current) 20 | [vModel(i),xNew(1,i),xNew(2,i)] = Model_2RC (current(i), (time(i)-time(i-1)), xNew(1,i-1),xNew(2,i-1), ocvVoltage, ECM_parameters) ; 21 | end 22 | end 23 | 24 | if model == 3 25 | for i = 2:length(current) 26 | [vModel(i),xNew(1,i),xNew(2,i)] = Model_1RCwH (current(i), (time(i)-time(i-1)), xNew(1,i-1),xNew(2,i-1), ocvVoltage, ECM_parameters) ; 27 | end 28 | end 29 | 30 | if model == 4 31 | for i = 2:length(current) 32 | [vModel(i),xNew(1,i),xNew(2,i),xNew(3,i)] = Model_2RCwH (current(i), (time(i)-time(i-1)), xNew(1,i-1),xNew(2,i-1),xNew(3,i-1), ocvVoltage, ECM_parameters) ; 33 | end 34 | end 35 | 36 | end -------------------------------------------------------------------------------- /Model_1RCwH.m: -------------------------------------------------------------------------------- 1 | %% A model that takes a single current value and calculates the voltage 2 | % response 3 | % Inputs - current: the current value going into the cell 4 | % - tSample: the time sample for the data points 5 | % - xPrev: The previous state values for Vrc 6 | % - ocvVotlage: The open circuit voltage for the cell. 7 | % - ECM_Parameters: The parameters of the ECM (r1, r2, C, Capacity) 8 | 9 | % Outputs - vModel: The model voltage for the cell at a particular current 10 | % input 11 | % - XTimUp: The updated state values for Vrc 12 | 13 | 14 | function [vModel,XTimUp,hk] = Model_1RCwH (current, tSample, xPrev, hkPrev, ocvVoltage, ECM_Parameters) 15 | 16 | % Model Parameters 17 | r0 = ECM_Parameters(1); 18 | r1 = ECM_Parameters(2); 19 | c1 = ECM_Parameters(3); 20 | k = ECM_Parameters(4); 21 | H = ECM_Parameters(5); 22 | 23 | tau1 = r1*c1; 24 | 25 | %% State Time Update 26 | XTimUp = exp(-tSample/(tau1))*xPrev + r1*(1-exp(-tSample/tau1))*current; 27 | if current == 0 28 | signH = 1; 29 | else 30 | signH = -current/abs(current); 31 | end 32 | hk = exp(-abs(k*current*tSample))*hkPrev + (1-exp(-abs(k*current*tSample)))*H*signH; 33 | 34 | %% The voltage response from the model 35 | vModel = ocvVoltage-XTimUp-r0*current+hk; 36 | 37 | end -------------------------------------------------------------------------------- /Least_Squares.m: -------------------------------------------------------------------------------- 1 | %% Jan 2020 2 | % Code for estimating the ECM model parameters from HPPC tests 3 | % Input is HPPC data that is a cell with n HPPC tests 4 | % Each HPPC tests has one column of time (s), then current (in A), and voltage 5 | % (in V) 6 | % The HPPC test should start with the first element being the cell at rest 7 | % before the 1C discharge. 8 | % The test assumes that the SOC does not change within the hppc window 9 | 10 | %% Parameters to change in the code 11 | currentLimit = 0.5; % Current above this limit will be considered as 1C current 12 | iniPar = [0.06;0.03;1000]; % 1RC 13 | %iniPar = [0.05;0.05;2000;0.005;800]; % 2RC 14 | %iniPar = [0.05;0.01;1000;0.001;0.1]; % 1RC+H 15 | %iniPar = [0.05;0.01;1500;0.003;200;0.000005;50]; % 2RC+H 16 | 17 | %% Parameters used in algorithm 18 | xIni = 0; % 1RC 19 | %xIni = [0; 0]; % 2RC and 1RC+H 20 | %xIni = [0; 0; 0]; % 2RC+H 21 | [m,n] = size(dataHPPC{1}); 22 | outputPar = zeros(3,n); % %3 - 1RC, 5 - 1RC+H and 2RC, 7 - 2RC+H 23 | modelError = zeros(m,n); 24 | vModel = zeros(m,n); 25 | model = 1; %1 - c1RC, 2 - 2RC, 3 - 1RC+H, 4 - 2RC+H 26 | 27 | %% Running the objective function and solving for the parameters 28 | for i = 1:n 29 | time = dataHPPC{1}(:,i); 30 | current = dataHPPC{2}(:,i); 31 | vExp = dataHPPC{3}(:,i); 32 | % Find the ocvCurve value right before the HPPC test starts 33 | index = find(current>currentLimit); 34 | ocvVoltage = vExp(index(1)-1); 35 | 36 | % Obtaining the parameter estimates 37 | fun = @(beta,x)ObjectiveFunction(beta,x,ocvVoltage,xIni,model); 38 | outputPar(:,i) = nlinfit([time,current],vExp,fun,iniPar); 39 | 40 | % Running the voltage model with the given battery parameters 41 | vModel(:,i) = ObjectiveFunction(outputPar(:,i),[time,current],ocvVoltage,xIni,model); 42 | modelError(:,i) = abs((vModel(:,i) - vExp)./vExp)*100; 43 | 44 | % Plotting scripts for the voltage model 45 | figure 46 | plot(vModel(:,i)) 47 | hold on 48 | plot(vExp) 49 | 50 | %figure 51 | %plot(current) 52 | 53 | end 54 | 55 | %output = {outputPar, vModel, modelError}; 56 | --------------------------------------------------------------------------------