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

Last change on this file since 20 was 20, checked in by f.jahn, 4 months ago

adc dma funktioniert und modbus funktioniert

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 //------------ separater CEF -----------
44 // bei Strom größer 0 -> Ladestrom CEF rechnen
45 if (sys_data.s.values.batteryCurrent >= 0) {
46 // 99 --> 99% --> 0.99
47 int32_t cefW = sys_data.s.parameter.cefW;
48 sys_data.s.values.correctedStromForChargeWhCnt = (sys_data.s.values.batteryCurrent * cefW) / 100;
49 sys_data.s.values.correctedStromForChargeWhCnt -= sys_data.s.parameter.extraDischargeStrom_mA;
50 } else {
51 sys_data.s.values.correctedStromForChargeWhCnt = sys_data.s.values.batteryCurrentCorrected;
52 }
53
54 // mW = (mA * mV) / 1000
55 int64_t i_mA = sys_data.s.values.correctedStromForChargeWhCnt;
56 int64_t v_mV = sys_data.s.values.batteryVoltage;
57 int64_t p_mW = (i_mA * v_mV) / 1000LL;
58
59 int64_t E_mWh = (int64_t)sys_data.s.parameter.battEnergy;
60 int64_t battEnergy_mWs = E_mWh * 3600LL; // Umrechnung mWh zu mWs
61
62 // Aufsummieren
63 sys_data.s.values.mWsCounter += p_mW; // Energy value for both positive and negative currents
64 sys_data.s.values.mWs_AutoMode += p_mW;
65
66
67 // Begrenzen, Batterie darf nicht über 100% gehen
68 if (sys_data.s.values.mWsCounter > battEnergy_mWs) {
69 sys_data.s.values.mWsCounter = battEnergy_mWs;
70 }
71
72 // Autmode Zähler, zählen von 0 Rückwärts und sollen nicht über 0 steigen
73 if (sys_data.s.values.mWs_AutoMode > 0) {
74 sys_data.s.values.mWs_AutoMode = 0;
75 }
76
77 sys_data.s.values.mWh_AutoMode = sys_data.s.values.mWs_AutoMode / 3600LL;
78 sys_data.s.values.mWhCounter = sys_data.s.values.mWsCounter / 3600LL;
79
80
81
82
83 // Counting Total Power
84 if (sys_data.s.values.batteryPower < 0)
85 {
86 totalDischarge += -sys_data.s.values.batteryPower;
87 sys_data.s.values.dischargeTotalWh = totalDischarge / 3600000; //Umrechnung von mWs auf Wh
88
89
90 sys_data.s.values.fullCyclesCnt = (uint16_t) ((sys_data.s.values.dischargeTotalAh * 1000) / sys_data.s.parameter.cellCapacity);
91 }
92 else
93 {
94 totalCharge += sys_data.s.values.batteryPower;
95 sys_data.s.values.chargeTotalWh = totalCharge / 3600000; //Umrechnung von mWs auf Wh
96 }
97
98
99
100}
101
102//------------------------------------------------------------------------------
103
104void WH_COUNTER_SetDetectedEnergy(void) {
105 sys_data.s.values.detectedEnergy = sys_data.s.values.mWh_AutoMode >= 0 ? sys_data.s.values.mWh_AutoMode : -sys_data.s.values.mWh_AutoMode;
106 WH_COUNTER_CalcSoH();
107}
108
109//------------------------------------------------------------------------------
110
111/*!
112 * \brief Returns Soc in m%
113 *
114 * \return SoC value in m%
115 */
116
117int32_t WH_COUNTER_GetSoCManual(void) {
118 int64_t E_mWh = sys_data.s.parameter.battEnergy;
119 int64_t battEnergy_mWs = E_mWh * 3600LL;
120
121 int64_t SoC = 0LL;
122 if (battEnergy_mWs != 0LL)
123 SoC = (100000LL * sys_data.s.values.mWsCounter) / battEnergy_mWs;
124 else
125 SoC = 0LL;
126
127 return (int32_t)SoC;
128}
129
130//------------------------------------------------------------------------------
131
132/*!
133 * \brief Returns Soc in m%
134 *
135 * \return SoC value in m%
136 */
137
138int32_t WH_COUNTER_GetSoCAuto(void) {
139 // int64_t E_mWh = sys_data.s.parameter.cellEnergy;
140 // int64_t cellEnergy_mWs = E_mWh * 3600LL;
141 const int64_t _100mPercent = 100000LL;
142
143 int64_t mWh_AutoMode = sys_data.s.values.mWh_AutoMode < 0 ? -sys_data.s.values.mWh_AutoMode : 0;
144 int64_t SoC = 0LL;
145 if (sys_data.s.values.detectedEnergy <= 0)
146 {
147 SoC = _100mPercent - (_100mPercent * mWh_AutoMode) / (int64_t)sys_data.s.parameter.battEnergy;
148 }
149 else
150 {
151 SoC = _100mPercent - (_100mPercent * mWh_AutoMode) / (int64_t)sys_data.s.values.detectedEnergy;
152 }
153
154 if (SoC > _100mPercent)
155 SoC = _100mPercent;
156 else if (SoC <= 0LL)
157 SoC = 0LL;
158
159 return (int32_t)SoC;
160}
161
162int32_t WH_COUNTER_GetSoCAutoTemp(void) {
163 // int64_t E_mWh = sys_data.s.parameter.cellEnergy;
164 // int64_t cellEnergy_mWs = E_mWh * 3600LL;
165 const int64_t _100mPercent = 100000LL;
166 int32_t SoC = 0LL;
167
168 // Verbleibene mAh
169 int64_t rmAh;
170 if (sys_data.s.values.detectedEnergy <= 0)
171 {
172 rmAh = sys_data.s.parameter.cellCapacity - (-sys_data.s.values.mAh_AutoMode); // 40000
173 }
174 else {
175 rmAh = sys_data.s.values.detectedCapacity - (-sys_data.s.values.mAh_AutoMode); // 40000
176 }
177
178
179 // verbleibene Energie
180 // dazu zunächst den Mittelwert der noch verbleibenden Spannung vom aktuellen Zeitpunkt bis zur Abschaltung ermittelndazu
181 int64_t avgVoltage = (sys_data.s.values.batteryVoltage + sys_data.s.values.uBatEmptyTempComp) / 2;
182
183 //Jetzt mit der verbleibene Kapazität die verbleibene Energie unter den aktuellen Bedingungen ermitteln (Spannung bei akt. Temp)
184 int64_t rP = (rmAh * avgVoltage) / 1000LL;
185
186
187 if (sys_data.s.values.detectedEnergy > 0)
188 {
189 SoC = (_100mPercent * rP) / sys_data.s.values.detectedEnergy;
190 }
191 else {
192 SoC = (_100mPercent * rP) / sys_data.s.parameter.battEnergy;
193 }
194
195
196 if (SoC > _100mPercent)
197 SoC = _100mPercent;
198 else if (SoC <= 0LL)
199 SoC = 0LL;
200
201 return SoC;
202}
203
204//------------------------------------------------------------------------------
205
206void WH_COUNTER_SetToMax(void) {
207 int64_t E_mWh = sys_data.s.parameter.battEnergy;
208 int64_t battEnergy_mWs = E_mWh * 3600LL;
209
210 sys_data.s.values.mWsCounter = battEnergy_mWs;
211
212 sys_data.s.values.mWs_AutoMode = 0LL;
213 sys_data.s.values.mWh_AutoMode = 0;
214
215 sys_data.s.values.lastTimeVbatFull = 0U;
216}
217
218//------------------------------------------------------------------------------
219
220void WH_COUNTER_CalcSoH(void)
221{
222 const int64_t _promille = 1000LL;
223
224 if (sys_data.s.values.detectedCapacity < 0) sys_data.s.values.SoH = -1; // SoH was not yet calculated
225 else
226 {
227 uint32_t detectedCapacity_mAh = sys_data.s.values.detectedCapacity;
228
229 if (detectedCapacity_mAh >= sys_data.s.parameter.cellCapacity) sys_data.s.values.SoH = (int32_t)_promille;
230 else
231 {
232 if (sys_data.s.parameter.cellCapacity == 0U)
233 sys_data.s.values.SoH = -1;
234 else
235 sys_data.s.values.SoH = (int32_t)((_promille * (int64_t)detectedCapacity_mAh) / (int64_t)sys_data.s.parameter.cellCapacity);
236 }
237 }
238}
Note: See TracBrowser for help on using the repository browser.