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

Last change on this file since 28 was 28, checked in by f.jahn, 3 months ago
File size: 6.8 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.cef / 100.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) ;
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
79 // Begrenzen, Batterie darf nicht über 100% gehen
80 if (sys_data.s.values.mWsCounter > battEnergy_mWs) {
81 sys_data.s.values.mWsCounter = battEnergy_mWs;
82 }
83
84 // Autmode Zähler, zählen von 0 Rückwärts und sollen nicht über 0 steigen
85 if (sys_data.s.values.mWs_AutoMode > 0) {
86 sys_data.s.values.mWs_AutoMode = 0;
87 }
88
89 sys_data.s.values.mWh_AutoMode = sys_data.s.values.mWs_AutoMode / 3600LL;
90 sys_data.s.values.mWhCounter = sys_data.s.values.mWsCounter / 3600LL;
91
92 // Counting Total Power
93 if (sys_data.s.values.batteryPower < 0)
94 {
95 totalDischarge += -sys_data.s.values.batteryPower;
96 sys_data.s.values.dischargeTotalWh = totalDischarge / 3600000; //Umrechnung von mWs auf Wh
97 }
98 else
99 {
100 totalCharge += sys_data.s.values.batteryPower;
101 sys_data.s.values.chargeTotalWh = totalCharge / 3600000; //Umrechnung von mWs auf Wh
102 }
103}
104
105//------------------------------------------------------------------------------
106
107void WH_COUNTER_SetDetectedEnergy(void) {
108 sys_data.s.values.detectedEnergy = sys_data.s.values.mWh_AutoMode >= 0 ? sys_data.s.values.mWh_AutoMode : -sys_data.s.values.mWh_AutoMode;
109 WH_COUNTER_CalcSoH();
110}
111
112//------------------------------------------------------------------------------
113
114/*!
115 * \brief Returns Soc in m%
116 *
117 * \return SoC value in m%
118 */
119
120int32_t WH_COUNTER_GetSoCManual(void) {
121 int64_t E_mWh = sys_data.s.parameter.battEnergy;
122 int64_t battEnergy_mWs = E_mWh * 3600LL;
123
124 int64_t SoC = 0LL;
125 if (battEnergy_mWs != 0LL)
126 SoC = (100000LL * sys_data.s.values.mWsCounter) / battEnergy_mWs;
127 else
128 SoC = 0LL;
129
130 return (int32_t)SoC;
131}
132
133//------------------------------------------------------------------------------
134
135/*!
136 * \brief Returns Soc in m%
137 *
138 * \return SoC value in m%
139 */
140
141int32_t WH_COUNTER_GetSoCAuto(void) {
142 // int64_t E_mWh = sys_data.s.parameter.cellEnergy;
143 // int64_t cellEnergy_mWs = E_mWh * 3600LL;
144 const int64_t _100mPercent = 100000LL;
145
146 int64_t mWh_AutoMode = sys_data.s.values.mWh_AutoMode < 0 ? -sys_data.s.values.mWh_AutoMode : 0;
147 int64_t SoC = 0LL;
148 if (sys_data.s.values.detectedEnergy <= 0)
149 {
150 SoC = _100mPercent - (_100mPercent * mWh_AutoMode) / (int64_t)sys_data.s.parameter.battEnergy;
151 }
152 else
153 {
154 SoC = _100mPercent - (_100mPercent * mWh_AutoMode) / (int64_t)sys_data.s.values.detectedEnergy;
155 }
156
157 if (SoC > _100mPercent)
158 SoC = _100mPercent;
159 else if (SoC <= 0LL)
160 SoC = 0LL;
161
162 return (int32_t)SoC;
163}
164
165
166int32_t WH_COUNTER_GetSoCAutoTemp(void) {
167 // int64_t E_mWh = sys_data.s.parameter.cellEnergy;
168 // int64_t cellEnergy_mWs = E_mWh * 3600LL;
169 const int64_t _100mPercent = 100000LL;
170 int32_t SoC = 0LL;
171
172 // Verbleibene mAh
173 int64_t rmAh;
174 if (sys_data.s.values.detectedEnergy <= 0)
175 {
176 rmAh = sys_data.s.parameter.cellCapacity - (-sys_data.s.values.mAh_AutoMode); // 40000
177 }
178 else {
179 rmAh = sys_data.s.values.detectedCapacity - (-sys_data.s.values.mAh_AutoMode); // 40000
180 }
181
182
183 // verbleibene Energie
184 // dazu zunächst den Mittelwert der noch verbleibenden Spannung vom aktuellen Zeitpunkt bis zur Abschaltung ermittelndazu
185 int64_t avgVoltage = (sys_data.s.values.batteryVoltage + sys_data.s.values.uBatEmptyTempComp) / 2;
186
187
188 //Jetzt mit der verbleibene Kapazität die verbleibene Energie unter den aktuellen Bedingungen ermitteln (Spannung bei akt. Temp)
189 int64_t rP = (rmAh * avgVoltage) / 1000LL;
190
191
192 if (sys_data.s.values.detectedEnergy > 0)
193 {
194 SoC = (_100mPercent * rP) / sys_data.s.values.detectedEnergy;
195 }
196 else {
197 SoC = (_100mPercent * rP) / sys_data.s.parameter.battEnergy;
198 }
199
200
201 if (SoC > _100mPercent)
202 SoC = _100mPercent;
203 else if (SoC <= 0LL)
204 SoC = 0LL;
205
206 return SoC;
207}
208
209//------------------------------------------------------------------------------
210
211void WH_COUNTER_SetToMax(void) {
212 int64_t E_mWh = sys_data.s.parameter.battEnergy;
213 int64_t battEnergy_mWs = E_mWh * 3600LL;
214
215 sys_data.s.values.mWsCounter = battEnergy_mWs;
216
217 sys_data.s.values.mWs_AutoMode = 0LL;
218 sys_data.s.values.mWh_AutoMode = 0;
219
220 sys_data.s.values.lastTimeVbatFull = 0U;
221}
222
223//------------------------------------------------------------------------------
224
225void WH_COUNTER_CalcSoH(void)
226{
227 const int64_t _promille = 1000LL;
228
229 if (sys_data.s.values.detectedCapacity < 0) sys_data.s.values.SoH = -1; // SoH was not yet calculated
230 else
231 {
232 uint32_t detectedCapacity_mAh = sys_data.s.values.detectedCapacity;
233
234 if (detectedCapacity_mAh >= sys_data.s.parameter.cellCapacity) sys_data.s.values.SoH = (int32_t)_promille;
235 else
236 {
237 if (sys_data.s.parameter.cellCapacity == 0U)
238 sys_data.s.values.SoH = -1;
239 else
240 sys_data.s.values.SoH = (int32_t)((_promille * (int64_t)detectedCapacity_mAh) / (int64_t)sys_data.s.parameter.cellCapacity);
241 }
242 }
243}
Note: See TracBrowser for help on using the repository browser.