source: trunk/fw_g473rct/SES/src/wh_counter.c @ 35

Last change on this file since 35 was 35, checked in by f.jahn, 25 hours ago
File size: 7.0 KB
Line 
1/*!
2 *      \file           wh_counter.c
3 *      \author         ECS, Zhambolat Kazharov
4 *      \brief
5 *
6 */
7
8#include <math.h>
9#include <stdint.h>
10
11#include "stm32g4xx_hal.h"
12#include "sysdata.h"
13#include "wh_counter.h"
14
15//static int64_t mWs_AutoMode;
16
17void WH_COUNTER_CalcSoH(void);
18
19
20void WH_COUNTER_Init(void)
21{
22  sys_data.s.values.mWs_AutoMode =   (int32_t)-sys_data.s.parameter.battEnergy * 3600;;
23}
24
25
26//------------------------------------------------------------------------------
27
28/*!
29 *      \brief  Calculates Wh periodically (1s)
30 *
31 *                      Must be called every second
32 *
33 */
34
35void WH_COUNTER_Exec(void) {
36
37  static uint64_t totalDischarge = 0;
38  static uint64_t totalCharge = 0;
39
40  if (totalDischarge == 0) totalDischarge = sys_data.s.values.dischargeTotalWh * 3600000;
41  if (totalCharge == 0) totalCharge = sys_data.s.values.chargeTotalWh * 3600000;
42
43  double cefwh;
44//  if (sys_data.s.values.calculatedCEFWh <= 0)
45//  {
46        cefwh =  sys_data.s.parameter.cefW / 1000.0;
47 // }
48 // else
49 // {
50//      cefwh =  sys_data.s.values.calculatedCEFWh / 1000.0;
51//  }
52 
53  double realStrom;
54  realStrom = (int32_t) sys_data.s.values.batteryCurrent - sys_data.s.parameter.extraDischargeStrom_mA;
55
56  //------------ separater CEF -----------
57  // bei Strom größer 0 -> Ladestrom CEF rechnen
58  if (realStrom >= 0) {// 99 --> 99% --> 0.99
59    sys_data.s.values.correctedStromForChargeWhCnt = (realStrom * cefwh * (sys_data.s.values.peukertRemoveCorrectionFaktor / 1000.0)) ;   
60  } 
61  else 
62  {
63    sys_data.s.values.correctedStromForChargeWhCnt = sys_data.s.values.batteryCurrentCorrected;
64  }
65
66  // mW = (mA * mV) / 1000
67  int64_t i_mA = sys_data.s.values.correctedStromForChargeWhCnt;
68  int64_t v_mV = sys_data.s.values.batteryVoltage;
69  int64_t p_mW = (i_mA * v_mV) / 1000LL;
70
71  int64_t E_mWh = (int64_t)sys_data.s.parameter.battEnergy;
72  int64_t battEnergy_mWs = E_mWh * 3600LL; // Umrechnung mWh zu mWs
73
74  // Aufsummieren
75  sys_data.s.values.mWsCounter += p_mW; // Energy value for both positive and negative currents
76  sys_data.s.values.mWs_AutoMode += p_mW;
77 
78  if (sys_data.s.values.soc > 0)
79  {
80        sys_data.s.values.mWsCounterUncorrected +=  ((int64_t) realStrom * sys_data.s.values.batteryVoltage )/ 1000LL;
81  }
82
83  // Begrenzen, Batterie darf nicht über 100% gehen
84  if (sys_data.s.values.mWsCounter > battEnergy_mWs) {
85    sys_data.s.values.mWsCounter = battEnergy_mWs;
86  }
87
88  // Autmode Zähler, zählen von 0 Rückwärts und sollen nicht über 0 steigen
89  if (sys_data.s.values.mWs_AutoMode > 0) {
90    sys_data.s.values.mWs_AutoMode = 0;
91  }
92
93  sys_data.s.values.mWh_AutoMode = sys_data.s.values.mWs_AutoMode / 3600LL;
94  sys_data.s.values.mWhCounter = sys_data.s.values.mWsCounter / 3600LL;
95
96  // Counting Total Power
97  if (sys_data.s.values.batteryPower < 0)
98  {
99          totalDischarge += -sys_data.s.values.batteryPower;
100          sys_data.s.values.dischargeTotalWh = totalDischarge / 3600000; //Umrechnung von mWs auf Wh   
101  }
102  else
103  {
104          totalCharge += sys_data.s.values.batteryPower;
105          sys_data.s.values.chargeTotalWh = totalCharge / 3600000; //Umrechnung von mWs auf Wh
106  }
107}
108
109//------------------------------------------------------------------------------
110
111void WH_COUNTER_SetDetectedEnergy(void) {
112  sys_data.s.values.detectedEnergy = sys_data.s.values.mWh_AutoMode >= 0 ? sys_data.s.values.mWh_AutoMode : -sys_data.s.values.mWh_AutoMode;
113  WH_COUNTER_CalcSoH();
114}
115
116//------------------------------------------------------------------------------
117
118/*!
119 *      \brief  Returns Soc in m%
120 *
121 *      \return SoC value in m%
122 */
123
124int32_t WH_COUNTER_GetSoCManual(void) {
125  int64_t E_mWh = sys_data.s.parameter.battEnergy;
126  int64_t battEnergy_mWs = E_mWh * 3600LL;
127
128  int64_t SoC = 0LL;
129  if (battEnergy_mWs != 0LL)
130    SoC = (100000LL * sys_data.s.values.mWsCounter) / battEnergy_mWs;
131  else
132    SoC = 0LL;
133
134  return (int32_t)SoC;
135}
136
137//------------------------------------------------------------------------------
138
139/*!
140 *      \brief  Returns Soc in m%
141 *
142 *      \return SoC value in m%
143 */
144
145int32_t WH_COUNTER_GetSoCAuto(void) {
146  // int64_t E_mWh = sys_data.s.parameter.cellEnergy;
147  // int64_t cellEnergy_mWs = E_mWh * 3600LL;
148  const int64_t _100mPercent = 100000LL;
149
150  int64_t mWh_AutoMode = sys_data.s.values.mWh_AutoMode < 0 ? -sys_data.s.values.mWh_AutoMode : 0;
151  int64_t SoC = 0LL;
152  if (sys_data.s.values.detectedEnergy <= 0)
153  {
154    SoC = _100mPercent - (_100mPercent * mWh_AutoMode) / (int64_t)sys_data.s.parameter.battEnergy;
155  }
156  else
157  {
158    SoC = _100mPercent - (_100mPercent * mWh_AutoMode) / (int64_t)sys_data.s.values.detectedEnergy;
159  }
160
161  if (SoC > _100mPercent)
162    SoC = _100mPercent;
163  else if (SoC <= 0LL)
164    SoC = 0LL;
165
166  return (int32_t)SoC;
167}
168
169
170int32_t WH_COUNTER_GetSoCAutoTemp(void) {
171  // int64_t E_mWh = sys_data.s.parameter.cellEnergy;
172  // int64_t cellEnergy_mWs = E_mWh * 3600LL;
173  const int64_t _100mPercent = 100000LL;
174  int32_t SoC = 0LL;
175
176  // Verbleibene mAh
177  int64_t rmAh;
178  if (sys_data.s.values.detectedEnergy <= 0)
179  {
180    rmAh = sys_data.s.parameter.cellCapacity - (-sys_data.s.values.mAh_AutoMode); // 40000
181  }
182  else {
183    rmAh = sys_data.s.values.detectedCapacity - (-sys_data.s.values.mAh_AutoMode); // 40000
184  }
185
186
187  // verbleibene Energie
188  // dazu zunächst den Mittelwert der noch verbleibenden Spannung vom aktuellen Zeitpunkt bis zur Abschaltung ermittelndazu
189  int64_t avgVoltage = (sys_data.s.values.batteryVoltage + sys_data.s.values.uBatEmptyTempComp) / 2;
190
191
192  //Jetzt mit der verbleibene Kapazität die verbleibene Energie unter den aktuellen Bedingungen ermitteln (Spannung bei akt. Temp)
193  int64_t rP = (rmAh * avgVoltage) / 1000LL;
194
195
196  if (sys_data.s.values.detectedEnergy > 0)
197  {
198    SoC = (_100mPercent * rP) / sys_data.s.values.detectedEnergy;
199  }
200  else {
201    SoC = (_100mPercent * rP) / sys_data.s.parameter.battEnergy;
202  }
203
204
205  if (SoC > _100mPercent)
206    SoC = _100mPercent;
207  else if (SoC <= 0LL)
208    SoC = 0LL;
209
210  return SoC;
211}
212
213//------------------------------------------------------------------------------
214
215void WH_COUNTER_SetToMax(void) {
216  int64_t E_mWh = sys_data.s.parameter.battEnergy;
217  int64_t battEnergy_mWs = E_mWh * 3600LL;
218
219  sys_data.s.values.mWsCounter = battEnergy_mWs;
220
221  sys_data.s.values.mWs_AutoMode = 0LL;
222  sys_data.s.values.mWh_AutoMode = 0;
223
224  sys_data.s.values.lastTimeVbatFull = 0U;
225}
226
227//------------------------------------------------------------------------------
228
229void WH_COUNTER_CalcSoH(void)
230{
231        const int64_t _promille = 1000LL;
232
233        if (sys_data.s.values.detectedCapacity < 0) sys_data.s.values.SoH = -1; // SoH was not yet calculated
234        else
235        {
236                uint32_t detectedCapacity_mAh = sys_data.s.values.detectedCapacity;
237
238                if (detectedCapacity_mAh >= sys_data.s.parameter.cellCapacity) sys_data.s.values.SoH = (int32_t)_promille;
239                else
240                {
241                        if (sys_data.s.parameter.cellCapacity == 0U)
242                                sys_data.s.values.SoH = -1;
243                        else
244                                sys_data.s.values.SoH = (int32_t)((_promille * (int64_t)detectedCapacity_mAh) / (int64_t)sys_data.s.parameter.cellCapacity);
245                }
246        }
247}
Note: See TracBrowser for help on using the repository browser.