source: trunk/firmware_v2/SES/src/mode_secondaryprotection.c@ 38

Last change on this file since 38 was 37, checked in by f.jahn, 11 days ago
File size: 10.7 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 printf("NEW_STATE: SECONDARYPROTECTION_ON\n");
91 smState = SECONDARYPROTECTION_ON;
92 smError = ERROR_NONE;
93
94 }
95 else
96 {
97 //Wechsel nicht möglich. Fehler Eingang aktiv
98 BUZZER_Beep(BUZZER_ON_TIME_REJECT);
99 BUTTON_SetModeOff();
100 //LEDS_RT_Blink_Start(LED_RT_ON_TIME_WARN_FAULT_INPUT, LED_GN_OFF_TIME); //Fehler Anzeigen
101 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
102 printf("NEW_STATE: SECONDARYPROTECTION_ERROR\n");
103 smState =SECONDARYPROTECTION_ERROR;
104 smError = ERROR_EXTERNAL_FAULT;
105 }
106 }
107
108
109 //Prüfe auf Wechsel in MANUAL ON Mode
110 //Keine Fehlerüberprüfungen. In diesem Modus werdem alle Alarme ignoriert.
111 if (BUTTON_GetMode() == BUTTON_MANUAL_ON)
112 {
113
114 RELAIS_SetPuls();
115 BUZZER_Alarm_Start(BUZZER_ON_TIME_ALARM_MANUAL_MODE, BUZZER_OFF_TIME);
116 LEDS_GN_On();
117 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
118 printf("NEW_STATE: SECONDARYPROTECTION_MANUAL_ON\n");
119 smState = SECONDARYPROTECTION_MANUAL_ON;
120 smError = ERROR_NONE;
121 }
122
123
124
125}
126
127static void SECONDARYPROTECTION_SM_On(void)
128{
129 int faultInput = 0;
130 int lvpAndOvpInput = 0;
131 static int lvpAndOvpInputTimeCounter = 0;
132 static int oldtime;
133
134 if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET)
135 {
136 faultInput = 1;
137 RELAIS_ResetPuls();
138 BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
139 LEDS_GN_Off();
140 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
141 BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird
142 printf("FAULT INPUT EVENT DETECTED!\n");
143 printf("NEW_STATE: SECONDARYPROTECTION_ERROR\n");
144 smState = SECONDARYPROTECTION_ERROR;
145 smError = ERROR_EXTERNAL_FAULT;
146 return;
147 }
148 else
149 {
150 faultInput = 0;
151 }
152
153 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))
154 {
155 if (HAL_GetTick() != oldtime)
156 {
157 lvpAndOvpInputTimeCounter++;
158 if (lvpAndOvpInputTimeCounter > 30000)
159 {
160 lvpAndOvpInput = 1;
161 lvpAndOvpInputTimeCounter=0;
162 }
163 oldtime = HAL_GetTick();
164 }
165 }
166 else
167 {
168 lvpAndOvpInputTimeCounter = 0;
169 lvpAndOvpInput = 0;
170 }
171
172
173
174 // Prüfe Wechsel in off mode
175 if (BUTTON_GetMode() == BUTTON_OFF)
176 {
177 //Ausschalten muss immer möglich sein
178 RELAIS_ResetPuls();
179 BUZZER_Beep(BUZZER_ON_TIME_CONFIRM); //Bestätigung
180 LEDS_GN_Off();
181 LEDS_RT_Off();
182 printf("NEW_STATE: SECONDARYPROTECTION_OFF\n");
183 smState = SECONDARYPROTECTION_OFF;
184 }
185
186 //Prüfe auf Fehlermode
187 if (VOLTAGE_MEAS_GetLimitAlarm() == 1)
188 {
189 RELAIS_ResetPuls();
190 BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
191 LEDS_GN_Off();
192 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
193 BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird
194 printf("FAULT VOLTAGE DROP DETECTED!\n");
195 printf("NEW_STATE: SECONDARYPROTECTION_ERROR\n");
196 smState = SECONDARYPROTECTION_ERROR;
197 smError = ERROR_VOLTAGE_DROP;
198 VOLTAGE_MEAS_ResetCounter(); // Damit Fehlerzähler bei Neustart auf 0
199 }
200
201
202
203 if (lvpAndOvpInput == 1)
204 {
205 RELAIS_ResetPuls();
206 BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
207 LEDS_GN_Off();
208 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
209 BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird
210 printf("BMS SECONDARY PROTECTION FAULT EVENT DETECTED (LVP & OVP )!\n");
211 printf("NEW_STATE: SECONDARYPROTECTION_ERROR\n");
212 smState = SECONDARYPROTECTION_ERROR;
213 smError = ERROR_LVP_AND_OVP;
214 }
215
216 if (CHIP_TEMPERATURE_GetTemp() > 80)
217 {
218 RELAIS_ResetPuls();
219 BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
220 LEDS_GN_Off();
221 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
222 BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird
223 printf("NEW_STATE: MAINSWITCH_ERROR, Temp too high\n");
224 smState = SECONDARYPROTECTION_ERROR;
225 smError = ERROR_TEMPERATURE;
226 }
227
228
229
230}
231
232static void SECONDARYPROTECTION_SM_ManualOn(void)
233{
234
235 int faultInput = 0;
236
237
238 if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET)
239 {
240 faultInput = 1;
241 }
242 else
243 {
244 faultInput = 0;
245 }
246
247 if (faultInput == 1)
248 {
249 RELAIS_ResetPuls();
250 BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
251 LEDS_GN_Off();
252 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
253 BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird
254 printf("FAULT INPUT EVENT DETECTED!\n");
255 printf("NEW_STATE: SECONDARYPROTECTION_ERROR\n");
256 smState = SECONDARYPROTECTION_ERROR;
257 smError = ERROR_EXTERNAL_FAULT;
258 }
259
260
261 // Prüfe Wechsel in off mode
262 if (BUTTON_GetMode() == BUTTON_OFF)
263 {
264 //Ausschalten muss immer möglich sein
265 RELAIS_ResetPuls();
266 BUZZER_Alarm_Stop();
267 LEDS_GN_Off();
268 LEDS_RT_Off();
269 printf("NEW_STATE: SECONDARYPROTECTION_OFF\n");
270 smState = SECONDARYPROTECTION_OFF;
271 smError = ERROR_NONE;
272 }
273
274}
275
276static void SECONDARYPROTECTION_SM_Error(void)
277{
278 int faultInput;
279 int lvpAndOvpInput;
280 static uint32_t retry_counter = 0;
281 static uint32_t oldTimeMSTick;
282
283 if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET)
284 {
285 faultInput = 1;
286 }
287 else
288 {
289 faultInput = 0;
290 }
291
292
293
294 //Prüfe auf Wechsel des Modus AUTO / SM ON
295 if (BUTTON_GetMode() == BUTTON_AUTO)
296 {
297 if (faultInput == 0)
298 {
299 RELAIS_SetPuls();
300 BUZZER_Beep(BUZZER_ON_TIME_CONFIRM);
301 LEDS_GN_Blink_Start(LED_GN_ON_TIME_ON_MODE, LED_GN_OFF_TIME);
302 LEDS_RT_Off(); //Fehler löschen
303 printf("NEW_STATE: SECONDARYPROTECTION_ON\n");
304 smState = SECONDARYPROTECTION_ON;
305 smError = ERROR_NONE;
306 }
307 else
308 {
309 //Wechsel nicht möglich. Fehler Eingang weiterhin aktiv
310 BUZZER_Beep(BUZZER_ON_TIME_REJECT);
311 BUTTON_SetModeOff();
312 }
313 }
314
315 //Prüfe auf Wechsel in MANUAL ON Mode
316 //Keine Fehlerüberprüfungen. In diesem Modus werdem alle Alarme ignoriert.
317 if (BUTTON_GetMode() == BUTTON_MANUAL_ON)
318 {
319
320 RELAIS_SetPuls();
321 BUZZER_Alarm_Start(BUZZER_ON_TIME_ALARM_MANUAL_MODE, BUZZER_OFF_TIME);
322 LEDS_GN_On();
323 LEDS_RT_Off();
324 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
325 printf("NEW_STATE: SECONDARYPROTECTION_MANUAL_ON\n");
326 smState = SECONDARYPROTECTION_MANUAL_ON;
327 smError = ERROR_NONE;
328 }
329
330
331 if (autoRetryMode == 1) {
332
333 if (oldTimeMSTick != HAL_GetTick())
334 {
335 oldTimeMSTick = HAL_GetTick();
336 retry_counter++;
337 }
338
339 if (retry_counter > 3600000) // 10 Minuten * 60 * 1000 = 600000 || 60 * 60 * 1000 =3600000
340 {
341 BUTTON_SetModeAuto();
342 retry_counter=0;
343 }
344 }
345}
346
347
348
349void MODE_SECONDARYPROTECTION_Exec(int am)
350{
351
352 autoRetryMode = am;
353
354 switch (smState)
355 {
356 case SECONDARYPROTECTION_OFF:
357 SECONDARYPROTECTION_SM_Off();
358 break;
359
360 case SECONDARYPROTECTION_ON:
361 SECONDARYPROTECTION_SM_On();
362 break;
363
364 case SECONDARYPROTECTION_MANUAL_ON:
365 SECONDARYPROTECTION_SM_ManualOn();
366 break;
367
368 case SECONDARYPROTECTION_ERROR:
369 SECONDARYPROTECTION_SM_Error();
370 break;
371
372 default:
373 break;
374 }
375}
376
377
Note: See TracBrowser for help on using the repository browser.