foxBMS  1.1.1
The foxBMS Battery Management System API Documentation
soc_counting.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2021, 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 2021-05-20 (date of last update)
47  * @ingroup APPLICATION
48  * @prefix SOC
49  *
50  * @brief SOC module responsible for calculation of SOC
51  *
52  */
53 
54 /*========== Includes =======================================================*/
55 #include "soc_counting.h"
56 
57 #include "bms.h"
58 #include "database.h"
59 #include "foxmath.h"
60 #include "fram.h"
61 
62 /*========== Macros and Definitions =========================================*/
63 /** This structure contains all the variables relevant for the SOX */
64 typedef struct SOC_STATE {
65  bool socInitialized; /*!< true if the initialization has passed, false otherwise */
66  bool sensorCcUsed[BS_NR_OF_STRINGS]; /*!< bool if coulomb counting functionality from current sensor is used */
67  float ccScalingAverage[BS_NR_OF_STRINGS]; /*!< current sensor offset scaling for average SOC */
68  float ccScalingMinimum[BS_NR_OF_STRINGS]; /*!< current sensor offset scaling value for minimum SOC */
69  float ccScalingMaximum[BS_NR_OF_STRINGS]; /*!< current sensor offset scaling value for maximum SOC */
70  uint32_t previousTimestamp[BS_NR_OF_STRINGS]; /*!< timestamp buffer to check if current/CC data has been updated */
72 
73 /** defines for maximum and minimum SOC */
74 #define MAXIMUM_SOC_PERC (100.0f)
75 #define MINIMUM_SOC_PERC (0.0f)
76 
77 /*========== Static Constant and Variable Definitions =======================*/
78 /** state variable for SOC module */
80  .socInitialized = false,
81  .sensorCcUsed = {REPEAT_U(false, STRIP(BS_NR_OF_STRINGS))},
82  .ccScalingAverage = {REPEAT_U(0.0f, STRIP(BS_NR_OF_STRINGS))},
83  .ccScalingMinimum = {REPEAT_U(0.0f, STRIP(BS_NR_OF_STRINGS))},
84  .ccScalingMaximum = {REPEAT_U(0.0f, STRIP(BS_NR_OF_STRINGS))},
85  .previousTimestamp = {REPEAT_U(0u, STRIP(BS_NR_OF_STRINGS))},
86 };
87 
88 /** local copies of database tables */
89 /**@{*/
91 /**@}*/
92 
93 /*========== Extern Constant and Variable Definitions =======================*/
94 
95 /*========== Static Function Prototypes =====================================*/
96 
97 /**
98  * @brief calculates string SOC in percentage from passed string charge in As
99  * @param[in] charge_As charge in As
100  * @return returns corresponding string SOC in percentage [0.0, 100.0]
101  */
102 static float SOC_GetStringSocPercentageFromCharge(uint32_t charge_As);
103 
104 /**
105  * @brief initializes database and FRAM SOC values via lookup table (average,
106  * minimum and maximum).
107  * @param[out] pTableSoc pointer to database enty with SOC values
108  */
109 static void SOC_RecalibrateViaLookupTable(DATA_BLOCK_SOX_s *pTableSoc);
110 
111 /**
112  * @brief sets SOC value with a parameter between 0.0 and 100.0.
113  * @details limits the SOE value to 0.0 respectively 100.0 if a value outside
114  * of the allowed SOE range is passed. Updates local fram and database
115  * struct but does *NOT* write them
116  * @param[out] pTableSoc pointer to SOC database entry
117  * @param[in] socMinimumValue_perc SOC min value to set
118  * @param[in] socMaximumValue_perc SOC max value to set
119  * @param[in] socAverageValue_perc SOC average value to set
120  * @param[in] stringNumber addressed string
121  */
122 static void SOC_SetValue(
123  DATA_BLOCK_SOX_s *pTableSoc,
124  float socMinimumValue_perc,
125  float socMaximumValue_perc,
126  float socAverageValue_perc,
127  uint8_t stringNumber);
128 
129 /**
130  * @brief Check if all database SOC percentage values are within [0.0, 100.0]
131  * Limits SOC values to limit values if outside of this range.
132  * @param[in,out] pTableSoc pointer to database struct with SOC values
133  * @param[in] stringNumber string that is checked
134  */
135 static void SOC_CheckDatabaseSocPercentageLimits(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber);
136 
137 /**
138  * @brief Set SOC-related values in non-volatile memory
139  * @param[in] pTableSoc pointer to database struct with SOC values
140  * @param[in] stringNumber addressed string
141  */
142 static void SOC_UpdateNvmValues(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber);
143 
144 /*========== Static Function Implementations ================================*/
145 static float SOC_GetStringSocPercentageFromCharge(uint32_t charge_As) {
146  const float charge_mAs = (float)charge_As * UNIT_CONVERSION_FACTOR_1000_FLOAT;
148 }
149 
151  FAS_ASSERT(pTableSoc != NULL_PTR);
152  DATA_BLOCK_MIN_MAX_s tableMinMaxCellVoltages = {.header.uniqueId = DATA_BLOCK_ID_MIN_MAX};
153  DATA_READ_DATA(&tableMinMaxCellVoltages);
154 
155  for (uint8_t stringNumber = 0u; stringNumber < BS_NR_OF_STRINGS; stringNumber++) {
156  SOC_SetValue(
157  pTableSoc,
158  SOC_GetFromVoltage(tableMinMaxCellVoltages.minimumCellVoltage_mV[stringNumber]),
159  SOC_GetFromVoltage(tableMinMaxCellVoltages.maximumCellVoltage_mV[stringNumber]),
160  SOC_GetFromVoltage(tableMinMaxCellVoltages.averageCellVoltage_mV[stringNumber]),
161  stringNumber);
162  }
164 }
165 
166 static void SOC_SetValue(
167  DATA_BLOCK_SOX_s *pTableSoc,
168  float socMinimumValue_perc,
169  float socMaximumValue_perc,
170  float socAverageValue_perc,
171  uint8_t stringNumber) {
172  FAS_ASSERT(pTableSoc != NULL_PTR);
173  /* Set database values */
174  pTableSoc->averageSoc_perc[stringNumber] = socAverageValue_perc;
175  pTableSoc->minimumSoc_perc[stringNumber] = socMinimumValue_perc;
176  pTableSoc->maximumSoc_perc[stringNumber] = socMaximumValue_perc;
177 
178  if (soc_state.sensorCcUsed[stringNumber] == true) {
179  /* Current sensor database entry is read before the call of SOC_SetValue */
180  float ccOffset_perc =
182 
183 #if POSITIVE_DISCHARGE_CURRENT == false
184  ccOffset_perc *= (-1.0f);
185 #endif /* POSITIVE_DISCHARGE_CURRENT == false */
186 
187  /* Recalibrate scaling values */
188  soc_state.ccScalingAverage[stringNumber] = pTableSoc->averageSoc_perc[stringNumber] + ccOffset_perc;
189  soc_state.ccScalingMinimum[stringNumber] = pTableSoc->minimumSoc_perc[stringNumber] + ccOffset_perc;
190  soc_state.ccScalingMaximum[stringNumber] = pTableSoc->maximumSoc_perc[stringNumber] + ccOffset_perc;
191  }
192 
193  /* Limit SOC values to [0.0, 100.0] */
194  SOC_CheckDatabaseSocPercentageLimits(pTableSoc, stringNumber);
195 
196  /* Update non-volatile memory values */
197  SOC_UpdateNvmValues(pTableSoc, stringNumber);
198 
200 }
201 
202 static void SOC_CheckDatabaseSocPercentageLimits(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber) {
203  FAS_ASSERT(pTableSoc != NULL_PTR);
204  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
205 
206  if (pTableSoc->averageSoc_perc[stringNumber] > MAXIMUM_SOC_PERC) {
207  pTableSoc->averageSoc_perc[stringNumber] = MAXIMUM_SOC_PERC;
208  }
209  if (pTableSoc->averageSoc_perc[stringNumber] < MINIMUM_SOC_PERC) {
210  pTableSoc->averageSoc_perc[stringNumber] = MINIMUM_SOC_PERC;
211  }
212  if (pTableSoc->minimumSoc_perc[stringNumber] > MAXIMUM_SOC_PERC) {
213  pTableSoc->minimumSoc_perc[stringNumber] = MAXIMUM_SOC_PERC;
214  }
215  if (pTableSoc->minimumSoc_perc[stringNumber] < MINIMUM_SOC_PERC) {
216  pTableSoc->minimumSoc_perc[stringNumber] = MINIMUM_SOC_PERC;
217  }
218  if (pTableSoc->maximumSoc_perc[stringNumber] > MAXIMUM_SOC_PERC) {
219  pTableSoc->maximumSoc_perc[stringNumber] = MAXIMUM_SOC_PERC;
220  }
221  if (pTableSoc->maximumSoc_perc[stringNumber] < MINIMUM_SOC_PERC) {
222  pTableSoc->maximumSoc_perc[stringNumber] = MINIMUM_SOC_PERC;
223  }
224 }
225 
226 static void SOC_UpdateNvmValues(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber) {
227  FAS_ASSERT(pTableSoc != NULL_PTR);
228  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
229  fram_soc.averageSoc_perc[stringNumber] = pTableSoc->averageSoc_perc[stringNumber];
230  fram_soc.minimumSoc_perc[stringNumber] = pTableSoc->minimumSoc_perc[stringNumber];
231  fram_soc.maximumSoc_perc[stringNumber] = pTableSoc->maximumSoc_perc[stringNumber];
232 }
233 
234 /*========== Extern Function Implementations ================================*/
235 
236 void SOC_Init(DATA_BLOCK_SOX_s *pSocValues, bool ccPresent, uint8_t stringNumber) {
237  FAS_ASSERT(pSocValues != NULL_PTR);
238  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
240 
242 
243  if (ccPresent == true) {
244  soc_state.sensorCcUsed[stringNumber] = true;
245 
246  float scalingOffset_perc =
248 
249  if (soc_tableCurrentSensor.currentCounter_As[stringNumber] < 0) {
250  scalingOffset_perc *= (-1.0f);
251  }
252 
253 #if POSITIVE_DISCHARGE_CURRENT == false
254  scalingOffset_perc *= (-1.0f);
255 #endif /* POSITIVE_DISCHARGE_CURRENT == false */
256 
257  soc_state.ccScalingAverage[stringNumber] = fram_soc.averageSoc_perc[stringNumber] + scalingOffset_perc;
258  soc_state.ccScalingMinimum[stringNumber] = fram_soc.minimumSoc_perc[stringNumber] + scalingOffset_perc;
259  soc_state.ccScalingMaximum[stringNumber] = fram_soc.maximumSoc_perc[stringNumber] + scalingOffset_perc;
260 
261  } else {
263  soc_state.sensorCcUsed[stringNumber] = false;
264  }
265 
266  pSocValues->averageSoc_perc[stringNumber] = fram_soc.averageSoc_perc[stringNumber];
267  pSocValues->minimumSoc_perc[stringNumber] = fram_soc.minimumSoc_perc[stringNumber];
268  pSocValues->maximumSoc_perc[stringNumber] = fram_soc.maximumSoc_perc[stringNumber];
269 
270  SOC_CheckDatabaseSocPercentageLimits(pSocValues, stringNumber);
271 
272  /* Alternatively, SOC can be initialized with {V,SOC} lookup table if available */
273  /* with the function SOC_Init_Lookup_Table() */
274 
275  soc_state.socInitialized = true;
276 }
277 
279  FAS_ASSERT(pSocValues != NULL_PTR);
280  bool continueFunction = true;
281  if (false == soc_state.socInitialized) {
282  /* Exit if SOC not initialized yet */
283  continueFunction = false;
284  }
285 
286  if (true == continueFunction) {
287  /* Read current sensor entry for coulomb/current counting or CC recalibration */
289 
291  /* Recalibrate SOC via LUT */
292  SOC_RecalibrateViaLookupTable(pSocValues);
293  } else {
294  for (uint8_t stringNumber = 0u; stringNumber < BS_NR_OF_STRINGS; stringNumber++) {
295  if (soc_state.sensorCcUsed[stringNumber] == false) {
296  /* check if current measurement has been updated */
297  if (soc_state.previousTimestamp[stringNumber] !=
299  float timestep_s =
300  ((float)(soc_tableCurrentSensor.timestampCurrent[stringNumber] - soc_state.previousTimestamp[stringNumber])) /
301  1000.0f;
302 
303  if (timestep_s > 0.0f) {
304  /* Current in charge direction negative means SOC increasing --> BAT naming, not ROB */
305 
306  float deltaSOC_perc =
307  (((float)soc_tableCurrentSensor.current_mA[stringNumber] * timestep_s) /
309  100.0f / 1000.0f; /* ((mA) * 1s) / 1As) * 100% */
310 
311 #if POSITIVE_DISCHARGE_CURRENT == false
312  deltaSOC_perc *= (-1.0f);
313 #endif /* POSITIVE_DISCHARGE_CURRENT == false */
314 
315  pSocValues->averageSoc_perc[stringNumber] = pSocValues->averageSoc_perc[stringNumber] -
316  deltaSOC_perc;
317  pSocValues->minimumSoc_perc[stringNumber] = pSocValues->minimumSoc_perc[stringNumber] -
318  deltaSOC_perc;
319  pSocValues->maximumSoc_perc[stringNumber] = pSocValues->maximumSoc_perc[stringNumber] -
320  deltaSOC_perc;
321 
322  /* Limit SOC calculation to 0% respectively 100% */
323  SOC_CheckDatabaseSocPercentageLimits(pSocValues, stringNumber);
324 
325  /* Update values in non-volatile memory */
326  SOC_UpdateNvmValues(pSocValues, stringNumber);
327  }
328  soc_state.previousTimestamp[stringNumber] =
330  } /* end check if current measurement has been updated */
331  /* update the variable for the next check */
332  } else {
333  /* check if cc measurement has been updated */
334  if (soc_state.previousTimestamp[stringNumber] !=
336  float deltaSoc_perc =
338  100.0f));
339 
340 #if POSITIVE_DISCHARGE_CURRENT == false
341  deltaSoc_perc *= (-1.0f);
342 #endif /* POSITIVE_DISCHARGE_CURRENT == false */
343 
344  pSocValues->averageSoc_perc[stringNumber] = soc_state.ccScalingAverage[stringNumber] -
345  deltaSoc_perc;
346  pSocValues->minimumSoc_perc[stringNumber] = soc_state.ccScalingMinimum[stringNumber] -
347  deltaSoc_perc;
348  pSocValues->maximumSoc_perc[stringNumber] = soc_state.ccScalingMaximum[stringNumber] -
349  deltaSoc_perc;
350 
351  /* Limit SOC values to [0.0, 100.0] */
352  SOC_CheckDatabaseSocPercentageLimits(pSocValues, stringNumber);
353 
354  /* Update values in non-volatile memory */
355  SOC_UpdateNvmValues(pSocValues, stringNumber);
356 
357  soc_state.previousTimestamp[stringNumber] =
359  } /* end check if cc measurement has been updated */
360  }
361  }
362  /* Update database and FRAM value */
364  }
365  }
366 }
367 
368 float SOC_GetFromVoltage(int16_t voltage_mV) {
369  float soc_perc = 0.50f;
370 
371  /* Variables for interpolating LUT value */
372  uint16_t between_high = 0;
373  uint16_t between_low = 0;
374 
375  /* Cell voltages are inserted in LUT in descending order -> start with 1 as we do not want to extrapolate. */
376  for (uint16_t i = 1u; i < bc_stateOfChargeLookupTableLength; i++) {
377  if (voltage_mV < bc_stateOfChargeLookupTable[i].voltage_mV) {
378  between_low = i + 1u;
379  between_high = i;
380  }
381  }
382 
383  /* Interpolate between LUT values, but do not extrapolate LUT! */
384  if (!(((0u == between_high) && (0u == between_low)) || /* cell voltage > maximum LUT voltage */
385  (between_low >= bc_stateOfChargeLookupTableLength))) { /* cell voltage < minimum LUT voltage */
386  soc_perc = MATH_linearInterpolation(
387  (float)bc_stateOfChargeLookupTable[between_low].voltage_mV,
388  bc_stateOfChargeLookupTable[between_low].value,
389  (float)bc_stateOfChargeLookupTable[between_high].voltage_mV,
390  bc_stateOfChargeLookupTable[between_high].value,
391  (float)voltage_mV);
392  } else if ((between_low >= bc_stateOfChargeLookupTableLength)) {
393  /* LUT SOE values are in descending order: cell voltage < minimum LUT voltage */
394  soc_perc = MINIMUM_SOC_PERC;
395  } else {
396  /* cell voltage > maximum LUT voltage */
397  soc_perc = 100.0f;
398  }
399  return soc_perc;
400 }
401 
402 /*========== Externalized Static Function Implementations (Unit Test) =======*/
uint16_t bc_stateOfChargeLookupTableLength
const BC_LUT_s bc_stateOfChargeLookupTable[]
#define BS_NR_OF_STRINGS
BMS_CURRENT_FLOW_STATE_e BMS_GetBatterySystemState(void)
Returns current battery system state (charging/discharging, resting or in relaxation phase)
Definition: bms.c:1272
bms driver header
@ BMS_AT_REST
Definition: bms.h:69
Database module header.
#define DATA_READ_DATA(...)
Definition: database.h:76
@ DATA_BLOCK_ID_MIN_MAX
Definition: database_cfg.h:75
@ DATA_BLOCK_ID_CURRENT_SENSOR
Definition: database_cfg.h:76
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:237
float MATH_linearInterpolation(float x1, float y1, float x2, float y2, float x_interpolate)
Linear inter-/extrapolates a third point according to two given points.
Definition: foxmath.c:69
math library for often used math functions
#define UNIT_CONVERSION_FACTOR_1000_FLOAT
Definition: foxmath.h:75
#define UNIT_CONVERSION_FACTOR_100_FLOAT
Definition: foxmath.h:74
STD_RETURN_TYPE_e FRAM_Read(FRAM_BLOCK_ID_e blockId)
Reads a variable from the FRAM.
Definition: fram.c:160
STD_RETURN_TYPE_e FRAM_Write(FRAM_BLOCK_ID_e blockId)
Writes a variable to the FRAM.
Definition: fram.c:101
Header for the driver for the FRAM module.
FRAM_SOC_s fram_soc
Definition: fram_cfg.c:70
@ FRAM_BLOCK_ID_SOC
Definition: fram_cfg.h:89
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:66
#define STRIP(x)
Definition: general.h:268
#define REPEAT_U(x, n)
Macro that helps to generate a series of literals (for array initializers).
Definition: general.h:256
static SOC_STATE_s soc_state
Definition: soc_counting.c:79
#define MAXIMUM_SOC_PERC
Definition: soc_counting.c:74
static void SOC_UpdateNvmValues(DATA_BLOCK_SOX_s *pTableSoc, uint8_t stringNumber)
Set SOC-related values in non-volatile memory.
Definition: soc_counting.c:226
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:236
struct SOC_STATE SOC_STATE_s
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:150
static DATA_BLOCK_CURRENT_SENSOR_s soc_tableCurrentSensor
Definition: soc_counting.c:90
float SOC_GetFromVoltage(int16_t voltage_mV)
look-up table for SOC initialization
Definition: soc_counting.c:368
static float SOC_GetStringSocPercentageFromCharge(uint32_t charge_As)
calculates string SOC in percentage from passed string charge in As
Definition: soc_counting.c:145
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:202
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:166
void SOC_Calculation(DATA_BLOCK_SOX_s *pSocValues)
periodically called algorithm to calculate state-of-charge (SOC)
Definition: soc_counting.c:278
#define MINIMUM_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
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:110
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:215
uint32_t timestampCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:220
int32_t current_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:216
int32_t currentCounter_As[BS_NR_OF_STRINGS]
Definition: database_cfg.h:228
uint32_t timestampCurrentCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:231
int16_t maximumCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:168
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:163
int16_t averageCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:165
int16_t minimumCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:166
float minimumSoc_perc[BS_NR_OF_STRINGS]
Definition: database_cfg.h:495
float averageSoc_perc[BS_NR_OF_STRINGS]
Definition: database_cfg.h:494
float maximumSoc_perc[BS_NR_OF_STRINGS]
Definition: database_cfg.h:496
float minimumSoc_perc[BS_NR_OF_STRINGS]
Definition: fram_cfg.h:120
float maximumSoc_perc[BS_NR_OF_STRINGS]
Definition: fram_cfg.h:121
float averageSoc_perc[BS_NR_OF_STRINGS]
Definition: fram_cfg.h:122
bool socInitialized
Definition: soc_counting.c:65
float ccScalingMaximum[BS_NR_OF_STRINGS]
Definition: soc_counting.c:69
bool sensorCcUsed[BS_NR_OF_STRINGS]
Definition: soc_counting.c:66
float ccScalingMinimum[BS_NR_OF_STRINGS]
Definition: soc_counting.c:68
float ccScalingAverage[BS_NR_OF_STRINGS]
Definition: soc_counting.c:67
uint32_t previousTimestamp[BS_NR_OF_STRINGS]
Definition: soc_counting.c:70