); IF _fbUnit1.xWarning THEN xWarning := TRUE; END_IF IF _fbUnit1.xError THEN xError := TRUE; xDebug1 := TRUE; END_IF IF NOT _fbUnit1.xSafetyIntlksOk THEN xSafetyIntlksOk := FALSE; END_IF IF NOT _fbUnit1.xAllComponentsInAuto THEN xAllUnitsInAutomatic := FALSE; END_IF // =============================== // Unit 2 // =============================== _fbUnit2( xEnable := xEnable, xStartBalancing := xStartBalancing, xInverterEnabled := xInverterEnabled, xVoltageSensorIs1500V := stModuleVoltageConfig.xUnit2Is1500V, xInSafetyCheckMode := xInSafetyCheckMode, stUnitConfig:= GVL_CONFIG.stUnitConfig, stHMIInterface:= stHMIInterface.stHMIInterfaceUnit2, xEmergencyStopOk:= xEmergencyStopOk, xReleaseErrors:= xReleaseErrors, xReleaseLimitErrors:= xReleaseLimitErrors, xConfirmAlarms:= xConfirmAlarms, xReleaseManualMode := xReleaseManualMode, rBalancingTargetVoltage := rBalancingTargetVoltage, _xWarningConfirmPending=> ); IF _fbUnit2.xWarning THEN xWarning := TRUE; END_IF IF _fbUnit2.xError THEN xError := TRUE; xDebug2 := TRUE; END_IF IF NOT _fbUnit2.xSafetyIntlksOk THEN xSafetyIntlksOk := FALSE; END_IF IF NOT _fbUnit2.xAllComponentsInAuto THEN xAllUnitsInAutomatic := FALSE; END_IF // =============================== // Unit 3 // =============================== _fbUnit3( xEnable := xEnable, xStartBalancing := xStartBalancing, xInverterEnabled := xInverterEnabled, xVoltageSensorIs1500V := stModuleVoltageConfig.xUnit3Is1500V, xInSafetyCheckMode := xInSafetyCheckMode, stUnitConfig:= GVL_CONFIG.stUnitConfig, stHMIInterface:= stHMIInterface.stHMIInterfaceUnit3, xEmergencyStopOk:= xEmergencyStopOk, xReleaseErrors:= xReleaseErrors, xReleaseLimitErrors:= xReleaseLimitErrors, xConfirmAlarms:= xConfirmAlarms, xReleaseManualMode := xReleaseManualMode, rBalancingTargetVoltage := rBalancingTargetVoltage, _xWarningConfirmPending=> ); IF _fbUnit3.xWarning THEN xWarning := TRUE; END_IF IF _fbUnit3.xError THEN xError := TRUE; xDebug3 := TRUE; END_IF IF NOT _fbUnit3.xSafetyIntlksOk THEN xSafetyIntlksOk := FALSE; END_IF IF NOT _fbUnit3.xAllComponentsInAuto THEN xAllUnitsInAutomatic := FALSE; END_IF // =============================== // Unit 4 // =============================== _fbUnit4( xEnable := xEnable, xStartBalancing := xStartBalancing, xInverterEnabled := xInverterEnabled, xVoltageSensorIs1500V := stModuleVoltageConfig.xUnit4Is1500V, xInSafetyCheckMode := xInSafetyCheckMode, stUnitConfig:= GVL_CONFIG.stUnitConfig, stHMIInterface:= stHMIInterface.stHMIInterfaceUnit4, xEmergencyStopOk:= xEmergencyStopOk, xReleaseErrors:= xReleaseErrors, xReleaseLimitErrors:= xReleaseLimitErrors, xConfirmAlarms:= xConfirmAlarms, xReleaseManualMode := xReleaseManualMode, rBalancingTargetVoltage := rBalancingTargetVoltage, _xWarningConfirmPending=> ); IF _fbUnit4.xWarning THEN xWarning := TRUE; END_IF IF _fbUnit4.xError THEN xError := TRUE; xDebug4 := TRUE; END_IF IF NOT _fbUnit4.xSafetyIntlksOk THEN xSafetyIntlksOk := FALSE; END_IF IF NOT _fbUnit4.xAllComponentsInAuto THEN xAllUnitsInAutomatic := FALSE; END_IF // =============================== // Units ready check // =============================== _xAllUnitsReady := _fbUnit1.xReady AND _fbUnit2.xReady AND _fbUnit3.xReady AND _fbUnit4.xReady; // =============================== // Balancing done check // =============================== xBalancingDone := _fbUnit1.xBalancingDone AND _fbUnit2.xBalancingDone AND _fbUnit3.xBalancingDone AND _fbUnit4.xBalancingDone; // =============================== // Units in shutdown discharge mode // =============================== xInShutdownDischargeMode := _fbUnit1.xInShutdownDischargeMode AND _fbUnit2.xInShutdownDischargeMode AND _fbUnit3.xInShutdownDischargeMode AND _fbUnit4.xInShutdownDischargeMode; // =============================== // Units shutdown discharge allowed // =============================== xShutdownDischargeAllowed := _fbUnit1.xShutdownDischargeAllowed AND _fbUnit2.xShutdownDischargeAllowed AND _fbUnit3.xShutdownDischargeAllowed AND _fbUnit4.xShutdownDischargeAllowed; // =============================== // All units off // =============================== xOff := _fbUnit1.xOff AND _fbUnit2.xOff AND _fbUnit3.xOff AND _fbUnit4.xOff; // =============================== // Calculate module voltage // =============================== rCurrentVoltage := _fbUnit1.rCurrentVoltage + _fbUnit2.rCurrentVoltage + _fbUnit3.rCurrentVoltage + _fbUnit4.rCurrentVoltage; stHMIInterface.rVoltage := rCurrentVoltage; // =============================== // Module balance check // =============================== // Reset balance ok flag _xBalanceOk := TRUE; // Test unit 1 with unit 2 IF ABS(_fbUnit1.rCurrentVoltage - _fbUnit2.rCurrentVoltage) > GVL_CONFIG.rMaxAbsDiffVoltageUnitsOnModule THEN _xBalanceOk := FALSE; END_IF // Test unit 1 with unit 3 IF ABS(_fbUnit1.rCurrentVoltage - _fbUnit3.rCurrentVoltage) > GVL_CONFIG.rMaxAbsDiffVoltageUnitsOnModule THEN _xBalanceOk := FALSE; END_IF // Test unit 1 with unit 4 IF ABS(_fbUnit1.rCurrentVoltage - _fbUnit4.rCurrentVoltage) > GVL_CONFIG.rMaxAbsDiffVoltageUnitsOnModule THEN _xBalanceOk := FALSE; END_IF // Test unit 2 with unit 3 IF ABS(_fbUnit2.rCurrentVoltage - _fbUnit3.rCurrentVoltage) > GVL_CONFIG.rMaxAbsDiffVoltageUnitsOnModule THEN _xBalanceOk := FALSE; END_IF // Test unit 2 with unit 4 IF ABS(_fbUnit2.rCurrentVoltage - _fbUnit4.rCurrentVoltage) > GVL_CONFIG.rMaxAbsDiffVoltageUnitsOnModule THEN _xBalanceOk := FALSE; END_IF // Test unit 3 with unit 4 IF ABS(_fbUnit3.rCurrentVoltage - _fbUnit4.rCurrentVoltage) > GVL_CONFIG.rMaxAbsDiffVoltageUnitsOnModule THEN _xBalanceOk := FALSE; END_IF // Release signal for balance not ok _fbBalanceNotOkSignal( xSignal:= NOT _xBalanceOk, xRelease:= xEnable AND _xAllUnitsReady, timOnDelay:= T#10S, timOffDelay:= T#5S, xReleaseSignal=> ); // Signal an error if all units are ready and module is out of balance IF _xAllUnitsReady AND _fbBalanceNotOkSignal.xReleaseSignal THEN xError := TRUE; END_IF // Raise error IF _fbBalanceNotOkSignal.xReleaseSignal AND (NOT _fbUnitsOutOfBalanceAlarm.bRaised) THEN _fbUnitsOutOfBalanceAlarm.Raise(0); END_IF // Clear error only with confirmation because of voltage ripple event spam IF (NOT _fbBalanceNotOkSignal.xReleaseSignal) AND _fbUnitsOutOfBalanceAlarm.bRaised AND xConfirmAlarms THEN _fbUnitsOutOfBalanceAlarm.Clear(0, FALSE); END_IF // Confirm error IF _fbUnitsOutOfBalanceAlarm.eConfirmationState = TcEventConfirmationState.WaitForConfirmation AND xConfirmAlarms THEN _fbUnitsOutOfBalanceAlarm.Confirm(0); END_IF // =============================== // Module ready validation check // =============================== IF _xAllUnitsReady AND _xBalanceOk THEN xReady := TRUE; ELSE xReady := FALSE; END_IF // =============================== // Get the smallest segment Voltage // for balancing // =============================== rSmallestSegmentVoltage := MIN(_fbUnit1.rCurrentVoltage, _fbUnit2.rCurrentVoltage, _fbUnit3.rCurrentVoltage, _fbUnit4.rCurrentVoltage); rHighestSegmentVoltage := MAX(_fbUnit1.rCurrentVoltage, _fbUnit2.rCurrentVoltage, _fbUnit3.rCurrentVoltage, _fbUnit4.rCurrentVoltage); // =============================== // Module status sum // =============================== IF xOff THEN stHMIInterface.eStatus := E_COMPONENT_STATUS.OFF; END_IF IF xReady THEN stHMIInterface.eStatus := E_COMPONENT_STATUS.ON; END_IF IF xError THEN stHMIInterface.eStatus := E_COMPONENT_STATUS.ERROR; END_IF]]>