Index 0 uiFirstUnitIndex : UINT; // Enable xEnable : BOOL; // Start balancing xStartBalancing : BOOL; // Module in safety check mode xInSafetyCheckMode : BOOL; // String operation mode eStringOperatingMode : E_STRING_OPERATING_MODE; // All safetyinterlocks are ok xSafetyIntlksOk : BOOL; // Module completely off xOff : BOOL := TRUE; // HMI Interface refstHMIInterface : REFERENCE TO ST_MODULE_HMI_INTERFACE; // Release alarms xReleaseErrors : BOOL; // Release analog io limit errors xReleaseLimitErrors : BOOL; // Release manual mode xReleaseManualMode : BOOL; // Switch all components to manual mode xAllToManualMode : BOOL; // Input to confirm all errors xConfirmAlarms : BOOL; // Balancing target Voltage rBalancingTargetVoltage : REAL; // Inverter enabled status xInverterEnabled : BOOL; // Leakage double segment 1/2 xLeakageSegments12 AT %I* : BOOL; // Leakage double segment 3/4 xLeakageSegments34 AT %I* : BOOL; // Leakage tank xLeakageTank AT %I* : BOOL; // Current current value from string to copy to HMI interface rCurrent : REAL; // Current EtherCAT state uiECState AT %I* : UINT; END_VAR VAR_OUTPUT // Module voltage rCurrentVoltage : REAL; // Module ready xReady : BOOL; // Module in shutdown segment discharge mode xInShutdownDischargeMode : BOOL; // Module can be discharged during shutdown sequence xShutdownDischargeAllowed : BOOL; // One unit has an error xError : BOOL; // One unit has a warning xWarning : BOOL; // Temperature control cabinet above 40 °C xTempCabinetWarning : BOOL; // All modules in automatic mode xAllUnitsInAutomatic : BOOL; // Smallest segment voltage rSmallestSegmentVoltage : REAL; // Highest segment voltage rHighestSegmentVoltage : REAL; // Balancing done xBalancingDone : BOOL; END_VAR VAR _fbUnit1 : FB_Unit(CONCAT(Name, ' - Unit 1')); _fbUnit2 : FB_Unit(CONCAT(Name, ' - Unit 2')); _fbUnit3 : FB_Unit(CONCAT(Name, ' - Unit 3')); _fbUnit4 : FB_Unit(CONCAT(Name, ' - Unit 4')); // Temperature sensor cabinet _fbTempSensorCabinet : FB_AnalogInput(CONCAT(Name, ' - T1_Cabinet')); // Flag for unit balance checking _xBalanceOk : BOOL; // All units are ready _xAllUnitsReady : BOOL; // Units out of balance alarm _fbUnitsOutOfBalanceAlarm : FB_TcAlarm; // Leackage tank alarm _fbLeackageTankAlarm : FB_TcAlarm; // Leackage Segment 1/2 alarm _fbLeackageSegment12Alarm : FB_TcAlarm; // Leackage Segemnt 3/4 alarm _fbLeackageSegment34Alarm : FB_TcAlarm; // Connection lost alarm _fbConnLostAlarm : FB_TcAlarm; // Module name _sName : STRING; _fbBalanceNotOkSignal : FB_ReleaseSignal; _xECModuleInOP : BOOL; _xFirstCycle : BOOL := TRUE; END_VAR ]]> refstHMIInterface.stTempCabinet); // Set warning output for modbus register bits IF _fbTempSensorCabinet.xWarningHigh THEN xTempCabinetWarning := TRUE; END_IF IF _fbTempSensorCabinet.xError THEN xError := TRUE; END_IF IF _fbTempSensorCabinet.xWarning THEN xWarning := TRUE; 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; refstHMIInterface.rVoltage := refstHMIInterface.rVoltage * 0.9 + rCurrentVoltage * 0.1; // =============================== // 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#5S, 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 (NOT _fbBalanceNotOkSignal.xReleaseSignal) 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); // =============================== // Copy string current to module current // =============================== refstHMIInterface.rCurrent := rCurrent; // =============================== // Module status sum // =============================== // Module ready IF xReady AND (NOT xError) THEN refstHMIInterface.eStatus := E_COMPONENT_STATUS.ON; END_IF // Module starting IF (NOT xOff) AND (NOT xReady) AND xEnable AND (NOT xError) THEN refstHMIInterface.eStatus := E_COMPONENT_STATUS.STARTING; END_IF // Module shutdown IF (NOT xOff) AND (NOT xReady) AND (NOT xEnable) AND (NOT xError) THEN refstHMIInterface.eStatus := E_COMPONENT_STATUS.SHUTDOWN; END_IF // Module off IF xOff AND (NOT xError) THEN refstHMIInterface.eStatus := E_COMPONENT_STATUS.OFF; END_IF // Module error IF xError THEN refstHMIInterface.eStatus := E_COMPONENT_STATUS.ERROR; END_IF ]]>