foxBMS  1.3.0
The foxBMS Battery Management System 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-05-30 (date of last update)
47  * @version v1.3.0
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 /** defines for maximum and minimum SOC */
75 #define MAXIMUM_SOC_PERC (100.0f)
76 #define MINIMUM_SOC_PERC (0.0f)
77 
78 /*========== Static Constant and Variable Definitions =======================*/
79 /** state variable for SOC module */
81  .socInitialized = false,
82  .sensorCcUsed = {REPEAT_U(false, STRIP(BS_NR_OF_STRINGS))},
83  .ccScalingAverage = {REPEAT_U(0.0f, STRIP(BS_NR_OF_STRINGS))},
84  .ccScalingMinimum = {REPEAT_U(0.0f, STRIP(BS_NR_OF_STRINGS))},
85  .ccScalingMaximum = {REPEAT_U(0.0f, STRIP(BS_NR_OF_STRINGS))},
86  .previousTimestamp = {REPEAT_U(0u, STRIP(BS_NR_OF_STRINGS))},
87 };
88 
89 /** local copies of database tables */
90 /**@{*/
92 /**@}*/
93 
94 /*========== Extern Constant and Variable Definitions =======================*/
95 
96 /*========== Static Function Prototypes =====================================*/
97 
98 /**
99  * @brief calculates string SOC in percentage from passed string charge in As
100  * @param[in] charge_As charge in As
101  * @return returns corresponding string SOC in percentage [0.0, 100.0]
102  */
103 static float SOC_GetStringSocPercentageFromCharge(uint32_t charge_As);
104 
105 /**
106  * @brief initializes database and FRAM SOC values via lookup table (average,
107  * minimum and maximum).
108  * @param[out] pTableSoc pointer to database enty with SOC values
109  */
110 static void SOC_RecalibrateViaLookupTable(DATA_BLOCK_SOX_s *pTableSoc);
111 
112 /**
113  * @brief sets SOC value with a parameter between 0.0 and 100.0.
114  * @details limits the SOE value to 0.0 respectively 100.0 if a value outside
115  * of the allowed SOE range is passed. Updates local fram and database
116  * struct but does *NOT* write them
117  * @param[out] pTableSoc pointer to SOC database entry
118  * @param[in] socMinimumValue_perc SOC min value to set
119  * @param[in] socMaximumValue_perc SOC max value to set
120  * @param[in] socAverageValue_perc SOC average value to set
121  * @param[in] stringNumber addressed string
122  */
123 static void SOC_SetValue(
124  DATA_BLOCK_SOX_s *pTableSoc,
125  float socMinimumValue_perc,
126  float socMaximumValue_perc,
127  float socAverageValue_perc,
128  uint8_t stringNumber);
129 
130 /**
131  * @brief Check if all database SOC percentage values are within [0.0, 100.0]
132  * Limits SOC values to limit values if outside of this range.
133  * @param[in,out] pTableSoc pointer to database struct with SOC values
134  * @param[in] stringNumber string that is checked
135  */
136 static void SOC_CheckDatabaseSocPercentageLimits(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber);
137 
138 /**
139  * @brief Set SOC-related values in non-volatile memory
140  * @param[in] pTableSoc pointer to database struct with SOC values
141  * @param[in] stringNumber addressed string
142  */
143 static void SOC_UpdateNvmValues(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber);
144 
145 /*========== Static Function Implementations ================================*/
146 static float SOC_GetStringSocPercentageFromCharge(uint32_t charge_As) {
147  const float charge_mAs = (float)charge_As * UNIT_CONVERSION_FACTOR_1000_FLOAT;
149 }
150 
152  FAS_ASSERT(pTableSoc != NULL_PTR);
153  DATA_BLOCK_MIN_MAX_s tableMinMaxCellVoltages = {.header.uniqueId = DATA_BLOCK_ID_MIN_MAX};
154  DATA_READ_DATA(&tableMinMaxCellVoltages);
155 
156  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
157  SOC_SetValue(
158  pTableSoc,
159  SOC_GetFromVoltage(tableMinMaxCellVoltages.minimumCellVoltage_mV[s]),
160  SOC_GetFromVoltage(tableMinMaxCellVoltages.maximumCellVoltage_mV[s]),
161  SOC_GetFromVoltage(tableMinMaxCellVoltages.averageCellVoltage_mV[s]),
162  s);
163  }
165 }
166 
167 static void SOC_SetValue(
168  DATA_BLOCK_SOX_s *pTableSoc,
169  float socMinimumValue_perc,
170  float socMaximumValue_perc,
171  float socAverageValue_perc,
172  uint8_t stringNumber) {
173  FAS_ASSERT(pTableSoc != NULL_PTR);
174  /* Set database values */
175  pTableSoc->averageSoc_perc[stringNumber] = socAverageValue_perc;
176  pTableSoc->minimumSoc_perc[stringNumber] = socMinimumValue_perc;
177  pTableSoc->maximumSoc_perc[stringNumber] = socMaximumValue_perc;
178 
179  if (soc_state.sensorCcUsed[stringNumber] == true) {
180  /* Current sensor database entry is read before the call of SOC_SetValue */
181  float ccOffset_perc =
183 
184 #if POSITIVE_DISCHARGE_CURRENT == false
185  ccOffset_perc *= (-1.0f);
186 #endif /* POSITIVE_DISCHARGE_CURRENT == false */
187 
188  /* Recalibrate scaling values */
189  soc_state.ccScalingAverage[stringNumber] = pTableSoc->averageSoc_perc[stringNumber] + ccOffset_perc;
190  soc_state.ccScalingMinimum[stringNumber] = pTableSoc->minimumSoc_perc[stringNumber] + ccOffset_perc;
191  soc_state.ccScalingMaximum[stringNumber] = pTableSoc->maximumSoc_perc[stringNumber] + ccOffset_perc;
192  }
193 
194  /* Limit SOC values to [0.0, 100.0] */
195  SOC_CheckDatabaseSocPercentageLimits(pTableSoc, stringNumber);
196 
197  /* Update non-volatile memory values */
198  SOC_UpdateNvmValues(pTableSoc, stringNumber);
199 
201 }
202 
203 static void SOC_CheckDatabaseSocPercentageLimits(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber) {
204  FAS_ASSERT(pTableSoc != NULL_PTR);
205  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
206 
207  if (pTableSoc->averageSoc_perc[stringNumber] > MAXIMUM_SOC_PERC) {
208  pTableSoc->averageSoc_perc[stringNumber] = MAXIMUM_SOC_PERC;
209  }
210  if (pTableSoc->averageSoc_perc[stringNumber] < MINIMUM_SOC_PERC) {
211  pTableSoc->averageSoc_perc[stringNumber] = MINIMUM_SOC_PERC;
212  }
213  if (pTableSoc->minimumSoc_perc[stringNumber] > MAXIMUM_SOC_PERC) {
214  pTableSoc->minimumSoc_perc[stringNumber] = MAXIMUM_SOC_PERC;
215  }
216  if (pTableSoc->minimumSoc_perc[stringNumber] < MINIMUM_SOC_PERC) {
217  pTableSoc->minimumSoc_perc[stringNumber] = MINIMUM_SOC_PERC;
218  }
219  if (pTableSoc->maximumSoc_perc[stringNumber] > MAXIMUM_SOC_PERC) {
220  pTableSoc->maximumSoc_perc[stringNumber] = MAXIMUM_SOC_PERC;
221  }
222  if (pTableSoc->maximumSoc_perc[stringNumber] < MINIMUM_SOC_PERC) {
223  pTableSoc->maximumSoc_perc[stringNumber] = MINIMUM_SOC_PERC;
224  }
225 }
226 
227 static void SOC_UpdateNvmValues(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber) {
228  FAS_ASSERT(pTableSoc != NULL_PTR);
229  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
230  fram_soc.averageSoc_perc[stringNumber] = pTableSoc->averageSoc_perc[stringNumber];
231  fram_soc.minimumSoc_perc[stringNumber] = pTableSoc->minimumSoc_perc[stringNumber];
232  fram_soc.maximumSoc_perc[stringNumber] = pTableSoc->maximumSoc_perc[stringNumber];
233 }
234 
235 /*========== Extern Function Implementations ================================*/
236 
237 void SOC_Init(DATA_BLOCK_SOX_s *pSocValues, bool ccPresent, uint8_t stringNumber) {
238  FAS_ASSERT(pSocValues != NULL_PTR);
239  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
241 
243 
244  if (ccPresent == true) {
245  soc_state.sensorCcUsed[stringNumber] = true;
246 
247  float scalingOffset_perc =
249 
250  if (soc_tableCurrentSensor.currentCounter_As[stringNumber] < 0) {
251  scalingOffset_perc *= (-1.0f);
252  }
253 
254 #if POSITIVE_DISCHARGE_CURRENT == false
255  scalingOffset_perc *= (-1.0f);
256 #endif /* POSITIVE_DISCHARGE_CURRENT == false */
257 
258  soc_state.ccScalingAverage[stringNumber] = fram_soc.averageSoc_perc[stringNumber] + scalingOffset_perc;
259  soc_state.ccScalingMinimum[stringNumber] = fram_soc.minimumSoc_perc[stringNumber] + scalingOffset_perc;
260  soc_state.ccScalingMaximum[stringNumber] = fram_soc.maximumSoc_perc[stringNumber] + scalingOffset_perc;
261 
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  100.0f));
335 
336 #if POSITIVE_DISCHARGE_CURRENT == false
337  deltaSoc_perc *= (-1.0f);
338 #endif /* POSITIVE_DISCHARGE_CURRENT == false */
339 
340  pSocValues->averageSoc_perc[s] = soc_state.ccScalingAverage[s] - deltaSoc_perc;
341  pSocValues->minimumSoc_perc[s] = soc_state.ccScalingMinimum[s] - deltaSoc_perc;
342  pSocValues->maximumSoc_perc[s] = soc_state.ccScalingMaximum[s] - deltaSoc_perc;
343 
344  /* Limit SOC values to [0.0, 100.0] */
346 
347  /* Update values in non-volatile memory */
348  SOC_UpdateNvmValues(pSocValues, s);
349 
351  } /* end check if cc measurement has been updated */
352  }
353  }
354  /* Update database and FRAM value */
356  }
357  }
358 }
359 
360 float SOC_GetFromVoltage(int16_t voltage_mV) {
361  float soc_perc = 0.50f;
362 
363  /* Variables for interpolating LUT value */
364  uint16_t between_high = 0;
365  uint16_t between_low = 0;
366 
367  /* Cell voltages are inserted in LUT in descending order -> start with 1 as we do not want to extrapolate. */
368  for (uint16_t i = 1u; i < bc_stateOfChargeLookupTableLength; i++) {
369  if (voltage_mV < bc_stateOfChargeLookupTable[i].voltage_mV) {
370  between_low = i + 1u;
371  between_high = i;
372  }
373  }
374 
375  /* Interpolate between LUT values, but do not extrapolate LUT! */
376  if (!(((between_high == 0u) && (between_low == 0u)) || /* cell voltage > maximum LUT voltage */
377  (between_low >= bc_stateOfChargeLookupTableLength))) { /* cell voltage < minimum LUT voltage */
378  soc_perc = MATH_LinearInterpolation(
379  (float)bc_stateOfChargeLookupTable[between_low].voltage_mV,
380  bc_stateOfChargeLookupTable[between_low].value,
381  (float)bc_stateOfChargeLookupTable[between_high].voltage_mV,
382  bc_stateOfChargeLookupTable[between_high].value,
383  (float)voltage_mV);
384  } else if ((between_low >= bc_stateOfChargeLookupTableLength)) {
385  /* LUT SOE values are in descending order: cell voltage < minimum LUT voltage */
386  soc_perc = MINIMUM_SOC_PERC;
387  } else {
388  /* cell voltage > maximum LUT voltage */
389  soc_perc = 100.0f;
390  }
391  return soc_perc;
392 }
393 
394 /*========== 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:1274
bms driver header
@ BMS_AT_REST
Definition: bms.h:70
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:241
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:85
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:71
@ FRAM_BLOCK_ID_SOC
Definition: fram_cfg.h:102
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:76
#define STRIP(x)
Definition: general.h:261
#define REPEAT_U(x, n)
Macro that helps to generate a series of literals (for array initializers).
Definition: general.h:249
void SOC_Init(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:237
float SOC_GetFromVoltage(int16_t voltage_mV)
look-up table for SOC initialization
Definition: soc_counting.c:360
void SOC_Calculation(DATA_BLOCK_SOX_s *pSocValues)
periodically called algorithm to calculate state-of-charge (SOC)
Definition: soc_counting.c:280
static SOC_STATE_s soc_state
Definition: soc_counting.c:80
#define MAXIMUM_SOC_PERC
Definition: soc_counting.c:75
static void SOC_UpdateNvmValues(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber)
Set SOC-related values in non-volatile memory.
Definition: soc_counting.c:227
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:151
static DATA_BLOCK_CURRENT_SENSOR_s soc_tableCurrentSensor
Definition: soc_counting.c:91
static float SOC_GetStringSocPercentageFromCharge(uint32_t charge_As)
calculates string SOC in percentage from passed string charge in As
Definition: soc_counting.c:146
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:203
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:167
#define MINIMUM_SOC_PERC
Definition: soc_counting.c:76
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:515
float averageSoc_perc[BS_NR_OF_STRINGS]
Definition: database_cfg.h:513
float minimumSoc_perc[BS_NR_OF_STRINGS]
Definition: database_cfg.h:514
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