// Dieser Modus ist ein Hauptschaltermodus mit Secondary Protection // Secondary Protection löst aus, wenn OVP und LVP wegfällt. // OVP und LVP fällt wegbei: // - Sehr tiefe Entladung // - Sehr hohe Spannung // - Übertemperatur // - je nach Liproeinstellung möglicherweise auch wenn sowohl Untertemperaturschutz für Ladung und für Last erreicht ist // - je nach Liproeinstellung möglicherweise auch wenn sowohl Überttemperaturschutz für Ladung und für Last erreicht ist // - Die letzten beiden Positionen können vielleicht ungewollt sein. // OVP UND LVP Signal gleichzeitig: // Es wurde eine Verzögerung von ca. 30 Sekunden implementiert. So kann noch problemlos ein Testjumper auf die Lipro gesteckt werden und die // einzelnennen Funktionen zu prüfen. Außerdem ist es eventuell für die Prametrierung hilfreich, wenn nicht sofort ausgeht // Auch wäre es hilfreich um zum Beispiel die Ursache über Modbus abfragen heruas zu bekommen // // Fault Input: // Hier ohne Verzögerung um schnell auf kurzschluss reagieren zu können // Ansonsten wie Modus 0 #include "stdio.h" #include "mode_lvp_ovp.h" #include "button.h" #include "relais.h" #include "main.h" #include "leds.h" #include "buzzer.h" #include "chip_temperature.h" typedef enum LVP_OVP_State_enum { LVP_OVP_OFF, LVP_OVP_ON, LVP_OVP_MANUAL_ON, LVP_OVP_ERROR } LVP_OVP_state_t; static LVP_OVP_state_t smState; static void LVP_OVP_SM_Off(void) { int faultInput; if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET) { faultInput = 1; } else { faultInput = 0; } //Prüfe auf Wechsel des Modus AUTO / SM ON if (BUTTON_GetMode() == BUTTON_AUTO) { if (faultInput == 0) { RELAIS_SetPuls(); BUZZER_Beep(BUZZER_ON_TIME_CONFIRM); LEDS_GN_Blink_Start(LED_GN_ON_TIME_ON_MODE, LED_GN_OFF_TIME); printf("LVP_OVP_SM_Off: NEW_STATE: LVP_OVP_ON\n"); smState = LVP_OVP_ON; } else { //Wechsel nicht möglich. Fehler Eingang aktiv BUZZER_Beep(BUZZER_ON_TIME_REJECT); BUTTON_SetModeOff(); //LEDS_RT_Blink_Start(LED_RT_ON_TIME_WARN_FAULT_INPUT, LED_GN_OFF_TIME); //Fehler Anzeigen 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 printf("LVP_OVP_SM_Off: NEW_STATE: LVP_OVP_ERROR_FAULT_INPUT\n"); smState =LVP_OVP_ERROR; } } //Prüfe auf Wechsel in MANUAL ON Mode //Keine Fehlerüberprüfungen. In diesem Modus werdem alle Alarme ignoriert. if (BUTTON_GetMode() == BUTTON_MANUAL_ON) { RELAIS_SetPuls(); BUZZER_Alarm_Start(BUZZER_ON_TIME_ALARM_MANUAL_MODE, BUZZER_OFF_TIME); LEDS_GN_On(); 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 printf("NEW_STATE: LVP_OVP_MANUAL_ON\n"); smState = LVP_OVP_MANUAL_ON; } } static void LVP_OVP_SM_On(void) { int faultInput = 0; static int lvpOROvpInput = 0; static int lvpAndOvpInputTimeCounter = 0; static int oldtime; if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET) { faultInput = 1; } else { faultInput = 0; } 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)) { if (HAL_GetTick() != oldtime) { if (lvpAndOvpInputTimeCounter < 5000)lvpAndOvpInputTimeCounter++; if (lvpAndOvpInputTimeCounter >= 5000) { lvpOROvpInput = 1; lvpAndOvpInputTimeCounter=0; } oldtime = HAL_GetTick(); } } if ((HAL_GPIO_ReadPin(GPIO_INPUT_LVP_GPIO_Port, GPIO_INPUT_LVP_Pin) == GPIO_PIN_RESET) && (HAL_GPIO_ReadPin(GPIO_INPUT_OVP_GPIO_Port, GPIO_INPUT_OVP_Pin) == GPIO_PIN_RESET)) { // if (HAL_GetTick() != oldtime) // { // lvpAndOvpInputTimeCounter++; // if (lvpAndOvpInputTimeCounter > 30000) // { lvpOROvpInput = 0; lvpAndOvpInputTimeCounter=0; // } // oldtime = HAL_GetTick(); // } } //Prüfe auf Fehlermode if (faultInput == 1) { RELAIS_ResetPuls(); BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung LEDS_GN_Off(); 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 BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird printf("FAULT INPUT EVENT DETECTED!\n"); printf("NEW_STATE: LVP_OVP_ERROR\n"); smState = LVP_OVP_ERROR; } if (CHIP_TEMPERATURE_GetTemp() > 80) { RELAIS_ResetPuls(); BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung LEDS_GN_Off(); 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 BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird printf("NEW_STATE: MAINSWITCH_ERROR, Temp too high\n"); smState = LVP_OVP_ERROR; } //LVP oder OVP hat stattgefunden, und Relais ist ein, dann aus if ((lvpOROvpInput == 1) && (RELAIS_GetState() == 1)) { RELAIS_ResetPuls(); BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung LEDS_GN_Off(); 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 printf("LVP OR OVP OFF!\n"); printf("NEW_STATE: LVP_OVP_Auto On, Relais off\n"); } //KEIN LVP und keine OVP Abschaltung, Relais ist aber noch aus, dann einschalten if ((lvpOROvpInput == 0) && (RELAIS_GetState() == 0)) { RELAIS_SetPuls(); BUZZER_Beep(BUZZER_ON_TIME_CONFIRM); //Warnung LEDS_GN_Off(); LEDS_GN_Blink_Start(LED_GN_ON_TIME_ON_MODE, LED_GN_OFF_TIME); printf("LVP AND OVP ON!\n"); printf("NEW_STATE: LVP_OVP_Auto On, Relais on\n"); } // Prüfe Wechsel in off mode if (BUTTON_GetMode() == BUTTON_OFF) { //Ausschalten muss immer möglich sein RELAIS_ResetPuls(); BUZZER_Beep(BUZZER_ON_TIME_CONFIRM); //Bestätigung LEDS_GN_Off(); LEDS_RT_Off(); printf("NEW_STATE: LVP_OVP_OFF\n"); smState = LVP_OVP_OFF; //Damit beim drücken auf on erstmal eingeschaltet wird lvpAndOvpInputTimeCounter=0; lvpOROvpInput = 0; } } static void LVP_OVP_SM_ManualOn(void) { // Prüfe Wechsel in off mode if (BUTTON_GetMode() == BUTTON_OFF) { //Ausschalten muss immer möglich sein RELAIS_ResetPuls(); BUZZER_Alarm_Stop(); LEDS_GN_Off(); LEDS_RT_Off(); printf("NEW_STATE: LVP_OVP_OFF\n"); smState = LVP_OVP_OFF; } } static void LVP_OVP_SM_Error(void) { int faultInput; int lvpAndOvpInput; if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET) { faultInput = 1; } else { faultInput = 0; } //Prüfe auf Wechsel des Modus AUTO / SM ON if (BUTTON_GetMode() == BUTTON_AUTO) { if (faultInput == 0) { RELAIS_SetPuls(); BUZZER_Beep(BUZZER_ON_TIME_CONFIRM); LEDS_GN_Blink_Start(LED_GN_ON_TIME_ON_MODE, LED_GN_OFF_TIME); LEDS_RT_Off(); //Fehler löschen printf("NEW_STATE: LVP_OVP_ON\n"); smState = LVP_OVP_ON; } else { //Wechsel nicht möglich. Fehler Eingang weiterhin aktiv BUZZER_Beep(BUZZER_ON_TIME_REJECT); BUTTON_SetModeOff(); } } //Prüfe auf Wechsel in MANUAL ON Mode //Keine Fehlerüberprüfungen. In diesem Modus werdem alle Alarme ignoriert. if (BUTTON_GetMode() == BUTTON_MANUAL_ON) { RELAIS_SetPuls(); BUZZER_Alarm_Start(BUZZER_ON_TIME_ALARM_MANUAL_MODE, BUZZER_OFF_TIME); LEDS_GN_On(); LEDS_RT_Off(); 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 printf("NEW_STATE: LVP_OVP_MANUAL_ON\n"); smState = LVP_OVP_MANUAL_ON; } } void MODE_LVP_OVP_Exec(void) { switch (smState) { case LVP_OVP_OFF: LVP_OVP_SM_Off(); break; case LVP_OVP_ON: LVP_OVP_SM_On(); break; case LVP_OVP_MANUAL_ON: LVP_OVP_SM_ManualOn(); break; case LVP_OVP_ERROR: LVP_OVP_SM_Error(); break; default: break; } }