source: trunk/firmware_v4/SES/src/mode_secondaryprotection.c@ 42

Last change on this file since 42 was 42, checked in by f.jahn, 5 days ago
File size: 10.9 KB
Line 
1
2// Dieser Modus ist ein Hauptschaltermodus mit Secondary Protection
3// Secondary Protection löst aus, wenn OVP und LVP wegfällt.
4// OVP und LVP fällt wegbei:
5// - Sehr tiefe Entladung
6// - Sehr hohe Spannung
7// - Übertemperatur
8// - je nach Liproeinstellung möglicherweise auch wenn sowohl Untertemperaturschutz für Ladung und für Last erreicht ist
9// - je nach Liproeinstellung möglicherweise auch wenn sowohl Überttemperaturschutz für Ladung und für Last erreicht ist
10// - Die letzten beiden Positionen können vielleicht ungewollt sein.
11
12// OVP UND LVP Signal gleichzeitig:
13// Es wurde eine Verzögerung von ca. 30 Sekunden implementiert. So kann noch problemlos ein Testjumper auf die Lipro gesteckt werden und die
14// einzelnennen Funktionen zu prüfen. Außerdem ist es eventuell für die Prametrierung hilfreich, wenn nicht sofort ausgeht
15// Auch wäre es hilfreich um zum Beispiel die Ursache über Modbus abfragen heruas zu bekommen
16
17//
18// Fault Input:
19// Hier ohne Verzögerung um schnell auf kurzschluss reagieren zu können
20// Ansonsten wie Modus 0
21
22
23
24#include "stdio.h"
25#include "mode_secondaryprotection.h"
26#include "button.h"
27#include "relais.h"
28#include "main.h"
29#include "leds.h"
30#include "buzzer.h"
31#include "voltage_meas.h"
32#include "chip_temperature.h"
33
34
35typedef enum SECONDARYPROTECTION_State_enum
36{
37 SECONDARYPROTECTION_OFF,
38 SECONDARYPROTECTION_ON,
39 SECONDARYPROTECTION_MANUAL_ON,
40 SECONDARYPROTECTION_ERROR
41} SECONDARYPROTECTION_state_t;
42
43typedef enum SECONDARYPROTECTION_ErrorState_enum
44{
45 ERROR_NONE,
46 ERROR_EXTERNAL_FAULT, //z.B Kurzschluss
47 ERROR_TEMPERATURE,
48 ERROR_VOLTAGE_DROP,
49 ERROR_LVP_AND_OVP, //z.B. kritische Überspannung, tiefeEntladung
50} SECONDARYPROTECTION_ErrorState_t;
51
52
53static SECONDARYPROTECTION_state_t smState;
54static SECONDARYPROTECTION_ErrorState_t smError;
55static int autoRetryMode;
56
57
58static void SECONDARYPROTECTION_SM_Off(void)
59{
60 int faultInput;
61 int lvpAndOvpInput;
62
63 if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET)
64 {
65 faultInput = 1;
66 }
67 else
68 {
69 faultInput = 0;
70 }
71
72 if ((HAL_GPIO_ReadPin(GPIO_INPUT_LVP_GPIO_Port, GPIO_INPUT_LVP_Pin) == GPIO_PIN_SET) && (HAL_GPIO_ReadPin(GPIO_INPUT_OVP_GPIO_Port, GPIO_INPUT_OVP_Pin) == GPIO_PIN_SET))
73 {
74 lvpAndOvpInput = 1;
75 }else {
76 lvpAndOvpInput = 0;
77 }
78
79
80
81
82 //Prüfe auf Wechsel des Modus AUTO / SM ON
83 if (BUTTON_GetMode() == BUTTON_AUTO)
84 {
85 if (faultInput == 0)
86 {
87 RELAIS_SetPuls();
88 BUZZER_Beep(BUZZER_ON_TIME_CONFIRM);
89 LEDS_GN_Blink_Start(LED_GN_ON_TIME_ON_MODE, LED_GN_OFF_TIME);
90#ifdef DEBUG
91 printf("NEW_STATE: SECONDARYPROTECTION_ON\n");
92#endif
93 smState = SECONDARYPROTECTION_ON;
94 smError = ERROR_NONE;
95
96 }
97 else
98 {
99 //Wechsel nicht möglich. Fehler Eingang aktiv
100 BUZZER_Beep(BUZZER_ON_TIME_REJECT);
101 BUTTON_SetModeOff();
102 //LEDS_RT_Blink_Start(LED_RT_ON_TIME_WARN_FAULT_INPUT, LED_GN_OFF_TIME); //Fehler Anzeigen
103 LEDS_RT_BlinkCode_Start(BLINK_CODE_ERROR_FAULT_INPUT, LED_RT_ON_TIME_WARN_FAULT_INPUT, LED_RT_OFF_TIME, LED_RT_OFF_TIME *5); //Fehler Anzeigen
104#ifdef DEBUG
105 printf("NEW_STATE: SECONDARYPROTECTION_ERROR\n");
106#endif
107 smState =SECONDARYPROTECTION_ERROR;
108 smError = ERROR_EXTERNAL_FAULT;
109 }
110 }
111
112
113 //Prüfe auf Wechsel in MANUAL ON Mode
114 //Keine Fehlerüberprüfungen. In diesem Modus werdem alle Alarme ignoriert.
115 if (BUTTON_GetMode() == BUTTON_MANUAL_ON)
116 {
117
118 RELAIS_SetPuls();
119 BUZZER_Alarm_Start(BUZZER_ON_TIME_ALARM_MANUAL_MODE, BUZZER_OFF_TIME);
120 LEDS_GN_On();
121 LEDS_RT_BlinkCode_Start(BLINK_CODE_WARN_MANUAL, LED_RT_ON_TIME_WARN_MANUAL_MODE, LED_RT_OFF_TIME, LED_RT_OFF_TIME * 5); //Fehler Anzeigen
122#ifdef DEBUG
123 printf("NEW_STATE: SECONDARYPROTECTION_MANUAL_ON\n");
124#endif
125 smState = SECONDARYPROTECTION_MANUAL_ON;
126 smError = ERROR_NONE;
127 }
128}
129
130static void SECONDARYPROTECTION_SM_On(void)
131{
132 int faultInput = 0;
133 int lvpAndOvpInput = 0;
134 static int lvpAndOvpInputTimeCounter = 0;
135 static int oldtime;
136
137 if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET)
138 {
139 faultInput = 1;
140 RELAIS_ResetPuls();
141 BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
142 LEDS_GN_Off();
143 LEDS_RT_BlinkCode_Start(BLINK_CODE_ERROR_FAULT_INPUT, LED_RT_ON_TIME_WARN_FAULT_INPUT, LED_RT_OFF_TIME, LED_RT_OFF_TIME *5); //Fehler Anzeigen
144 BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird
145#ifdef DEBUG
146 printf("FAULT INPUT EVENT DETECTED!\n");
147 printf("NEW_STATE: SECONDARYPROTECTION_ERROR\n");
148#endif
149 smState = SECONDARYPROTECTION_ERROR;
150 smError = ERROR_EXTERNAL_FAULT;
151 return;
152 }
153 else
154 {
155 faultInput = 0;
156 }
157
158 if ((HAL_GPIO_ReadPin(GPIO_INPUT_LVP_GPIO_Port, GPIO_INPUT_LVP_Pin) == GPIO_PIN_SET) && (HAL_GPIO_ReadPin(GPIO_INPUT_OVP_GPIO_Port, GPIO_INPUT_OVP_Pin) == GPIO_PIN_SET))
159 {
160 if (HAL_GetTick() != oldtime)
161 {
162 lvpAndOvpInputTimeCounter++;
163 if (lvpAndOvpInputTimeCounter > 30000)
164 {
165 lvpAndOvpInput = 1;
166 lvpAndOvpInputTimeCounter=0;
167 }
168 oldtime = HAL_GetTick();
169 }
170 }
171 else
172 {
173 lvpAndOvpInputTimeCounter = 0;
174 lvpAndOvpInput = 0;
175 }
176
177
178
179 // Prüfe Wechsel in off mode
180 if (BUTTON_GetMode() == BUTTON_OFF)
181 {
182 //Ausschalten muss immer möglich sein
183 RELAIS_ResetPuls();
184 BUZZER_Beep(BUZZER_ON_TIME_CONFIRM); //Bestätigung
185 LEDS_GN_Off();
186 LEDS_RT_Off();
187#ifdef DEBUG
188 printf("NEW_STATE: SECONDARYPROTECTION_OFF\n");
189#endif
190 smState = SECONDARYPROTECTION_OFF;
191 }
192
193 //Prüfe auf Fehlermode
194 if (VOLTAGE_MEAS_GetLimitAlarm() == 1)
195 {
196 RELAIS_ResetPuls();
197 BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
198 LEDS_GN_Off();
199 LEDS_RT_BlinkCode_Start(BLINK_CODE_ERROR_VOLTAGE_DROP, LED_RT_ON_TIME_WARN_VOLTAGE_DROP, LED_RT_OFF_TIME, LED_RT_OFF_TIME *5); //Fehler Anzeigen
200 BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird
201#ifdef DEBUG
202 printf("FAULT VOLTAGE DROP DETECTED!\n");
203 printf("NEW_STATE: SECONDARYPROTECTION_ERROR\n");
204#endif
205 smState = SECONDARYPROTECTION_ERROR;
206 smError = ERROR_VOLTAGE_DROP;
207 VOLTAGE_MEAS_ResetCounter(); // Damit Fehlerzähler bei Neustart auf 0
208 }
209
210
211
212 if (lvpAndOvpInput == 1)
213 {
214 RELAIS_ResetPuls();
215 BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
216 LEDS_GN_Off();
217 LEDS_RT_BlinkCode_Start(BLINK_CODE_ERROR_OVP_LVP, LED_RT_ON_TIME_WARN_OVP_AND_LVP_INPUT, LED_RT_OFF_TIME, LED_RT_OFF_TIME *5); //Fehler Anzeigen
218 BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird
219#ifdef DEBUG
220 printf("BMS SECONDARY PROTECTION FAULT EVENT DETECTED (LVP & OVP )!\n");
221 printf("NEW_STATE: SECONDARYPROTECTION_ERROR\n");
222#endif
223 smState = SECONDARYPROTECTION_ERROR;
224 smError = ERROR_LVP_AND_OVP;
225 }
226
227 if (CHIP_TEMPERATURE_GetTemp() > 80)
228 {
229 RELAIS_ResetPuls();
230 BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
231 LEDS_GN_Off();
232 LEDS_RT_BlinkCode_Start(BLINK_CODE_ERROR_TEMP, LED_RT_ON_TIME_WARN_TEMP, LED_GN_OFF_TIME, LED_GN_OFF_TIME *5); //Fehler Anzeigen
233 BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird
234#ifdef DEBUG
235 printf("NEW_STATE: MAINSWITCH_ERROR, Temp too high\n");
236#endif
237 smState = SECONDARYPROTECTION_ERROR;
238 smError = ERROR_TEMPERATURE;
239 }
240
241
242
243}
244
245static void SECONDARYPROTECTION_SM_ManualOn(void)
246{
247
248 int faultInput = 0;
249
250
251 if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET)
252 {
253 faultInput = 1;
254 }
255 else
256 {
257 faultInput = 0;
258 }
259
260 if (faultInput == 1)
261 {
262 RELAIS_ResetPuls();
263 BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
264 LEDS_GN_Off();
265 LEDS_RT_BlinkCode_Start(BLINK_CODE_ERROR_FAULT_INPUT, LED_RT_ON_TIME_WARN_FAULT_INPUT, LED_RT_OFF_TIME, LED_RT_OFF_TIME *5); //Fehler Anzeigen
266 BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird
267#ifdef DEBUG
268 printf("FAULT INPUT EVENT DETECTED!\n");
269 printf("NEW_STATE: SECONDARYPROTECTION_ERROR\n");
270#endif
271 smState = SECONDARYPROTECTION_ERROR;
272 smError = ERROR_EXTERNAL_FAULT;
273 }
274
275
276 // Prüfe Wechsel in off mode
277 if (BUTTON_GetMode() == BUTTON_OFF)
278 {
279 //Ausschalten muss immer möglich sein
280 RELAIS_ResetPuls();
281 BUZZER_Alarm_Stop();
282 LEDS_GN_Off();
283 LEDS_RT_Off();
284#ifdef DEBUG
285 printf("NEW_STATE: SECONDARYPROTECTION_OFF\n");
286#endif
287 smState = SECONDARYPROTECTION_OFF;
288 smError = ERROR_NONE;
289 }
290
291}
292
293static void SECONDARYPROTECTION_SM_Error(void)
294{
295 int faultInput;
296 int lvpAndOvpInput;
297 static uint32_t retry_counter = 0;
298 static uint32_t oldTimeMSTick;
299
300 if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET)
301 {
302 faultInput = 1;
303 }
304 else
305 {
306 faultInput = 0;
307 }
308
309
310
311 //Prüfe auf Wechsel des Modus AUTO / SM ON
312 if (BUTTON_GetMode() == BUTTON_AUTO)
313 {
314 if (faultInput == 0)
315 {
316 RELAIS_SetPuls();
317 BUZZER_Beep(BUZZER_ON_TIME_CONFIRM);
318 LEDS_GN_Blink_Start(LED_GN_ON_TIME_ON_MODE, LED_GN_OFF_TIME);
319 LEDS_RT_Off(); //Fehler löschen
320#ifdef DEBUG
321 printf("NEW_STATE: SECONDARYPROTECTION_ON\n");
322#endif
323 smState = SECONDARYPROTECTION_ON;
324 smError = ERROR_NONE;
325 }
326 else
327 {
328 //Wechsel nicht möglich. Fehler Eingang weiterhin aktiv
329 BUZZER_Beep(BUZZER_ON_TIME_REJECT);
330 BUTTON_SetModeOff();
331 }
332 }
333
334 //Prüfe auf Wechsel in MANUAL ON Mode
335 //Keine Fehlerüberprüfungen. In diesem Modus werdem alle Alarme ignoriert.
336 if (BUTTON_GetMode() == BUTTON_MANUAL_ON)
337 {
338
339 RELAIS_SetPuls();
340 BUZZER_Alarm_Start(BUZZER_ON_TIME_ALARM_MANUAL_MODE, BUZZER_OFF_TIME);
341 LEDS_GN_On();
342 LEDS_RT_Off();
343 LEDS_RT_BlinkCode_Start(BLINK_CODE_WARN_MANUAL, LED_RT_ON_TIME_WARN_MANUAL_MODE, LED_RT_OFF_TIME, LED_RT_OFF_TIME *5); //Fehler Anzeigen
344#ifdef DEBUG
345 printf("NEW_STATE: SECONDARYPROTECTION_MANUAL_ON\n");
346#endif
347 smState = SECONDARYPROTECTION_MANUAL_ON;
348 smError = ERROR_NONE;
349 }
350
351
352 if (autoRetryMode == 1) {
353
354 if (oldTimeMSTick != HAL_GetTick())
355 {
356 oldTimeMSTick = HAL_GetTick();
357 retry_counter++;
358 }
359
360 if (retry_counter > 3600000) // 10 Minuten * 60 * 1000 = 600000 || 60 * 60 * 1000 =3600000
361 {
362 BUTTON_SetModeAuto();
363 retry_counter=0;
364 }
365 }
366}
367
368
369
370void MODE_SECONDARYPROTECTION_Exec(int am)
371{
372
373 autoRetryMode = am;
374
375 switch (smState)
376 {
377 case SECONDARYPROTECTION_OFF:
378 SECONDARYPROTECTION_SM_Off();
379 break;
380
381 case SECONDARYPROTECTION_ON:
382 SECONDARYPROTECTION_SM_On();
383 break;
384
385 case SECONDARYPROTECTION_MANUAL_ON:
386 SECONDARYPROTECTION_SM_ManualOn();
387 break;
388
389 case SECONDARYPROTECTION_ERROR:
390 SECONDARYPROTECTION_SM_Error();
391 break;
392
393 default:
394 break;
395 }
396}
397
398
Note: See TracBrowser for help on using the repository browser.