); // Set error active if fb has error IF _fbPosolytPumpInlet.xError THEN _xErrorActive := TRUE; END_IF // Set warning if fb has warning IF _fbPosolytPumpInlet.xWarning THEN _xWarningActive := TRUE; END_IF // =============================== // Pump negolyt segment inlet // =============================== // Safety Interlocks stHMIInterface.stNegolytPump.stInterlock.asSafetyINTLKName[0] := 'Emergency stop ok'; _stNegolytPumpInletSIntlk.0 := xEmergencyStopOk; // Process interlocks stHMIInterface.stNegolytPump.stInterlock.asProcessINTLKName[0] := 'At least one valve is open'; _stNegolytPumpInletPIntlk.0 := _fbNegolytValveTankOutlet.IsOpen; // Valve fb _fbNegolytPumpInlet( xReleaseManualMode:= TRUE, wProcessINTLK:= _stNegolytPumpInletPIntlk, wProcessINTLKUsed:= _stNegolytPumpInletPIntlkUsed, wSafetyINTLK:= _stNegolytPumpInletSIntlk, wSafetyINTLKUsed:= _stNegolytPumpInletSIntlkUsed, xReleaseErrors:= xReleaseErrors, xConfirmAlarms:= xConfirmAlarms, rSPautomatic:= rSetpointNegolytPumpInlet, xReleaseAnalogInLimitErrors:= xReleaseLimitErrors, stMotorAnalogConfig:= stUnitConfig.stConfigNegolytPump, stHMIInterface:= stHMIInterface.stNegolytPump, xWarning=> ); // Set error active if fb has error IF _fbNegolytPumpInlet.xError THEN _xErrorActive := TRUE; END_IF // Set warning if fb has warning IF _fbNegolytPumpInlet.xWarning THEN _xWarningActive := TRUE; END_IF // =============================== // Pressure sensors posolyt segment inlet // =============================== _fbPressurePosolytSegmentInlet( stScalingConfig:= stUnitConfig.stConfigPosolytPressureSegmentInlet, stEWConfig:= stUnitConfig.stEWLPosolytPressureSegmentInlet, stEWDelayConfig:= stUnitConfig.stEWDPosolytPressureSegmentInlet, xReleaseErrors:= xReleaseErrors, xReleaseLimitErrors:= xReleaseLimitErrors, xReleaseHardwareErrors:= xReleaseErrors, xConfirmAlarms:= xConfirmAlarms, stHMIInterface => stHMIInterface.stPosolytPressureSegmentInlet); // Set error active if fb has error IF _fbPressurePosolytSegmentInlet.xError THEN _xErrorActive := TRUE; END_IF // Set warning if fb has warning IF _fbPressurePosolytSegmentInlet.xWarning THEN _xWarningActive := TRUE; END_IF // =============================== // Pressure sensors negolyt segment inlet // =============================== _fbPressureNegolytSegmentInlet( stScalingConfig:= stUnitConfig.stConfigNegolytPressureSegmentInlet, stEWConfig:= stUnitConfig.stEWLNegolytPressureSegmentInlet, stEWDelayConfig:= stUnitConfig.stEWDNegolytPressureSegmentInlet, xReleaseErrors:= xReleaseErrors, xReleaseLimitErrors:= xReleaseLimitErrors, xReleaseHardwareErrors:= xReleaseErrors, xConfirmAlarms:= xConfirmAlarms, stHMIInterface => stHMIInterface.stNegolytPressureSegmentInlet); // Set error active if fb has error IF _fbPressureNegolytSegmentInlet.xError THEN _xErrorActive := TRUE; END_IF // Set warning if fb has warning IF _fbPressureNegolytSegmentInlet.xWarning THEN _xWarningActive := TRUE; END_IF // =============================== // Voltage segment // =============================== _fbVoltageSegment( stScalingConfig:= , stEWConfig:= , stEWDelayConfig:= , xReleaseErrors:= xReleaseErrors, xReleaseLimitErrors:= xReleaseLimitErrors, xReleaseHardwareErrors:= xReleaseErrors, xConfirmAlarms:= xConfirmAlarms, stHMIInterface=> stHMIInterface.stVoltageSegment); // Set error active if fb has error IF _fbVoltageSegment.xError THEN _xErrorActive := TRUE; END_IF // Set warning if fb has warning IF _fbVoltageSegment.xWarning THEN _xWarningActive := TRUE; END_IF // =============================== // Check if all components are in automatic // =============================== _xAllComponentsInAutomatic := _fbPosolytValveTankOutlet.IsInAutomaticMode AND _fbNegolytValveTankOutlet.IsInAutomaticMode AND _fbPosolytPumpInlet.IsInAutomaticMode AND _fbNegolytPumpInlet.IsInAutomaticMode; // Raise warning IF NOT _fbNotAllAutomaticAlarm.bRaised AND (NOT _xAllComponentsInAutomatic) THEN _fbNotAllAutomaticAlarm.Raise(0); END_IF // Clear warning and reset IF _fbNotAllAutomaticAlarm.bRaised AND _xAllComponentsInAutomatic THEN _fbNotAllAutomaticAlarm.Clear(0, TRUE); END_IF // =============================== // Run state machine for startup and shutdown // =============================== CASE _iState OF 0: // Off IF xEnable AND _xAllComponentsInAutomatic AND (NOT _xErrorActive) THEN _iState := 10; END_IF 10: // Open all valves _fbPosolytValveTankOutlet.ReqAutomaticOpen(); _fbNegolytValveTankOutlet.ReqAutomaticOpen(); _iState := 15; 15: // Wait for all valves to be open IF _fbPosolytValveTankOutlet.IsOpen AND _fbNegolytValveTankOutlet.IsOpen THEN IF NOT _fbPosolytValveTankOutlet.xError AND _fbNegolytValveTankOutlet.xError THEN _iState := 20; END_IF END_IF // If enable signal is lost, or there is an error, goto shutdown IF (NOT xEnable) OR _xErrorActive THEN _iState := 40; END_IF 20: // Start pumps _fbPosolytPumpInlet.ReqAutomaticStart(); _fbNegolytPumpInlet.ReqAutomaticStart(); _iState := 25; 25: // Wait for all pumps to run IF _fbPosolytPumpInlet.xInTarget AND _fbNegolytPumpInlet.xInTarget THEN _iState := 30; END_IF // If enable signal is lost, goto shutdown IF (NOT xEnable) OR _xErrorActive THEN _iState := 40; END_IF 30: // Wait some time _tonStartupCheck(In := TRUE, PT := _timUnitStartupWaitTime); // After some time, check if all values are ok IF _tonStartupCheck.Q THEN // Check for minimum unit voltage IF _fbVoltageSegment.rScaledValue >= GVL_CONFIG.rMinimumUnitVoltage AND NOT _xErrorActive AND NOT _xWarningActive THEN xReady := TRUE; _iState := 35; ELSE _iState := 40; END_IF END_IF // If enable signal is lost, goto shutdown IF (NOT xEnable) OR _xErrorActive THEN _iState := 40; END_IF 35: // Unit in enabled state IF (NOT xEnable) OR _xErrorActive THEN _iState := 40; END_IF 40: // Close all valves _fbNegolytValveTankOutlet.ReqAutomaticClose(); _fbPosolytValveTankOutlet.ReqAutomaticClose(); _iState := 45; 45: // Wait for valves to be closed IF _fbNegolytValveTankOutlet.IsClosed AND _fbPosolytValveTankOutlet.IsClosed THEN _iState := 50; END_IF // When there is an error trying to close the valves, // dont try to discharge the segment IF _fbNegolytValveTankOutlet.xError OR _fbPosolytValveTankOutlet.xError THEN _iState := 60; END_IF // Check for restart condition IF xEnable AND (NOT _xErrorActive) THEN _iState := 0; END_IF 50: // Wait for unit voltage to drop below a certain threshold IF (_fbVoltageSegment.rScaledValue <= GVL_CONFIG.rPumpshutoffThreshold) THEN _iState := 60; END_IF // Check for restart condition IF xEnable AND (NOT _xErrorActive) THEN _iState := 0; END_IF 60: // Disable pumps _fbPosolytPumpInlet.ReqAutomaticStop(); _fbNegolytPumpInlet.ReqAutomaticStop(); _iState := 65; 65: // Wait for pumps to be stopped IF _fbPosolytPumpInlet.IsStopped AND _fbNegolytPumpInlet.IsStopped THEN IF _xErrorActive THEN _iState := 1000; ELSE _iState := 0; END_IF END_IF // Check for restart condition IF xEnable AND (NOT _xErrorActive) THEN _iState := 0; END_IF 1000: // Alarm active // Only allow reset when enable is deactivated to avoid an // automatic restart of the unit IF (NOT _xErrorActive) AND (NOT xEnable) THEN _iState := 0; END_IF END_CASE // =============================== // Output error and warning flags // =============================== xError := _xErrorActive; xWarning := _xWarningActive;]]>