Store Hybrid Pulse Power Characterization Data in HPPCTest
Object and Analyze and Interact with Test Data
This examples shows you how to import and store data from hybrid pulse power characterization (HPPC) experimental techniques and interact with the stored data by adding or removing pulses, plotting test voltage, and modifying the state-of-charge (SOC) values of all pulses.
Hybrid Pulse Power Characterization
The HPPC technique involves applying a series of constant current pulses to a battery and measuring its terminal voltage and temperature responses at different operating conditions. Multiple key operating conditions affect the impedance of the cell and the measured voltage response. These operating conditions include:
Initial battery soak temperature
Initial state of charge (SOC)
Current or load
Current directionality such as charge or discharge
State of health (SOH) or remaining capacity
Load frequency
Thermal boundary conditions
The measured voltage response from each current pulse contains valuable information about the impedance of the battery. In turn, this impedance gives you information about the battery performance and power capability.
The HPPC test method is essential for characterizing the direct current internal resistance (DCIR) of a battery, developing dynamic battery models, testing and improving the robustness of battery management systems (BMS), and ensuring that batteries meet the performance requirements of their applications. Several organizations have developed standardized HPPC test procedures to ensure consistency and comparability of the results. These are some of the key industry standards:
USABC (United States Advanced Battery Consortium)
IEC 62660-1 (International Electrotechnical Commission)
SAE J1798 (Society of Automotive Engineers)
ISO 12405-1 (International Organization for Standardization)
Idaho National Lab INL/EXT-15-34184
The typical goal for many of these standards is to obtain an approximation of the maximum current and power that a battery can deliver or accept at a given SOC value or at any of the key operating conditions. This plot shows the dynamic voltage response for lithium-ion batteries from an initial resting state or equilibrium state at mild operating conditions of 25 °C and 90% SOC.
This pulse is repeated across multiple operating points to create lookup tables that map the capabilities of a battery cell.
Load Test Data
Load the required HPPC data obtained for a BAK 2.9 Ah battery cell at 25 °C. This data consists of a table with three columns. The columns of the table refer to time, voltage, and current values, respectively.
load("testDataBAKcells/hppcDataBAKcell25degC.mat")
Store Data in HPPCTest
Object
Simscape™ Battery™ includes objects and functions that allow you to store HPPC data into container objects. You can then use these objects to remove outliers, filter or analyze data, and perform pre- and post-data processing.
Store the HPPC data inside an HPPCTest
object by using the hppcTest
function. You can use this object to view the data, add or edit breakpoints, add or remove pulses, and include additional information such as state of charge and capacity. The HPPC data is a table, so you must also specify each column name by using the TimeVariable
, VoltageVariable
, and CurrentVariable
arguments. These names must match the names of the columns in the hppcData
table.
hppcExp25degC = hppcTest(hppcData,... TimeVariable="time (s)",... VoltageVariable="voltage (V)",... CurrentVariable="current (A)");
Analyze the identified current pulses of the hppcExp
object by using the TestSummary
property. This property contains a summary of the HPPC test that shows all the identified pulses and related data, returned as a table.
hppcExp25degC.TestSummary
ans=18×13 table
PulseID Directionality SOC HPPCData PulseDuration PseudoOCV_V MaximumVoltage MinimumVoltage Current_A C_rate PulseStartIndex PulseEndIndex Temperature_degC
_______ ______________ _______ _________________ _____________ ___________ ______________ ______________ _________ ______ _______________ _____________ ________________
1 "Discharge" 1 {701×6 timetable} 30 4.1745 4.1745 3.7846 -6.1869 1.8976 354 1055 25
2 "Discharge" 0.90376 {701×6 timetable} 30 4.0837 4.0837 3.7479 -6.187 1.8977 2702 3403 25
3 "Discharge" 0.80754 {702×6 timetable} 30 4.0132 4.0132 3.6652 -6.1867 1.8975 5049 5751 25
4 "Discharge" 0.71133 {701×6 timetable} 30 3.9226 3.9226 3.5775 -6.1868 1.8976 7398 8099 25
5 "Discharge" 0.61512 {701×6 timetable} 30 3.846 3.846 3.4942 -6.1868 1.8976 9746 10447 25
6 "Discharge" 0.51891 {701×6 timetable} 30 3.7353 3.7353 3.4001 -6.1871 1.8977 12094 12795 25
7 "Discharge" 0.4227 {701×6 timetable} 30 3.65 3.65 3.3236 -6.1867 1.8975 14442 15143 25
8 "Discharge" 0.32649 {701×6 timetable} 30 3.6015 3.6015 3.2652 -6.1869 1.8976 16790 17491 25
9 "Discharge" 0.23028 {701×6 timetable} 30 3.5507 3.5507 3.1931 -6.1869 1.8976 19138 19839 25
10 "Charge" 0.98415 {502×6 timetable} 10 4.1158 4.3889 4.1158 4.6393 1.423 1055 1557 25
11 "Charge" 0.88793 {502×6 timetable} 10 4.057 4.3001 4.057 4.6406 1.4233 3403 3905 25
12 "Charge" 0.79172 {502×6 timetable} 10 3.9674 4.2113 3.9674 4.6394 1.423 5751 6253 25
13 "Charge" 0.69551 {502×6 timetable} 10 3.8751 4.1175 3.8751 4.6396 1.423 8099 8601 25
14 "Charge" 0.5993 {502×6 timetable} 10 3.7905 4.0355 3.7905 4.6396 1.423 10447 10949 25
15 "Charge" 0.50309 {502×6 timetable} 10 3.6936 3.9339 3.6936 4.6405 1.4233 12795 13297 25
16 "Charge" 0.40688 {502×6 timetable} 10 3.6224 3.8602 3.6224 4.6396 1.423 15143 15645 25
⋮
Plot HPPCTest
Voltage
Plot the entire HPPC test voltage using the plot
function. The plot
function requires the HPPCTest
object you want to plot as input. You can also specify optional name-value arguments, such as the parent container of the chart or the visibility of the charge and discharge pulse indices.
plot(hppcExp25degC,Parent=figure);
The plot
function returns an HPPCChart
object. You can also use the HPPCChart
object directly to view the test data. The output is the same as using the plot
function.
simscape.battery.parameters.ui.HPPCChart(HPPCTest=hppcExp25degC,Parent=figure);
Plot Voltage from Pulse in HPPCTest
Object
If you want to plot the measured voltage for a pulse at a specific index instead of plotting the entire HPPC test voltage, use the plotPulse
function.
For example, plot the data of the sixth pulse. The plotPulse
function requires the HPPCTest object that contains the pulse you want to plot and the index of the pulse to plot as inputs. The plot shows the measured voltage of the sixth pulse in the TestSummary
property table of the hppcExp
object.
plotPulse(hppcExp25degC,6)
Add Single Pulse to HPPCTest
Object
Load the HPPC data obtained for a BAK 2.9 Ah battery cell at 0 °C and store the data inside another HPPCTest
object.
load("testDataBAKcells/hppcDataBAKcell0degC.mat") hppcExp0degC = hppcTest(hppcData,TimeVariable="time (s)",... VoltageVariable="voltage (V)",... CurrentVariable="current (A)",Temperature=zeros(numel(hppcData(:,1)),1));
Retrieve a single pulse from the hppcExp0degC
object.
singlePulse = hppcExp0degC.TestSummary.HPPCData{17}
singlePulse=502×6 timetable
Time Voltage Current Charge Temperature StateOfCharge OpenCircuitVoltage
_________ _______ _______ _______ ___________ _____________ __________________
0 sec 3.5704 0 0.42168 0 0.31068 3.5704
0.134 sec 3.7501 0 0.42168 0 0.31068 3.7501
0.136 sec 3.77 3.8121 0.42168 0 0.31068 3.77
0.236 sec 3.8845 3.9634 0.42179 0 0.31072 3.8845
0.336 sec 3.8922 3.964 0.4219 0 0.31076 3.8922
0.436 sec 3.8959 3.9652 0.42201 0 0.3108 3.8959
0.536 sec 3.8986 3.9644 0.42212 0 0.31084 3.8986
0.636 sec 3.9008 3.964 0.42223 0 0.31088 3.9008
0.736 sec 3.9025 3.9638 0.42234 0 0.31092 3.9025
0.836 sec 3.9041 3.9646 0.42245 0 0.31096 3.9041
0.936 sec 3.9056 3.9642 0.42256 0 0.311 3.9056
1.036 sec 3.9069 3.9648 0.42267 0 0.31104 3.9069
1.136 sec 3.9081 3.9644 0.42278 0 0.31108 3.9081
1.236 sec 3.9091 3.9646 0.42289 0 0.31111 3.9091
1.336 sec 3.9102 3.9642 0.423 0 0.31115 3.9102
1.436 sec 3.9112 3.9656 0.42311 0 0.31119 3.9112
⋮
Add this pulse data to the hppcExp25degC
object by using the addPulseData
function. The inputs of the addPulseData
function are the HPPCTest
object you want to modify and the data of the single pulse you want to add to the test container.
addPulseData(hppcExp25degC,singlePulse)
Analyze the TestSummary
property table. Observe how the table now contains an additional pulse.
hppcExp25degC.TestSummary
ans=19×13 table
PulseID Directionality SOC HPPCData PulseDuration PseudoOCV_V MaximumVoltage MinimumVoltage Current_A C_rate PulseStartIndex PulseEndIndex Temperature_degC
_______ ______________ _______ _________________ _____________ ___________ ______________ ______________ _________ ______ _______________ _____________ ________________
1 "Discharge" 1 {701×6 timetable} 30 4.1745 4.1745 3.7846 -6.1869 1.8976 354 1055 25
2 "Discharge" 0.90376 {701×6 timetable} 30 4.0837 4.0837 3.7479 -6.187 1.8977 2702 3403 25
3 "Discharge" 0.80754 {702×6 timetable} 30 4.0132 4.0132 3.6652 -6.1867 1.8975 5049 5751 25
4 "Discharge" 0.71133 {701×6 timetable} 30 3.9226 3.9226 3.5775 -6.1868 1.8976 7398 8099 25
5 "Discharge" 0.61512 {701×6 timetable} 30 3.846 3.846 3.4942 -6.1868 1.8976 9746 10447 25
6 "Discharge" 0.51891 {701×6 timetable} 30 3.7353 3.7353 3.4001 -6.1871 1.8977 12094 12795 25
7 "Discharge" 0.4227 {701×6 timetable} 30 3.65 3.65 3.3236 -6.1867 1.8975 14442 15143 25
8 "Discharge" 0.32649 {701×6 timetable} 30 3.6015 3.6015 3.2652 -6.1869 1.8976 16790 17491 25
9 "Discharge" 0.23028 {701×6 timetable} 30 3.5507 3.5507 3.1931 -6.1869 1.8976 19138 19839 25
10 "Charge" 0.98415 {502×6 timetable} 10 4.1158 4.3889 4.1158 4.6393 1.423 1055 1557 25
11 "Charge" 0.88793 {502×6 timetable} 10 4.057 4.3001 4.057 4.6406 1.4233 3403 3905 25
12 "Charge" 0.79172 {502×6 timetable} 10 3.9674 4.2113 3.9674 4.6394 1.423 5751 6253 25
13 "Charge" 0.69551 {502×6 timetable} 10 3.8751 4.1175 3.8751 4.6396 1.423 8099 8601 25
14 "Charge" 0.5993 {502×6 timetable} 10 3.7905 4.0355 3.7905 4.6396 1.423 10447 10949 25
15 "Charge" 0.50309 {502×6 timetable} 10 3.6936 3.9339 3.6936 4.6405 1.4233 12795 13297 25
16 "Charge" 0.40688 {502×6 timetable} 10 3.6224 3.8602 3.6224 4.6396 1.423 15143 15645 25
⋮
Remove Pulse from HPPCTest
Object
When a pulse is defective or if there are missing data points or breached cell operating points, you might want to remove it from the HPPC test data. To remove the data of a pulse, you can use the removePulseParameters
function.
For example, remove the first pulse. The inputs of the removePulse
function are the HPPCTest
object you want to modify and the index of the pulse you want to remove in the TestSummary
property table.
removePulse(hppcExp25degC,1)
Analyze the identified pulses of the hppcExp
object again to see the results. The removePulse
function successfully removed the current pulse with state of charge (SOC) equal to 1.
hppcExp25degC.TestSummary
ans=18×13 table
PulseID Directionality SOC HPPCData PulseDuration PseudoOCV_V MaximumVoltage MinimumVoltage Current_A C_rate PulseStartIndex PulseEndIndex Temperature_degC
_______ ______________ _______ _________________ _____________ ___________ ______________ ______________ _________ ______ _______________ _____________ ________________
1 "Discharge" 0.90376 {701×6 timetable} 30 4.0837 4.0837 3.7479 -6.187 1.8977 2702 3403 25
2 "Discharge" 0.80754 {702×6 timetable} 30 4.0132 4.0132 3.6652 -6.1867 1.8975 5049 5751 25
3 "Discharge" 0.71133 {701×6 timetable} 30 3.9226 3.9226 3.5775 -6.1868 1.8976 7398 8099 25
4 "Discharge" 0.61512 {701×6 timetable} 30 3.846 3.846 3.4942 -6.1868 1.8976 9746 10447 25
5 "Discharge" 0.51891 {701×6 timetable} 30 3.7353 3.7353 3.4001 -6.1871 1.8977 12094 12795 25
6 "Discharge" 0.4227 {701×6 timetable} 30 3.65 3.65 3.3236 -6.1867 1.8975 14442 15143 25
7 "Discharge" 0.32649 {701×6 timetable} 30 3.6015 3.6015 3.2652 -6.1869 1.8976 16790 17491 25
8 "Discharge" 0.23028 {701×6 timetable} 30 3.5507 3.5507 3.1931 -6.1869 1.8976 19138 19839 25
9 "Charge" 0.98415 {502×6 timetable} 10 4.1158 4.3889 4.1158 4.6393 1.423 1055 1557 25
10 "Charge" 0.88793 {502×6 timetable} 10 4.057 4.3001 4.057 4.6406 1.4233 3403 3905 25
11 "Charge" 0.79172 {502×6 timetable} 10 3.9674 4.2113 3.9674 4.6394 1.423 5751 6253 25
12 "Charge" 0.69551 {502×6 timetable} 10 3.8751 4.1175 3.8751 4.6396 1.423 8099 8601 25
13 "Charge" 0.5993 {502×6 timetable} 10 3.7905 4.0355 3.7905 4.6396 1.423 10447 10949 25
14 "Charge" 0.50309 {502×6 timetable} 10 3.6936 3.9339 3.6936 4.6405 1.4233 12795 13297 25
15 "Charge" 0.40688 {502×6 timetable} 10 3.6224 3.8602 3.6224 4.6396 1.423 15143 15645 25
16 "Charge" 0.31066 {502×6 timetable} 10 3.5695 3.8109 3.5695 4.6397 1.4231 17491 17993 25
⋮
Modify SOC Values for Discharge and Charge Pulses
If you want to modify the SOC values for either all discharge or charge pulses inside an HPPCTest
object, you can use the setDischargeSOCs
and setChargeSOCs
functions.
For this example, generate two arrays of random numbers. Each array contains the new SOC values for the discharge and charge pulses, respectively.
SOCDischarge = rand(1,8)
SOCDischarge = 1×8
0.8147 0.9058 0.1270 0.9134 0.6324 0.0975 0.2785 0.5469
SOCCharge = rand(1,10)
SOCCharge = 1×10
0.9575 0.9649 0.1576 0.9706 0.9572 0.4854 0.8003 0.1419 0.4218 0.9157
Update the SOC values of all discharge pulses using the setDischargeSOCs
function. The setDischargeSOCs
function requires as inputs the HPPCTest
object you want to modify and a vector that contains the new SOC values.
setDischargeSOCs(hppcExp25degC,SOCDischarge);
Visualize the new discharge SOC values using the TestSummary
property of the hppcExp
object. The setDischargeSOCs
function replaced the first eight values in the SOC column with the values of the SOCDischarge
variable.
hppcExp25degC.TestSummary
ans=18×13 table
PulseID Directionality SOC HPPCData PulseDuration PseudoOCV_V MaximumVoltage MinimumVoltage Current_A C_rate PulseStartIndex PulseEndIndex Temperature_degC
_______ ______________ _______ _________________ _____________ ___________ ______________ ______________ _________ ______ _______________ _____________ ________________
1 "Discharge" 0.91338 {701×6 timetable} 30 4.0837 4.0837 3.7479 -6.187 1.8977 2702 3403 25
2 "Discharge" 0.90579 {702×6 timetable} 30 4.0132 4.0132 3.6652 -6.1867 1.8975 5049 5751 25
3 "Discharge" 0.81472 {701×6 timetable} 30 3.9226 3.9226 3.5775 -6.1868 1.8976 7398 8099 25
4 "Discharge" 0.63236 {701×6 timetable} 30 3.846 3.846 3.4942 -6.1868 1.8976 9746 10447 25
5 "Discharge" 0.54688 {701×6 timetable} 30 3.7353 3.7353 3.4001 -6.1871 1.8977 12094 12795 25
6 "Discharge" 0.2785 {701×6 timetable} 30 3.65 3.65 3.3236 -6.1867 1.8975 14442 15143 25
7 "Discharge" 0.12699 {701×6 timetable} 30 3.6015 3.6015 3.2652 -6.1869 1.8976 16790 17491 25
8 "Discharge" 0.09754 {701×6 timetable} 30 3.5507 3.5507 3.1931 -6.1869 1.8976 19138 19839 25
9 "Charge" 0.98415 {502×6 timetable} 10 4.1158 4.3889 4.1158 4.6393 1.423 1055 1557 25
10 "Charge" 0.88793 {502×6 timetable} 10 4.057 4.3001 4.057 4.6406 1.4233 3403 3905 25
11 "Charge" 0.79172 {502×6 timetable} 10 3.9674 4.2113 3.9674 4.6394 1.423 5751 6253 25
12 "Charge" 0.69551 {502×6 timetable} 10 3.8751 4.1175 3.8751 4.6396 1.423 8099 8601 25
13 "Charge" 0.5993 {502×6 timetable} 10 3.7905 4.0355 3.7905 4.6396 1.423 10447 10949 25
14 "Charge" 0.50309 {502×6 timetable} 10 3.6936 3.9339 3.6936 4.6405 1.4233 12795 13297 25
15 "Charge" 0.40688 {502×6 timetable} 10 3.6224 3.8602 3.6224 4.6396 1.423 15143 15645 25
16 "Charge" 0.31066 {502×6 timetable} 10 3.5695 3.8109 3.5695 4.6397 1.4231 17491 17993 25
⋮
Now update the SOC values for all charge pulses using the setChargeSOCs
function. The setChargeSOCs
function requires as inputs the HPPCTest
object you want to modify and a vector that contains the new SOC values.
setChargeSOCs(hppcExp25degC,SOCCharge);
Visualize the new charge SOC values using the TestSummary
property of the hppcExp
object. The setChargeSOCs
function replaced the last ten values in the SOC column with the values of the SOCCharge
variable.
hppcExp25degC.TestSummary
ans=18×13 table
PulseID Directionality SOC HPPCData PulseDuration PseudoOCV_V MaximumVoltage MinimumVoltage Current_A C_rate PulseStartIndex PulseEndIndex Temperature_degC
_______ ______________ _______ _________________ _____________ ___________ ______________ ______________ _________ ______ _______________ _____________ ________________
1 "Discharge" 0.91338 {701×6 timetable} 30 4.0837 4.0837 3.7479 -6.187 1.8977 2702 3403 25
2 "Discharge" 0.90579 {702×6 timetable} 30 4.0132 4.0132 3.6652 -6.1867 1.8975 5049 5751 25
3 "Discharge" 0.81472 {701×6 timetable} 30 3.9226 3.9226 3.5775 -6.1868 1.8976 7398 8099 25
4 "Discharge" 0.63236 {701×6 timetable} 30 3.846 3.846 3.4942 -6.1868 1.8976 9746 10447 25
5 "Discharge" 0.54688 {701×6 timetable} 30 3.7353 3.7353 3.4001 -6.1871 1.8977 12094 12795 25
6 "Discharge" 0.2785 {701×6 timetable} 30 3.65 3.65 3.3236 -6.1867 1.8975 14442 15143 25
7 "Discharge" 0.12699 {701×6 timetable} 30 3.6015 3.6015 3.2652 -6.1869 1.8976 16790 17491 25
8 "Discharge" 0.09754 {701×6 timetable} 30 3.5507 3.5507 3.1931 -6.1869 1.8976 19138 19839 25
9 "Charge" 0.97059 {502×6 timetable} 10 4.1158 4.3889 4.1158 4.6393 1.423 1055 1557 25
10 "Charge" 0.96489 {502×6 timetable} 10 4.057 4.3001 4.057 4.6406 1.4233 3403 3905 25
11 "Charge" 0.95751 {502×6 timetable} 10 3.9674 4.2113 3.9674 4.6394 1.423 5751 6253 25
12 "Charge" 0.95717 {502×6 timetable} 10 3.8751 4.1175 3.8751 4.6396 1.423 8099 8601 25
13 "Charge" 0.91574 {502×6 timetable} 10 3.7905 4.0355 3.7905 4.6396 1.423 10447 10949 25
14 "Charge" 0.80028 {502×6 timetable} 10 3.6936 3.9339 3.6936 4.6405 1.4233 12795 13297 25
15 "Charge" 0.48538 {502×6 timetable} 10 3.6224 3.8602 3.6224 4.6396 1.423 15143 15645 25
16 "Charge" 0.42176 {502×6 timetable} 10 3.5695 3.8109 3.5695 4.6397 1.4231 17491 17993 25
⋮
Store Multiple HPPCTest
Objects
If you have multiple HPPC data stored in different HPPCTest
objects, you can store all the objects inside a single HPPCTestSuite
object. The HPPCTestSuite
object is a container for storing multiple HPPC tests of type HPPCTest
.
Create an HPPCTestSuite
object that contains the two HPPCTest
objects you created previously in this example by using the hppcTestSuite
function. The HPPCTestSuite
object shows the number of HPPCTest
objects, their temperature, and the number of pulses in each test.
hppcSuite1 = hppcTestSuite([hppcExp0degC;hppcExp25degC]); disp(hppcSuite1.SuiteSummary)
TestID Test Temperature NumPulses ______ ________________________________________ ___________ _________ 1 1×1 simscape.battery.parameters.HPPCTest 0 18 2 1×1 simscape.battery.parameters.HPPCTest 23.611 18
Add HPPCTest
Object to HPPCTestSuite
Object
If you have an existing HPPCTestSuite
object and you want to add the data from another HPPCTest
object, you can use the addHPPCTest
function.
For this example, load the HPPC data obtained for a BAK 2.9 Ah battery cell at 35 °C and store it inside another HPPCTest
object.
load("testDataBAKcells/hppcDataBAKcell35degC.mat") hppcExp35degC = hppcTest(hppcData,TimeVariable="time (s)",... VoltageVariable="voltage (V)",... CurrentVariable="current (A)",... Temperature=repmat(35,numel(hppcData(:,1)),1));
Add the data from this HPPCTest
object to the test container, hppcSuite1
, by using the addHPPCTest
function. The requires input arguments of this function are the HPPCTestSuite
object you want to modify and the HPPCTest
object you want to add to the test suite.
addHPPCTest(hppcSuite1,hppcExp35degC); disp(hppcSuite1.SuiteSummary)
TestID Test Temperature NumPulses ______ ________________________________________ ___________ _________ 1 1×1 simscape.battery.parameters.HPPCTest 0 18 2 1×1 simscape.battery.parameters.HPPCTest 23.611 18 3 1×1 simscape.battery.parameters.HPPCTest 35 18
See Also
hppcTest
| hppcTestSuite
| HPPCChart