foxBMS - Unit Tests  1.4.1
The foxBMS Unit Tests API Documentation
soc_counting.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2022, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file soc_counting.c
44  * @author foxBMS Team
45  * @date 2020-10-07 (date of creation)
46  * @updated 2022-10-27 (date of last update)
47  * @version v1.4.1
48  * @ingroup APPLICATION
49  * @prefix SOC
50  *
51  * @brief SOC module responsible for calculation of SOC
52  *
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "soc_counting.h"
57 
58 #include "bms.h"
59 #include "database.h"
60 #include "foxmath.h"
61 #include "fram.h"
62 
63 /*========== Macros and Definitions =========================================*/
64 /** This structure contains all the variables relevant for the SOX */
65 typedef struct {
66  bool socInitialized; /*!< true if the initialization has passed, false otherwise */
67  bool sensorCcUsed[BS_NR_OF_STRINGS]; /*!< bool if coulomb counting functionality from current sensor is used */
68  float ccScalingAverage[BS_NR_OF_STRINGS]; /*!< current sensor offset scaling for average SOC */
69  float ccScalingMinimum[BS_NR_OF_STRINGS]; /*!< current sensor offset scaling value for minimum SOC */
70  float ccScalingMaximum[BS_NR_OF_STRINGS]; /*!< current sensor offset scaling value for maximum SOC */
71  uint32_t previousTimestamp[BS_NR_OF_STRINGS]; /*!< timestamp buffer to check if current/CC data has been updated */
72 } SOC_STATE_s;
73 
74 /** Maximum SOC in percentage */
75 #define SOC_MAXIMUM_SOC_perc (100.0f)
76 /** Minimum SOC in percentage */
77 #define SOC_MINIMUM_SOC_perc (0.0f)
78 
79 /*========== Static Constant and Variable Definitions =======================*/
80 /** state variable for SOC module */
82  .socInitialized = false,
83  .sensorCcUsed = {GEN_REPEAT_U(false, GEN_STRIP(BS_NR_OF_STRINGS))},
84  .ccScalingAverage = {GEN_REPEAT_U(0.0f, GEN_STRIP(BS_NR_OF_STRINGS))},
85  .ccScalingMinimum = {GEN_REPEAT_U(0.0f, GEN_STRIP(BS_NR_OF_STRINGS))},
86  .ccScalingMaximum = {GEN_REPEAT_U(0.0f, GEN_STRIP(BS_NR_OF_STRINGS))},
87  .previousTimestamp = {GEN_REPEAT_U(0u, GEN_STRIP(BS_NR_OF_STRINGS))},
88 };
89 
90 /** local copies of database tables */
91 /**@{*/
93 /**@}*/
94 
95 /*========== Extern Constant and Variable Definitions =======================*/
96 
97 /*========== Static Function Prototypes =====================================*/
98 
99 /**
100  * @brief calculates string SOC in percentage from passed string charge in As
101  * @param[in] charge_As charge in As
102  * @return returns corresponding string SOC in percentage [0.0, 100.0]
103  */
104 static float SOC_GetStringSocPercentageFromCharge(uint32_t charge_As);
105 
106 /**
107  * @brief initializes database and FRAM SOC values via lookup table (average,
108  * minimum and maximum).
109  * @param[out] pTableSoc pointer to database enty with SOC values
110  */
111 static void SOC_RecalibrateViaLookupTable(DATA_BLOCK_SOX_s *pTableSoc);
112 
113 /**
114  * @brief sets SOC value with a parameter between 0.0 and 100.0.
115  * @details limits the SOE value to 0.0 respectively 100.0 if a value outside
116  * of the allowed SOE range is passed. Updates local fram and database
117  * struct but does *NOT* write them
118  * @param[out] pTableSoc pointer to SOC database entry
119  * @param[in] socMinimumValue_perc SOC min value to set
120  * @param[in] socMaximumValue_perc SOC max value to set
121  * @param[in] socAverageValue_perc SOC average value to set
122  * @param[in] stringNumber addressed string
123  */
124 static void SOC_SetValue(
125  DATA_BLOCK_SOX_s *pTableSoc,
126  float socMinimumValue_perc,
127  float socMaximumValue_perc,
128  float socAverageValue_perc,
129  uint8_t stringNumber);
130 
131 /**
132  * @brief Check if all database SOC percentage values are within [0.0, 100.0]
133  * Limits SOC values to limit values if outside of this range.
134  * @param[in,out] pTableSoc pointer to database struct with SOC values
135  * @param[in] stringNumber string that is checked
136  */
137 static void SOC_CheckDatabaseSocPercentageLimits(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber);
138 
139 /**
140  * @brief Set SOC-related values in non-volatile memory
141  * @param[in] pTableSoc pointer to database struct with SOC values
142  * @param[in] stringNumber addressed string
143  */
144 static void SOC_UpdateNvmValues(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber);
145 
146 /*========== Static Function Implementations ================================*/
147 static float SOC_GetStringSocPercentageFromCharge(uint32_t charge_As) {
148  const float charge_mAs = (float)charge_As * UNIT_CONVERSION_FACTOR_1000_FLOAT;
150 }
151 
153  FAS_ASSERT(pTableSoc != NULL_PTR);
154  DATA_BLOCK_MIN_MAX_s tableMinMaxCellVoltages = {.header.uniqueId = DATA_BLOCK_ID_MIN_MAX};
155  DATA_READ_DATA(&tableMinMaxCellVoltages);
156 
157  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
158  SOC_SetValue(
159  pTableSoc,
160  SE_GetStateOfChargeFromVoltage(tableMinMaxCellVoltages.minimumCellVoltage_mV[s]),
161  SE_GetStateOfChargeFromVoltage(tableMinMaxCellVoltages.maximumCellVoltage_mV[s]),
162  SE_GetStateOfChargeFromVoltage(tableMinMaxCellVoltages.averageCellVoltage_mV[s]),
163  s);
164  }
166 }
167 
168 static void SOC_SetValue(
169  DATA_BLOCK_SOX_s *pTableSoc,
170  float socMinimumValue_perc,
171  float socMaximumValue_perc,
172  float socAverageValue_perc,
173  uint8_t stringNumber) {
174  FAS_ASSERT(pTableSoc != NULL_PTR);
175  /* Set database values */
176  pTableSoc->averageSoc_perc[stringNumber] = socAverageValue_perc;
177  pTableSoc->minimumSoc_perc[stringNumber] = socMinimumValue_perc;
178  pTableSoc->maximumSoc_perc[stringNumber] = socMaximumValue_perc;
179 
180  if (soc_state.sensorCcUsed[stringNumber] == true) {
181  /* Current sensor database entry is read before the call of SOC_SetValue */
182  float ccOffset_perc =
184 
185 #if POSITIVE_DISCHARGE_CURRENT == false
186  ccOffset_perc *= (-1.0f);
187 #endif /* POSITIVE_DISCHARGE_CURRENT == false */
188 
189  /* Recalibrate scaling values */
190  soc_state.ccScalingAverage[stringNumber] = pTableSoc->averageSoc_perc[stringNumber] + ccOffset_perc;
191  soc_state.ccScalingMinimum[stringNumber] = pTableSoc->minimumSoc_perc[stringNumber] + ccOffset_perc;
192  soc_state.ccScalingMaximum[stringNumber] = pTableSoc->maximumSoc_perc[stringNumber] + ccOffset_perc;
193  }
194 
195  /* Limit SOC values to [0.0, 100.0] */
196  SOC_CheckDatabaseSocPercentageLimits(pTableSoc, stringNumber);
197 
198  /* Update non-volatile memory values */
199  SOC_UpdateNvmValues(pTableSoc, stringNumber);
200 
202 }
203 
204 static void SOC_CheckDatabaseSocPercentageLimits(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber) {
205  FAS_ASSERT(pTableSoc != NULL_PTR);
206  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
207 
208  if (pTableSoc->averageSoc_perc[stringNumber] > SOC_MAXIMUM_SOC_perc) {
209  pTableSoc->averageSoc_perc[stringNumber] = SOC_MAXIMUM_SOC_perc;
210  }
211  if (pTableSoc->averageSoc_perc[stringNumber] < SOC_MINIMUM_SOC_perc) {
212  pTableSoc->averageSoc_perc[stringNumber] = SOC_MINIMUM_SOC_perc;
213  }
214  if (pTableSoc->minimumSoc_perc[stringNumber] > SOC_MAXIMUM_SOC_perc) {
215  pTableSoc->minimumSoc_perc[stringNumber] = SOC_MAXIMUM_SOC_perc;
216  }
217  if (pTableSoc->minimumSoc_perc[stringNumber] < SOC_MINIMUM_SOC_perc) {
218  pTableSoc->minimumSoc_perc[stringNumber] = SOC_MINIMUM_SOC_perc;
219  }
220  if (pTableSoc->maximumSoc_perc[stringNumber] > SOC_MAXIMUM_SOC_perc) {
221  pTableSoc->maximumSoc_perc[stringNumber] = SOC_MAXIMUM_SOC_perc;
222  }
223  if (pTableSoc->maximumSoc_perc[stringNumber] < SOC_MINIMUM_SOC_perc) {
224  pTableSoc->maximumSoc_perc[stringNumber] = SOC_MINIMUM_SOC_perc;
225  }
226 }
227 
228 static void SOC_UpdateNvmValues(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber) {
229  FAS_ASSERT(pTableSoc != NULL_PTR);
230  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
231  fram_soc.averageSoc_perc[stringNumber] = pTableSoc->averageSoc_perc[stringNumber];
232  fram_soc.minimumSoc_perc[stringNumber] = pTableSoc->minimumSoc_perc[stringNumber];
233  fram_soc.maximumSoc_perc[stringNumber] = pTableSoc->maximumSoc_perc[stringNumber];
234 }
235 
236 /*========== Extern Function Implementations ================================*/
237 
238 void SE_InitializeStateOfCharge(DATA_BLOCK_SOX_s *pSocValues, bool ccPresent, uint8_t stringNumber) {
239  FAS_ASSERT(pSocValues != NULL_PTR);
240  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
242 
244 
245  if (ccPresent == true) {
246  soc_state.sensorCcUsed[stringNumber] = true;
247 
248  float scalingOffset_perc =
250 
251  if (soc_tableCurrentSensor.currentCounter_As[stringNumber] < 0) {
252  scalingOffset_perc *= (-1.0f);
253  }
254 
255 #if POSITIVE_DISCHARGE_CURRENT == false
256  scalingOffset_perc *= (-1.0f);
257 #endif /* POSITIVE_DISCHARGE_CURRENT == false */
258 
259  soc_state.ccScalingAverage[stringNumber] = fram_soc.averageSoc_perc[stringNumber] + scalingOffset_perc;
260  soc_state.ccScalingMinimum[stringNumber] = fram_soc.minimumSoc_perc[stringNumber] + scalingOffset_perc;
261  soc_state.ccScalingMaximum[stringNumber] = fram_soc.maximumSoc_perc[stringNumber] + scalingOffset_perc;
262  } else {
264  soc_state.sensorCcUsed[stringNumber] = false;
265  }
266 
267  pSocValues->averageSoc_perc[stringNumber] = fram_soc.averageSoc_perc[stringNumber];
268  pSocValues->minimumSoc_perc[stringNumber] = fram_soc.minimumSoc_perc[stringNumber];
269  pSocValues->maximumSoc_perc[stringNumber] = fram_soc.maximumSoc_perc[stringNumber];
270 
271  SOC_CheckDatabaseSocPercentageLimits(pSocValues, stringNumber);
272 
273  /* Alternatively, SOC can be initialized with {V,SOC} lookup table if available */
274  /* with the function SOC_Init_Lookup_Table() */
275 
276  soc_state.socInitialized = true;
277 }
278 
279 /* INCLUDE MARKER FOR THE DOCUMENTATION; DO NOT MOVE cc-documentation-start-include */
281  /* INCLUDE MARKER FOR THE DOCUMENTATION; DO NOT MOVE cc-documentation-stop-include */
282  FAS_ASSERT(pSocValues != NULL_PTR);
283  bool continueFunction = true;
284  if (soc_state.socInitialized == false) {
285  /* Exit if SOC not initialized yet */
286  continueFunction = false;
287  }
288 
289  if (continueFunction == true) {
290  /* Read current sensor entry for coulomb/current counting or CC recalibration */
292 
294  /* Recalibrate SOC via LUT */
295  SOC_RecalibrateViaLookupTable(pSocValues);
296  } else {
297  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
298  if (soc_state.sensorCcUsed[s] == false) {
299  /* check if current measurement has been updated */
301  float timeStep_s =
303  1000.0f;
304 
305  if (timeStep_s > 0.0f) {
306  /* Current in charge direction negative means SOC increasing --> BAT naming, not ROB */
307 
308  float deltaSOC_perc =
309  (((float)soc_tableCurrentSensor.current_mA[s] * timeStep_s) / SOC_STRING_CAPACITY_mAs) *
310  100.0f / 1000.0f; /* ((mA) * 1s) / 1As) * 100% */
311 
312 #if POSITIVE_DISCHARGE_CURRENT == false
313  deltaSOC_perc *= (-1.0f);
314 #endif /* POSITIVE_DISCHARGE_CURRENT == false */
315 
316  pSocValues->averageSoc_perc[s] = pSocValues->averageSoc_perc[s] - deltaSOC_perc;
317  pSocValues->minimumSoc_perc[s] = pSocValues->minimumSoc_perc[s] - deltaSOC_perc;
318  pSocValues->maximumSoc_perc[s] = pSocValues->maximumSoc_perc[s] - deltaSOC_perc;
319 
320  /* Limit SOC calculation to 0% respectively 100% */
322 
323  /* Update values in non-volatile memory */
324  SOC_UpdateNvmValues(pSocValues, s);
325  }
327  } /* end check if current measurement has been updated */
328  /* update the variable for the next check */
329  } else {
330  /* check if cc measurement has been updated */
332  float deltaSoc_perc =
334 
335 #if POSITIVE_DISCHARGE_CURRENT == false
336  deltaSoc_perc *= (-1.0f);
337 #endif /* POSITIVE_DISCHARGE_CURRENT == false */
338 
339  pSocValues->averageSoc_perc[s] = soc_state.ccScalingAverage[s] - deltaSoc_perc;
340  pSocValues->minimumSoc_perc[s] = soc_state.ccScalingMinimum[s] - deltaSoc_perc;
341  pSocValues->maximumSoc_perc[s] = soc_state.ccScalingMaximum[s] - deltaSoc_perc;
342 
343  /* Limit SOC values to [0.0, 100.0] */
345 
346  /* Update values in non-volatile memory */
347  SOC_UpdateNvmValues(pSocValues, s);
348 
350  } /* end check if cc measurement has been updated */
351  }
352  }
353  /* Update database and FRAM value */
355  }
356  }
357 }
358 
359 extern float SE_GetStateOfChargeFromVoltage(int16_t voltage_mV) {
360  float soc_perc = 0.50f;
361 
362  /* Variables for interpolating LUT value */
363  uint16_t between_high = 0;
364  uint16_t between_low = 0;
365 
366  /* Cell voltages are inserted in LUT in descending order -> start with 1 as we do not want to extrapolate. */
367  for (uint16_t i = 1u; i < bc_stateOfChargeLookupTableLength; i++) {
368  if (voltage_mV < bc_stateOfChargeLookupTable[i].voltage_mV) {
369  between_low = i + 1u;
370  between_high = i;
371  }
372  }
373 
374  /* Interpolate between LUT values, but do not extrapolate LUT! */
375  if (!(((between_high == 0u) && (between_low == 0u)) || /* cell voltage > maximum LUT voltage */
376  (between_low >= bc_stateOfChargeLookupTableLength))) { /* cell voltage < minimum LUT voltage */
377  soc_perc = MATH_LinearInterpolation(
378  (float)bc_stateOfChargeLookupTable[between_low].voltage_mV,
379  bc_stateOfChargeLookupTable[between_low].value,
380  (float)bc_stateOfChargeLookupTable[between_high].voltage_mV,
381  bc_stateOfChargeLookupTable[between_high].value,
382  (float)voltage_mV);
383  } else if ((between_low >= bc_stateOfChargeLookupTableLength)) {
384  /* LUT SOE values are in descending order: cell voltage < minimum LUT voltage */
385  soc_perc = SOC_MINIMUM_SOC_perc;
386  } else {
387  /* cell voltage > maximum LUT voltage */
388  soc_perc = 100.0f;
389  }
390  return soc_perc;
391 }
392 
393 /*========== Externalized Static Function Implementations (Unit Test) =======*/
uint16_t bc_stateOfChargeLookupTableLength
const BC_LUT_s bc_stateOfChargeLookupTable[]
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
BMS_CURRENT_FLOW_STATE_e BMS_GetBatterySystemState(void)
Returns current battery system state (charging/discharging, resting or in relaxation phase)
Definition: bms.c:1569
bms driver header
@ BMS_AT_REST
Definition: bms.h:72
Database module header.
#define DATA_READ_DATA(...)
Definition: database.h:83
@ DATA_BLOCK_ID_MIN_MAX
Definition: database_cfg.h:78
@ DATA_BLOCK_ID_CURRENT_SENSOR
Definition: database_cfg.h:79
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:248
float MATH_LinearInterpolation(const float x1, const float y1, const float x2, const float y2, const float x_interpolate)
Linear inter-/extrapolates a third point according to two given points.
Definition: foxmath.c:86
math library for often used math functions
#define UNIT_CONVERSION_FACTOR_1000_FLOAT
Definition: foxmath.h:78
#define UNIT_CONVERSION_FACTOR_100_FLOAT
Definition: foxmath.h:77
FRAM_RETURN_TYPE_e FRAM_ReadData(FRAM_BLOCK_ID_e blockId)
Reads a variable from the FRAM.
Definition: fram.c:193
FRAM_RETURN_TYPE_e FRAM_WriteData(FRAM_BLOCK_ID_e blockId)
Writes a variable to the FRAM.
Definition: fram.c:115
Header for the driver for the FRAM module.
FRAM_SOC_s fram_soc
Definition: fram_cfg.c:69
@ FRAM_BLOCK_ID_SOC
Definition: fram_cfg.h:102
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:76
#define GEN_REPEAT_U(x, n)
Macro that helps to generate a series of literals (for array initializers).
Definition: general.h:250
#define GEN_STRIP(x)
Definition: general.h:261
void SE_CalculateStateOfCharge(DATA_BLOCK_SOX_s *pSocValues)
periodically called algorithm to calculate state-of-charge (SOC)
Definition: soc_counting.c:280
void SE_InitializeStateOfCharge(DATA_BLOCK_SOX_s *pSocValues, bool ccPresent, uint8_t stringNumber)
initializes startup SOC-related values like lookup from nonvolatile ram at startup
Definition: soc_counting.c:238
float SE_GetStateOfChargeFromVoltage(int16_t voltage_mV)
look-up table for SOC initialization
Definition: soc_counting.c:359
static SOC_STATE_s soc_state
Definition: soc_counting.c:81
static void SOC_UpdateNvmValues(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber)
Set SOC-related values in non-volatile memory.
Definition: soc_counting.c:228
#define SOC_MINIMUM_SOC_perc
Definition: soc_counting.c:77
static void SOC_RecalibrateViaLookupTable(DATA_BLOCK_SOX_s *pTableSoc)
initializes database and FRAM SOC values via lookup table (average, minimum and maximum).
Definition: soc_counting.c:152
static DATA_BLOCK_CURRENT_SENSOR_s soc_tableCurrentSensor
Definition: soc_counting.c:92
static float SOC_GetStringSocPercentageFromCharge(uint32_t charge_As)
calculates string SOC in percentage from passed string charge in As
Definition: soc_counting.c:147
static void SOC_CheckDatabaseSocPercentageLimits(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber)
Check if all database SOC percentage values are within [0.0, 100.0] Limits SOC values to limit values...
Definition: soc_counting.c:204
static void SOC_SetValue(DATA_BLOCK_SOX_s *pTableSoc, float socMinimumValue_perc, float socMaximumValue_perc, float socAverageValue_perc, uint8_t stringNumber)
sets SOC value with a parameter between 0.0 and 100.0.
Definition: soc_counting.c:168
#define SOC_MAXIMUM_SOC_perc
Definition: soc_counting.c:75
Header for SOC module, responsible for calculation of SOC.
#define SOC_STRING_CAPACITY_As
#define SOC_STRING_CAPACITY_mAs
uint32_t timestampCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:216
int32_t current_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:212
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:211
int32_t currentCounter_As[BS_NR_OF_STRINGS]
Definition: database_cfg.h:224
uint32_t timestampCurrentCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:227
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:119
int16_t averageCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:161
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:159
int16_t maximumCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:164
int16_t minimumCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:162
float maximumSoc_perc[BS_NR_OF_STRINGS]
Definition: database_cfg.h:505
float averageSoc_perc[BS_NR_OF_STRINGS]
Definition: database_cfg.h:503
float minimumSoc_perc[BS_NR_OF_STRINGS]
Definition: database_cfg.h:504
float minimumSoc_perc[BS_NR_OF_STRINGS]
Definition: fram_cfg.h:135
float averageSoc_perc[BS_NR_OF_STRINGS]
Definition: fram_cfg.h:137
float maximumSoc_perc[BS_NR_OF_STRINGS]
Definition: fram_cfg.h:136
float ccScalingMinimum[BS_NR_OF_STRINGS]
Definition: soc_counting.c:69
bool socInitialized
Definition: soc_counting.c:66
uint32_t previousTimestamp[BS_NR_OF_STRINGS]
Definition: soc_counting.c:71
float ccScalingAverage[BS_NR_OF_STRINGS]
Definition: soc_counting.c:68
bool sensorCcUsed[BS_NR_OF_STRINGS]
Definition: soc_counting.c:67
float ccScalingMaximum[BS_NR_OF_STRINGS]
Definition: soc_counting.c:70