Main Content

Store Hybrid Pulse Power Characterization Data in HPPCTest Object and Analyze and Interact with Test Data

Since R2025a

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);

Figure contains an object of type simscape.battery.parameters.ui.hppcchart.

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);

Figure contains an object of type simscape.battery.parameters.ui.hppcchart.

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)

Figure contains an object of type simscape.battery.parameters.ui.voltageverificationchart.

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

| |

Topics