GVL_CONFIG.rMaxAbsDiffVoltageModulesInString THEN _xBalanceOk := FALSE; END_IF // Test module 1 with module 3 IF ABS(_fbModule1.rCurrentVoltage - _fbModule3.rCurrentVoltage) > GVL_CONFIG.rMaxAbsDiffVoltageModulesInString THEN _xBalanceOk := FALSE; END_IF // Test module 2 with module 3 IF ABS(_fbModule2.rCurrentVoltage - _fbModule3.rCurrentVoltage) > GVL_CONFIG.rMaxAbsDiffVoltageModulesInString THEN _xBalanceOk := FALSE; END_IF // Release signal for balance not ok _fbBalanceNotOkSignal( xSignal:= _xBalanceOk OR (NOT xEnable), xRelease:= TRUE, timOnDelay:= T#5S, timOffDelay:= T#60S, xReleaseSignal=> ); // Signal an error if all units are ready and module is out of balance IF _xAllModulesReady AND (NOT _fbBalanceNotOkSignal.xReleaseSignal) THEN xError := TRUE; END_IF // Raise error IF (NOT _fbBalanceNotOkSignal.xReleaseSignal) AND (NOT _fbModulesOutOfBalanceAlarm.bRaised) THEN _fbModulesOutOfBalanceAlarm.Raise(0); END_IF // Clear error IF _fbBalanceNotOkSignal.xReleaseSignal AND _fbModulesOutOfBalanceAlarm.bRaised THEN _fbModulesOutOfBalanceAlarm.Clear(0, FALSE); END_IF // Confirm error IF _fbModulesOutOfBalanceAlarm.eConfirmationState = TcEventConfirmationState.WaitForConfirmation AND xConfirmAlarms THEN _fbModulesOutOfBalanceAlarm.Confirm(0); END_IF // =============================== // String ready validation check // =============================== _tonResetPulseLength(); _tonErrorDCCBNotClosed(); CASE _iState OF 0: // Idle IF _xAllModulesReady AND _xBalanceOk AND xAllModulesInAutoMode AND xEnable THEN xCloseDCCB := TRUE; xResetSafetyDCCB := TRUE; _tonResetPulseLength.IN := TRUE; _iState := 10; END_IF 10: // Reset safety from sensors IF _tonResetPulseLength.Q THEN _tonResetPulseLength.IN := FALSE; xResetSafetyDCCB := FALSE; _tonErrorDCCBNotClosed.IN := TRUE; _iState := 20; END_IF 20: // Check if DC relais closed IF NOT xDCCBOpen THEN xReady := TRUE; _iState := 30; END_IF IF _tonErrorDCCBNotClosed.Q THEN _tonErrorDCCBNotClosed.IN := FALSE; xError := TRUE; xReady := FALSE; _iState := 1000; END_IF 30: // All modules ready // !!! ATTENTION !!! // BMS HAS TO SHUT DOWN THE INVERTER BEFORE DISSABLING THE STRING // OTHERWISE THE DC CIRCUIT BREAKERS WILL OPEN WHILE THE INVERTER IS STILL ACTIVE // THIS CAN DAMAGE THE INVERTER IF NOT xEnable THEN // xCloseDCCB := FALSE; _iState := 0; ELSIF NOT _xAllModulesReady OR NOT _xBalanceOk THEN xError := TRUE; // xCloseDCCB := FALSE; _iState := 1000; END_IF 1000: // Error state // Leave error state only if modules are deactivated IF NOT xEnable THEN _tonResetPulseLength.IN := FALSE; _tonErrorDCCBNotClosed.IN := FALSE; _iState := 0; END_IF END_CASE IF _xAllModulesReady AND _xBalanceOk AND (_iState = 30) THEN xReady := TRUE; ELSE xReady := FALSE; END_IF // =============================== // String status sum // =============================== IF xOff THEN eStatus := E_COMPONENT_STATUS.OFF; END_IF IF xReady THEN eStatus := E_COMPONENT_STATUS.ON; END_IF IF xError THEN eStatus := E_COMPONENT_STATUS.ERROR; END_IF]]>