added sync units for cabinet temperature, changes in modbus interface to EMS (1.0.4 and 1.0.5), added error counter to modbus communication, lot of changes to kaco (faults, consecutive errors, bms error messages), isolation error ledge, allowed startbalancing when on shutdown, tower light integration
1327 lines
40 KiB
XML
1327 lines
40 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.12">
|
|
<POU Name="FB_Unit" Id="{e9bb815b-eb46-4920-800d-910484e58b22}" SpecialFunc="None">
|
|
<Declaration><![CDATA[FUNCTION_BLOCK FB_Unit
|
|
VAR_INPUT
|
|
// Unit configuration
|
|
stUnitConfig : REFERENCE TO ST_UNIT_CONFIG;
|
|
|
|
// HMI interface
|
|
stHMIInterface : REFERENCE TO ST_UNIT_HMI_INTERFACE;
|
|
|
|
// Start unit
|
|
xEnable : BOOL;
|
|
|
|
// Star balancing
|
|
xStartBalancing : BOOL;
|
|
|
|
// Unit in safety check mode
|
|
xInSafetyCheckMode : BOOL;
|
|
|
|
// String operation mode
|
|
eStringOperatingMode : E_STRING_OPERATING_MODE;
|
|
|
|
// Emergency stop ok
|
|
xEmergencyStopOk : BOOL;
|
|
|
|
// All safetyinterlocks are ok
|
|
xSafetyIntlksOk : BOOL;
|
|
|
|
// Release alarms
|
|
xReleaseErrors : BOOL;
|
|
|
|
// Release analog io limit errors
|
|
xReleaseLimitErrors : BOOL;
|
|
|
|
// Release manual mode
|
|
xReleaseManualMode : BOOL;
|
|
|
|
// Input to confirm all errors
|
|
xConfirmAlarms : BOOL;
|
|
|
|
// Balancing target Voltage
|
|
rBalancingTargetVoltage : REAL;
|
|
|
|
// Switch all components to manual mode
|
|
xAllToManualMode : BOOL;
|
|
|
|
// Inverter enabled status
|
|
xInverterEnabled : BOOL;
|
|
END_VAR
|
|
VAR_IN_OUT
|
|
// Modbus warning register
|
|
stModbusWarnings : U_UNIT_WARNING_REGISTER;
|
|
|
|
// Modbus error register
|
|
stModbusErrors : U_UNIT_ERROR_REGISTER;
|
|
END_VAR
|
|
VAR_OUTPUT
|
|
// Unit state
|
|
//eUnitState : E_COMPONENT_STATUS := E_COMPONENT_STATUS.OFF;
|
|
|
|
// Unit ready
|
|
xReady : BOOL;
|
|
|
|
// Unit completely off
|
|
xOff : BOOL := TRUE;
|
|
|
|
// Unit can be discharged during shutdown sequence
|
|
xShutdownDischargeAllowed : BOOL;
|
|
|
|
// Unit in shutdown segment discharge mode
|
|
xInShutdownDischargeMode : BOOL;
|
|
|
|
// Error active
|
|
xError : BOOL;
|
|
|
|
// Warning active
|
|
xWarning : BOOL;
|
|
|
|
// Current Unit voltage
|
|
rCurrentVoltage : REAL;
|
|
|
|
// All components in automatic mode
|
|
xAllComponentsInAuto : BOOL;
|
|
|
|
// Balancing done
|
|
xBalancingDone : BOOL;
|
|
|
|
// Reset MCB
|
|
xResetMCB AT %Q* : BOOL;
|
|
END_VAR
|
|
VAR
|
|
// Check unit condition after some time during startup
|
|
_timUnitStartupWaitTime : TIME := T#1M;
|
|
|
|
// Valves posolyt
|
|
_fbPosolytValveTankOutlet : FB_Valve(CONCAT(_sName, ' - Posolyt tank outlet'));
|
|
|
|
// Valves negolyt
|
|
_fbNegolytValveTankOutlet : FB_Valve(CONCAT(_sName, ' - Negolyt tank outlet'));
|
|
|
|
// Pumps posolyt
|
|
_fbPosolytPumpInlet : FB_MotorAnalog(CONCAT(_sName, ' - Posolyt segment inlet'));
|
|
|
|
// Pumps negolyt
|
|
_fbNegolytPumpInlet : FB_MotorAnalog(CONCAT(_sName, ' - Negolyt segment inlet'));
|
|
|
|
// Pressure sensors posolyt
|
|
_fbPressurePosolytSegmentInlet : FB_AnalogInput(CONCAT(_sName, ' - P1_P'));
|
|
_fbPressurePosolytTankInlet : FB_AnalogInput(CONCAT(_sName, ' - P3_P'));
|
|
|
|
// Pressure sensors negolyt
|
|
_fbPressureNegolytSegmentInlet : FB_AnalogInput(CONCAT(_sName, ' - P1_N'));
|
|
_fbPressureNegolytTankInlet : FB_AnalogInput(CONCAT(_sName, ' - P3_N'));
|
|
|
|
// Temperature sensor posolyt
|
|
_fbTempSensorPosolyt : FB_AnalogInput(CONCAT(Name, ' - T1_P'));
|
|
|
|
// Temperature sensor negolyt
|
|
_fbTempSensorNegolyt : FB_AnalogInput(CONCAT(Name, ' - T1_N'));
|
|
|
|
// Unit voltage
|
|
_fbVoltageSegment : FB_AnalogInput('Voltage');
|
|
|
|
// Valve posolyt tank outlet interlocks
|
|
_stPosolytValveTankOutletPIntlk : T_INTERLOCK;
|
|
_stPosolytValveTankOutletPIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0000;
|
|
|
|
_stPosolytValveTankOutletSIntlk : T_INTERLOCK;
|
|
_stPosolytValveTankOutletSIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0001;
|
|
|
|
// Valve negolyt tank outlet interlocks
|
|
_stNegolytValveTankOutletPIntlk : T_INTERLOCK;
|
|
_stNegolytValveTankOutletPIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0000;
|
|
|
|
_stNegolytValveTankOutletSIntlk : T_INTERLOCK;
|
|
_stNegolytValveTankOutletSIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0001;
|
|
|
|
// Pump posolyt inlet interlocks
|
|
_stPosolytPumpInletPIntlk : T_INTERLOCK;
|
|
_stPosolytPumpInletPIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0001;
|
|
_stPosolytPumpInletSIntlk : T_INTERLOCK;
|
|
_stPosolytPumpInletSIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0111;
|
|
|
|
// Pump negolyt inlet interlocks
|
|
_stNegolytPumpInletPIntlk : T_INTERLOCK;
|
|
_stNegolytPumpInletPIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0001;
|
|
_stNegolytPumpInletSIntlk : T_INTERLOCK;
|
|
_stNegolytPumpInletSIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0111;
|
|
|
|
// Error active
|
|
_xErrorActive : BOOL;
|
|
|
|
// Warning active
|
|
_xWarningActive : BOOL;
|
|
|
|
// Shutdown discharge allowed voltage
|
|
_rShutdownDischargeVoltageThreshold : REAL;
|
|
|
|
// Current state
|
|
_iState: INT;
|
|
|
|
// All components in automatic mode
|
|
_xAllComponentsInAutomatic : BOOL;
|
|
|
|
// Not all components in automatic mode alarm
|
|
_fbNotAllAutomaticAlarm : FB_TcAlarm;
|
|
|
|
// Pressure difference between pos and neg inlet to big
|
|
_fbPressureDiffToBig : FB_TcAlarm;
|
|
|
|
// General unit error
|
|
_fbUnitError : FB_TcAlarm;
|
|
|
|
// Unit name
|
|
_sName : STRING;
|
|
|
|
// Unit startup check timer
|
|
_tonStartupCheck : TON;
|
|
|
|
// Enable voltage limit checks
|
|
_xEnableVoltageLimitChecks : BOOL;
|
|
|
|
// Manual mode allowed flag
|
|
_xReleaseManualMode : BOOL;
|
|
|
|
_xReleaseSignalDeltaPSegment : FB_ReleaseSignal;
|
|
_xDeltaPSegmentInletToHigh : BOOL;
|
|
_xEnableCheckForDeltaPSegmentInlet : BOOL;
|
|
_xErrorDeltaPSegmentInlet : BOOL;
|
|
|
|
// Setpoint posolyt pump inlet
|
|
_rSetpointPosolytPumpInlet : REAL;
|
|
|
|
// Setpoint negolyt pump inlet
|
|
_rSetpointNegolytPumpInlet : REAL;
|
|
|
|
// Timer for resetting the MCB (minimum on time 0,5s)
|
|
_tofResetMCB : TOF := (PT := T#0.75S);
|
|
|
|
// Timeout Voltage not reached
|
|
_tonVoltageCheckTimeput : TON := (PT := T#2M);
|
|
|
|
// Freezed balancing target voltage
|
|
_rBalancingTargetVoltage : REAL;
|
|
|
|
// Trigger for switching to manual mode
|
|
_rtrigSwitchToManualMode : R_TRIG;
|
|
|
|
// Trigger for switching to automatic mode
|
|
_rtrigSwitchToAutoMode : R_TRIG;
|
|
_tonManualMode : TON;
|
|
|
|
// Filtered pressure sensor posolyt segment inlet data for HMI
|
|
_rFilteredPressPosolytInlet : REAL;
|
|
|
|
// Filtered pressure sensor posolyt segment inlet data for HMI
|
|
_rFilteredPressNegolytInlet : REAL;
|
|
|
|
// Filtered pressure sensor posolyt tank inlet data for HMI
|
|
_rFilteredPressPosolytTank : REAL;
|
|
|
|
// Filtered pressure sensor posolyt tank inlet data for HMI
|
|
_rFilteredPressNegolytTank : REAL;
|
|
|
|
// Pumps ready
|
|
_xPumpsReady : BOOL;
|
|
|
|
// Indicate if it ise the first cycle
|
|
xFirstCycle : BOOL := TRUE;
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[IF xFirstCycle THEN
|
|
_fbPosolytValveTankOutlet.Name := CONCAT(_sName, ' - Posolyt tank outlet');
|
|
stHMIInterface.stNS12.sName := 'Posolyt tank outlet';
|
|
|
|
_fbNegolytValveTankOutlet.Name := CONCAT(_sName, ' - Negolyt tank outlet');
|
|
stHMIInterface.stNS22.sName := 'Negolyt tank outlet';
|
|
|
|
_fbPosolytPumpInlet.Name := CONCAT(_sName, ' - Posolyt segment inlet');
|
|
stHMIInterface.stNS11.sName := 'Posolyt segment inlet';
|
|
|
|
_fbNegolytPumpInlet.Name := CONCAT(_sName, ' - Negolyt segment inlet');
|
|
stHMIInterface.stNS21.sName := 'Negolyt segment inlet';
|
|
|
|
_fbPressurePosolytSegmentInlet.Name := CONCAT(_sName, ' - Pressure Posolyt Segment Inlet');
|
|
_fbPressurePosolytTankInlet.Name := CONCAT(_sName, ' - Pressure Posolyt Tank inlet');
|
|
|
|
_fbPressureNegolytSegmentInlet.Name := CONCAT(_sName, ' - Pressure Negolyt Segment Inlet');
|
|
_fbPressureNegolytTankInlet.Name := CONCAT(_sName, ' - Pressure Negolyt Tank Inlet');
|
|
|
|
_fbTempSensorPosolyt.Name := CONCAT(_sName, ' - Temperature Posolyt Tank Inlet');
|
|
_fbTempSensorNegolyt.Name := CONCAT(_sName, ' - Temperature Negolyt Tank Inlet');
|
|
|
|
_fbVoltageSegment.Name := CONCAT(_sName, ' - Voltage');
|
|
|
|
_fbUnitError.ipArguments.Clear().AddString(_sName);
|
|
|
|
_fbPressureDiffToBig.CreateEx(stEventEntry := TC_EVENTS.General.PressureDiffToBig, TRUE, 0);
|
|
_fbPressureDiffToBig.ipArguments.Clear().AddString(_sName);
|
|
|
|
xFirstCycle := FALSE;
|
|
END_IF
|
|
|
|
|
|
// Manual mode trigger
|
|
_tonManualMode(IN := (xAllToManualMode AND xReleaseManualMode), PT := T#10S);
|
|
_rtrigSwitchToManualMode(CLK := _tonManualMode.Q);
|
|
IF _rtrigSwitchToManualMode.Q THEN
|
|
_fbPosolytValveTankOutlet.ReqManualMode();
|
|
_fbNegolytValveTankOutlet.ReqManualMode();
|
|
_fbPosolytPumpInlet.ReqManualMode();
|
|
_fbNegolytPumpInlet.ReqManualMode();
|
|
END_IF
|
|
|
|
// Auto mode trigger
|
|
_rtrigSwitchToAutoMode(CLK := (NOT _tonManualMode.Q));
|
|
IF _rtrigSwitchToAutoMode.Q THEN
|
|
_fbPosolytValveTankOutlet.ReqAutomaticMode();
|
|
_fbNegolytValveTankOutlet.ReqAutomaticMode();
|
|
_fbPosolytPumpInlet.ReqAutomaticMode();
|
|
_fbNegolytPumpInlet.ReqAutomaticMode();
|
|
END_IF
|
|
|
|
// Reset MCB logic
|
|
_tofResetMCB(IN := xConfirmAlarms);
|
|
xResetMCB := _tofResetMCB.Q;
|
|
|
|
// Reset error active
|
|
_xErrorActive := FALSE;
|
|
|
|
// Reset warning active
|
|
_xWarningActive := FALSE;
|
|
|
|
// Reset safety interlocks flag
|
|
xSafetyIntlksOk := TRUE;
|
|
|
|
// Copy release manual mode
|
|
_xReleaseManualMode := xReleaseManualMode;
|
|
|
|
// ===============================
|
|
// Valve posolyt tank outlet
|
|
// ===============================
|
|
|
|
// Safety Interlocks
|
|
stHMIInterface.stNS12.stInterlock.asSafetyINTLKName[0] := 'Emergency stop ok';
|
|
_stPosolytValveTankOutletSIntlk.0 := xEmergencyStopOk;
|
|
|
|
// Valve fb
|
|
_fbPosolytValveTankOutlet(
|
|
xReleaseManualMode:= _xReleaseManualMode,
|
|
wProcessINTLK:= _stPosolytValveTankOutletPIntlk,
|
|
wProcessINTLKUsed:= _stPosolytValveTankOutletPIntlkUsed,
|
|
wSafetyINTLK:= _stPosolytValveTankOutletSIntlk,
|
|
wSafetyINTLKUsed:= _stPosolytValveTankOutletSIntlkUsed,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
stValveConfig:= stUnitConfig.stConfigPosolytValve,
|
|
stHMIInterface:= stHMIInterface.stNS12);
|
|
|
|
|
|
// Set error active if fb has error
|
|
IF _fbPosolytValveTankOutlet.xError THEN
|
|
stModbusErrors.stBitmap.bValvePos := 1;
|
|
_xErrorActive := TRUE;
|
|
END_IF
|
|
|
|
|
|
// Set safety interlock flag if fb has safety interlocks active
|
|
IF NOT stHMIInterface.stNS12.stInterlock.xSafetyINTLKOk THEN
|
|
xSafetyIntlksOk := FALSE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Valve negolyt tank outlet
|
|
// ===============================
|
|
|
|
// Safety Interlocks
|
|
stHMIInterface.stNS22.stInterlock.asSafetyINTLKName[0] := 'Emergency stop ok';
|
|
_stNegolytValveTankOutletSIntlk.0 := xEmergencyStopOk;
|
|
|
|
// Valve fb
|
|
_fbNegolytValveTankOutlet(
|
|
xReleaseManualMode:= _xReleaseManualMode,
|
|
wProcessINTLK:= _stNegolytValveTankOutletPIntlk,
|
|
wProcessINTLKUsed:= _stNegolytValveTankOutletPIntlkUsed,
|
|
wSafetyINTLK:= _stNegolytValveTankOutletSIntlk,
|
|
wSafetyINTLKUsed:= _stNegolytValveTankOutletSIntlkUsed,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
stValveConfig:= stUnitConfig.stConfigNegolytValve,
|
|
stHMIInterface:= stHMIInterface.stNS22);
|
|
|
|
// Set error active if fb has error
|
|
IF _fbNegolytValveTankOutlet.xError THEN
|
|
stModbusErrors.stBitmap.bValveNeg := 1;
|
|
_xErrorActive := TRUE;
|
|
END_IF
|
|
|
|
// Set safety interlock flag if fb has safety interlocks active
|
|
IF NOT stHMIInterface.stNS22.stInterlock.xSafetyINTLKOk THEN
|
|
xSafetyIntlksOk := FALSE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Pump posolyt segment inlet
|
|
// ===============================
|
|
|
|
// Safety Interlocks
|
|
stHMIInterface.stNS11.stInterlock.asSafetyINTLKName[0] := 'Emergency stop ok';
|
|
_stPosolytPumpInletSIntlk.0 := xEmergencyStopOk;
|
|
stHMIInterface.stNS11.stInterlock.asSafetyINTLKName[1] := 'Segment inlet pressure to high';
|
|
_stPosolytPumpInletSIntlk.1 := NOT _fbPressurePosolytSegmentInlet.xErrorHigh;
|
|
stHMIInterface.stNS11.stInterlock.asSafetyINTLKName[2] := 'Segment inlet pressure to low';
|
|
_stPosolytPumpInletSIntlk.2 := NOT _fbPressurePosolytSegmentInlet.xErrorLow;
|
|
|
|
// Process interlocks
|
|
stHMIInterface.stNS21.stInterlock.asProcessINTLKName[0] := 'Negolyt Pump Error';
|
|
_stPosolytPumpInletPIntlk.0 := NOT _fbNegolytPumpInlet.xError;
|
|
|
|
|
|
// Pump fb
|
|
_fbPosolytPumpInlet(
|
|
xReleaseManualMode:= _xReleaseManualMode,
|
|
wProcessINTLK:= _stPosolytPumpInletPIntlk,
|
|
wProcessINTLKUsed:= _stPosolytPumpInletPIntlkUsed,
|
|
wSafetyINTLK:= _stPosolytPumpInletSIntlk,
|
|
wSafetyINTLKUsed:= _stPosolytPumpInletSIntlkUsed,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
rSPautomatic:= _rSetpointPosolytPumpInlet,
|
|
xReleaseAnalogInLimitErrors:= xReleaseLimitErrors AND GVL_SCADA.xDummy,
|
|
stMotorAnalogConfig:= stUnitConfig.stConfigPosolytPump,
|
|
stHMIInterface:= stHMIInterface.stNS11,
|
|
xWarning=> );
|
|
|
|
// Set error active if fb has error
|
|
IF _fbPosolytPumpInlet.xError THEN
|
|
stModbusErrors.stBitmap.bPumpPos := 1;
|
|
_xErrorActive := TRUE;
|
|
END_IF
|
|
|
|
// Set warning if fb has warning
|
|
IF _fbPosolytPumpInlet.xWarning THEN
|
|
_xWarningActive := TRUE;
|
|
END_IF
|
|
|
|
// Set safety interlock flag if fb has safety interlocks active
|
|
IF NOT stHMIInterface.stNS11.stInterlock.xSafetyINTLKOk THEN
|
|
xSafetyIntlksOk := FALSE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Pump negolyt segment inlet
|
|
// ===============================
|
|
|
|
// Safety Interlocks
|
|
stHMIInterface.stNS21.stInterlock.asSafetyINTLKName[0] := 'Emergency stop ok';
|
|
_stNegolytPumpInletSIntlk.0 := xEmergencyStopOk;
|
|
stHMIInterface.stNS11.stInterlock.asSafetyINTLKName[1] := 'Segment inlet pressure to high';
|
|
_stNegolytPumpInletSIntlk.1 := NOT _fbPressureNegolytSegmentInlet.xErrorHigh;
|
|
stHMIInterface.stNS11.stInterlock.asSafetyINTLKName[2] := 'Segment inlet pressure to low';
|
|
_stNegolytPumpInletSIntlk.2 := NOT _fbPressureNegolytSegmentInlet.xErrorLow;
|
|
|
|
// Process interlocks
|
|
stHMIInterface.stNS11.stInterlock.asProcessINTLKName[0] := 'Posolyt Pump Error';
|
|
_stNegolytPumpInletPIntlk.0 := NOT _fbPosolytPumpInlet.xError;
|
|
|
|
|
|
// Pump fb
|
|
_fbNegolytPumpInlet(
|
|
xReleaseManualMode:= _xReleaseManualMode,
|
|
wProcessINTLK:= _stNegolytPumpInletPIntlk,
|
|
wProcessINTLKUsed:= _stNegolytPumpInletPIntlkUsed,
|
|
wSafetyINTLK:= _stNegolytPumpInletSIntlk,
|
|
wSafetyINTLKUsed:= _stNegolytPumpInletSIntlkUsed,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
rSPautomatic:= _rSetpointNegolytPumpInlet,
|
|
xReleaseAnalogInLimitErrors:= xReleaseLimitErrors AND GVL_SCADA.xDummy,
|
|
stMotorAnalogConfig:= stUnitConfig.stConfigNegolytPump,
|
|
stHMIInterface:= stHMIInterface.stNS21,
|
|
xWarning=> );
|
|
|
|
// Set error active if fb has error
|
|
IF _fbNegolytPumpInlet.xError THEN
|
|
stModbusErrors.stBitmap.bPumpNeg := 1;
|
|
_xErrorActive := TRUE;
|
|
END_IF
|
|
|
|
// Set warning if fb has warning
|
|
IF _fbNegolytPumpInlet.xWarning THEN
|
|
_xWarningActive := TRUE;
|
|
END_IF
|
|
|
|
// Set safety interlock flag if fb has safety interlocks active
|
|
IF NOT stHMIInterface.stNS21.stInterlock.xSafetyINTLKOk THEN
|
|
xSafetyIntlksOk := FALSE;
|
|
END_IF
|
|
|
|
_xPumpsReady := stHMIInterface.stNS21.stInterlock.xProcessINTLKOk AND stHMIInterface.stNS21.stInterlock.xSafetyINTLKOk AND stHMIInterface.stNS11.stInterlock.xProcessINTLKOk AND stHMIInterface.stNS11.stInterlock.xSafetyINTLKOk;
|
|
|
|
// ===============================
|
|
// Pressure sensor posolyt segment inlet
|
|
// ===============================
|
|
_fbPressurePosolytSegmentInlet(
|
|
stScalingConfig:= stUnitConfig.stConfigPosolytPressureSegmentInlet,
|
|
stEWConfig:= stUnitConfig.stEWLPosolytPressureSegmentInlet,
|
|
stEWDelayConfig:= stUnitConfig.stEWDPosolytPressureSegmentInlet,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
xReleaseLimitErrors:= xReleaseLimitErrors AND _fbPosolytPumpInlet.IsRunning AND _fbPosolytPumpInlet.xInTarget AND (NOT xStartBalancing), // AND (_fbPosolytPumpInlet.rSPautomatic > 40),
|
|
xReleaseHardwareErrors:= xReleaseErrors,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
stHMIInterface => stHMIInterface.stP11);
|
|
|
|
// Filter pressure sensor data for HMI
|
|
_rFilteredPressPosolytInlet := _rFilteredPressPosolytInlet * 0.9 + stHMIInterface.stP11.rValue * 0.1;
|
|
stHMIInterface.stP11.rValue := _rFilteredPressPosolytInlet;
|
|
|
|
// Set modbus error register bits
|
|
IF _fbPressurePosolytSegmentInlet.xErrorLow THEN
|
|
stModbusErrors.stBitmap.bPInPosLow := 1;
|
|
END_IF
|
|
IF _fbPressurePosolytSegmentInlet.xErrorHigh THEN
|
|
stModbusErrors.stBitmap.bPInPosHigh := 1;
|
|
END_IF
|
|
IF _fbPressurePosolytSegmentInlet.xError THEN
|
|
stModbusErrors.stBitmap.bPInPosError := 1;
|
|
END_IF
|
|
|
|
// Set modbus warning register bits
|
|
IF _fbPressurePosolytSegmentInlet.xWarningLow THEN
|
|
stModbusWarnings.stBitmap.bPInPosLow := 1;
|
|
END_IF
|
|
IF _fbPressurePosolytSegmentInlet.xWarningHigh THEN
|
|
stModbusWarnings.stBitmap.bPInPosHigh := 1;
|
|
END_IF
|
|
|
|
|
|
// 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 AND _fbNegolytPumpInlet.IsRunning AND _fbNegolytPumpInlet.xInTarget AND (NOT xStartBalancing),// AND (_fbNegolytPumpInlet.rSPautomatic > 40),
|
|
xReleaseHardwareErrors:= xReleaseErrors,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
stHMIInterface => stHMIInterface.stP21);
|
|
|
|
// Filter pressure sensor data for HMI
|
|
_rFilteredPressNegolytInlet := _rFilteredPressNegolytInlet * 0.9 + stHMIInterface.stP21.rValue * 0.1;
|
|
stHMIInterface.stP21.rValue := _rFilteredPressNegolytInlet;
|
|
|
|
// Set modbus error register bits
|
|
IF _fbPressureNegolytSegmentInlet.xErrorLow THEN
|
|
stModbusErrors.stBitmap.bPInNegLow := 1;
|
|
END_IF
|
|
IF _fbPressureNegolytSegmentInlet.xErrorHigh THEN
|
|
stModbusErrors.stBitmap.bPInNegHigh := 1;
|
|
END_IF
|
|
IF _fbPressureNegolytSegmentInlet.xError THEN
|
|
stModbusErrors.stBitmap.bPInNegError := 1;
|
|
END_IF
|
|
|
|
// Set modbus warning register bits
|
|
IF _fbPressureNegolytSegmentInlet.xWarningLow THEN
|
|
stModbusWarnings.stBitmap.bPInNegLow := 1;
|
|
END_IF
|
|
IF _fbPressureNegolytSegmentInlet.xWarningHigh THEN
|
|
stModbusWarnings.stBitmap.bPInNegHigh := 1;
|
|
END_IF
|
|
|
|
// 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
|
|
|
|
|
|
// ===============================
|
|
// Pressure sensors posolyt tank inlet
|
|
// ===============================
|
|
_fbPressurePosolytTankInlet(
|
|
stScalingConfig:= stUnitConfig.stConfigPosolytPressureTankInlet,
|
|
stEWConfig:= stUnitConfig.stEWLPosolytPressureTankInlet,
|
|
stEWDelayConfig:= stUnitConfig.stEWDPosolytPressureTankInlet,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
xReleaseLimitErrors:= xReleaseLimitErrors,
|
|
xReleaseHardwareErrors:= xReleaseErrors,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
stHMIInterface => stHMIInterface.stP12);
|
|
|
|
// Filter pressure sensor data for HMI
|
|
_rFilteredPressPosolytTank := _rFilteredPressPosolytTank * 0.9 + stHMIInterface.stP12.rValue * 0.1;
|
|
stHMIInterface.stP12.rValue := _rFilteredPressPosolytTank;
|
|
|
|
// Set modbus error register bits
|
|
IF _fbPressurePosolytTankInlet.xErrorLow THEN
|
|
stModbusErrors.stBitmap.bPTankPosLow := 1;
|
|
END_IF
|
|
IF _fbPressurePosolytTankInlet.xErrorHigh THEN
|
|
stModbusErrors.stBitmap.bPTankPosHigh := 1;
|
|
END_IF
|
|
IF _fbPressurePosolytTankInlet.xError THEN
|
|
stModbusErrors.stBitmap.bPTankPosError := 1;
|
|
END_IF
|
|
|
|
// Set modbus warning register bits
|
|
IF _fbPressurePosolytTankInlet.xWarningLow THEN
|
|
stModbusWarnings.stBitmap.bPTankPosLow := 1;
|
|
END_IF
|
|
IF _fbPressurePosolytTankInlet.xWarningHigh THEN
|
|
stModbusWarnings.stBitmap.bPTankPosHigh := 1;
|
|
END_IF
|
|
|
|
// Set error active if fb has error
|
|
IF _fbPressurePosolytTankInlet.xError THEN
|
|
_xErrorActive := TRUE;
|
|
END_IF
|
|
|
|
// Set warning if fb has warning
|
|
IF _fbPressurePosolytTankInlet.xWarning THEN
|
|
_xWarningActive := TRUE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Pressure sensors negolyt tank inlet
|
|
// ===============================
|
|
_fbPressureNegolytTankInlet(
|
|
stScalingConfig:= stUnitConfig.stConfigNegolytPressureTankInlet,
|
|
stEWConfig:= stUnitConfig.stEWLNegolytPressureTankInlet,
|
|
stEWDelayConfig:= stUnitConfig.stEWDNegolytPressureTankInlet,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
xReleaseLimitErrors:= xReleaseLimitErrors,
|
|
xReleaseHardwareErrors:= xReleaseErrors,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
stHMIInterface => stHMIInterface.stP22);
|
|
|
|
// Filter pressure sensor data for HMI
|
|
_rFilteredPressNegolytTank := _rFilteredPressNegolytTank * 0.9 + stHMIInterface.stP22.rValue * 0.1;
|
|
stHMIInterface.stP22.rValue := _rFilteredPressNegolytTank;
|
|
|
|
// Set modbus error register bits
|
|
IF _fbPressureNegolytTankInlet.xErrorLow THEN
|
|
stModbusErrors.stBitmap.bPTankNegLow := 1;
|
|
END_IF
|
|
IF _fbPressureNegolytTankInlet.xErrorHigh THEN
|
|
stModbusErrors.stBitmap.bPTankNegHigh := 1;
|
|
END_IF
|
|
IF _fbPressureNegolytTankInlet.xError THEN
|
|
stModbusErrors.stBitmap.bPTankNegError := 1;
|
|
END_IF
|
|
|
|
// Set modbus warning register bits
|
|
IF _fbPressureNegolytTankInlet.xWarningLow THEN
|
|
stModbusWarnings.stBitmap.bPTankNegLow := 1;
|
|
END_IF
|
|
IF _fbPressureNegolytTankInlet.xWarningHigh THEN
|
|
stModbusWarnings.stBitmap.bPTankNegHigh := 1;
|
|
END_IF
|
|
|
|
// Set error active if fb has error
|
|
IF _fbPressureNegolytTankInlet.xError THEN
|
|
_xErrorActive := TRUE;
|
|
END_IF
|
|
|
|
// Set warning if fb has warning
|
|
IF _fbPressureNegolytTankInlet.xWarning THEN
|
|
_xWarningActive := TRUE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Temperature sensor posolyt tank inlet
|
|
// ===============================
|
|
_fbTempSensorPosolyt(
|
|
stScalingConfig:= stUnitConfig.stConfigPosolytTempTankInlet,
|
|
stEWConfig:= GVL_CONFIG.stUnitConfig.stEWLPosolytTempTankInlet,
|
|
stEWDelayConfig:= GVL_CONFIG.stUnitConfig.stEWDPosolytTempTankInlet,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
xReleaseLimitErrors:= xReleaseLimitErrors,
|
|
xReleaseHardwareErrors:= xReleaseErrors,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
stHMIInterface=> stHMIInterface.stT11);
|
|
|
|
// Set modbus error register bits
|
|
IF _fbTempSensorPosolyt.xErrorLow THEN
|
|
stModbusErrors.stBitmap.bTPosLow := 1;
|
|
END_IF
|
|
IF _fbTempSensorPosolyt.xErrorHigh THEN
|
|
stModbusErrors.stBitmap.bTPosHigh := 1;
|
|
END_IF
|
|
IF _fbTempSensorPosolyt.xError THEN
|
|
stModbusErrors.stBitmap.bTPosError := 1;
|
|
END_IF
|
|
|
|
// Set modbus warning register bits
|
|
IF _fbTempSensorPosolyt.xWarningLow THEN
|
|
stModbusWarnings.stBitmap.bTPosLow := 1;
|
|
END_IF
|
|
IF _fbTempSensorPosolyt.xWarningHigh THEN
|
|
stModbusWarnings.stBitmap.bTPosHigh := 1;
|
|
END_IF
|
|
|
|
IF _fbTempSensorPosolyt.xError THEN
|
|
_xErrorActive := TRUE;
|
|
END_IF
|
|
|
|
IF _fbTempSensorPosolyt.xWarning THEN
|
|
_xWarningActive := TRUE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Temperature sensor negolyt tank inlet
|
|
// ===============================
|
|
_fbTempSensorNegolyt(
|
|
stScalingConfig:= stUnitConfig.stConfigNegolytTempTankInlet,
|
|
stEWConfig:= GVL_CONFIG.stUnitConfig.stEWLNegolytTempTankInlet,
|
|
stEWDelayConfig:= GVL_CONFIG.stUnitConfig.stEWDNegolytTempTankInlet,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
xReleaseLimitErrors:= xReleaseLimitErrors,
|
|
xReleaseHardwareErrors:= xReleaseErrors,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
stHMIInterface=> stHMIInterface.stT21);
|
|
|
|
// Set modbus error register bits
|
|
IF _fbTempSensorNegolyt.xErrorLow THEN
|
|
stModbusErrors.stBitmap.bTNegLow := 1;
|
|
END_IF
|
|
IF _fbTempSensorNegolyt.xErrorHigh THEN
|
|
stModbusErrors.stBitmap.bTNegHigh := 1;
|
|
END_IF
|
|
IF _fbTempSensorNegolyt.xError THEN
|
|
stModbusErrors.stBitmap.bTNegError := 1;
|
|
END_IF
|
|
|
|
// Set modbus warning register bits
|
|
IF _fbTempSensorNegolyt.xWarningLow THEN
|
|
stModbusWarnings.stBitmap.bTNegLow := 1;
|
|
END_IF
|
|
IF _fbTempSensorNegolyt.xWarningHigh THEN
|
|
stModbusWarnings.stBitmap.bTNegHigh := 1;
|
|
END_IF
|
|
|
|
IF _fbTempSensorNegolyt.xError THEN
|
|
_xErrorActive := TRUE;
|
|
END_IF
|
|
|
|
IF _fbTempSensorNegolyt.xWarning THEN
|
|
_xWarningActive := TRUE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Voltage segment
|
|
// ===============================
|
|
_fbVoltageSegment(
|
|
stScalingConfig:= GVL_CONFIG.stUnitConfig.stConfigVoltageSegment,
|
|
stEWConfig:= GVL_CONFIG.stUnitConfig.stEWLVoltageSegment,
|
|
stEWDelayConfig:= GVL_CONFIG.stUnitConfig.stEWDVoltageSegment,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
xReleaseLimitErrors:= xReleaseLimitErrors AND _xEnableVoltageLimitChecks,
|
|
xReleaseHardwareErrors:= xReleaseErrors,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
stHMIInterface=> stHMIInterface.stE31,
|
|
rScaledValue => rCurrentVoltage);
|
|
|
|
// Set modbus error register bits
|
|
IF _fbVoltageSegment.xErrorLow THEN
|
|
stModbusErrors.stBitmap.bVLow := 1;
|
|
END_IF
|
|
IF _fbVoltageSegment.xErrorHigh THEN
|
|
stModbusErrors.stBitmap.bVHigh := 1;
|
|
END_IF
|
|
IF _fbVoltageSegment.xError THEN
|
|
stModbusErrors.stBitmap.bVError := 1;
|
|
END_IF
|
|
|
|
// Set modbus warning register bits
|
|
IF _fbVoltageSegment.xWarningLow THEN
|
|
stModbusWarnings.stBitmap.bVLow := 1;
|
|
END_IF
|
|
IF _fbVoltageSegment.xWarningHigh THEN
|
|
stModbusWarnings.stBitmap.bVHigh := 1;
|
|
END_IF
|
|
|
|
// 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 for EStop
|
|
// ===============================
|
|
IF (NOT xEmergencyStopOk) THEN
|
|
_xErrorActive := TRUE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Write Voltage to HMI
|
|
// ===============================
|
|
stHMIInterface.rVoltage := stHMIInterface.rVoltage * 0.9 + _fbVoltageSegment.rScaledValue * 0.1;
|
|
|
|
|
|
// ===============================
|
|
// Check for pressure difference
|
|
// ===============================
|
|
_xDeltaPSegmentInletToHigh := (ABS(_fbPressurePosolytSegmentInlet.rScaledValue - _fbPressureNegolytSegmentInlet.rScaledValue) > GVL_CONFIG.stUnitConfig.rMaxDeltaPSegmentInlet);
|
|
_xReleaseSignalDeltaPSegment(
|
|
xSignal:= _xDeltaPSegmentInletToHigh,
|
|
xRelease:= _xEnableCheckForDeltaPSegmentInlet,
|
|
timOnDelay:= T#5S,
|
|
timOffDelay:= T#2S,
|
|
xReleaseSignal=> _xErrorDeltaPSegmentInlet);
|
|
|
|
IF _xErrorDeltaPSegmentInlet AND (NOT _fbPressureDiffToBig.bRaised) THEN
|
|
_fbPressureDiffToBig.Raise(0);
|
|
END_IF
|
|
|
|
IF (NOT _xErrorDeltaPSegmentInlet) AND _fbPressureDiffToBig.bRaised THEN
|
|
_fbPressureDiffToBig.Clear(0, FALSE);
|
|
END_IF
|
|
|
|
IF _fbPressureDiffToBig.eConfirmationState = TcEventConfirmationState.WaitForConfirmation THEN
|
|
_fbPressureDiffToBig.Confirm(0);
|
|
END_IF
|
|
|
|
IF _xErrorDeltaPSegmentInlet THEN
|
|
_xErrorActive := 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) AND (NOT xAllToManualMode) THEN
|
|
_fbNotAllAutomaticAlarm.Raise(0);
|
|
END_IF
|
|
|
|
// Clear warning and reset
|
|
IF _fbNotAllAutomaticAlarm.bRaised AND _xAllComponentsInAutomatic THEN
|
|
_fbNotAllAutomaticAlarm.Clear(0, TRUE);
|
|
END_IF
|
|
|
|
// Calculate shutdown discharge threshold
|
|
_rShutdownDischargeVoltageThreshold := GVL_CONFIG.rMinimumUnitVoltage + GVL_CONFIG.rDeltaUnitVoltageShutdownDischarge;
|
|
|
|
|
|
// ===============================
|
|
// Run state machine for startup
|
|
// and shutdown
|
|
// NEEDS TO BE CALLED AFTER ALL COMPONENTS BECAUSE OF RESET AND ALARM ACKNOWLEDGEMENT!!!
|
|
// (e.g. restart pumps after estop if segment voltage is still to high)
|
|
// ===============================
|
|
StateMachine();
|
|
|
|
|
|
// ===============================
|
|
// Output error and warning flags
|
|
// ===============================
|
|
xError := _xErrorActive;
|
|
xWarning := _xWarningActive;
|
|
|
|
IF (NOT xSafetyIntlksOk) THEN
|
|
stModbusErrors.stBitmap.bSafetyIntlk := 1;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Reset modbus error register with alarm confirmation
|
|
// ===============================
|
|
IF xConfirmAlarms THEN
|
|
stModbusErrors.dwRegister := 0;
|
|
stModbusWarnings.dwRegister := 0;
|
|
END_IF
|
|
|
|
// ===============================
|
|
// Handle general error message
|
|
// ===============================
|
|
IF xError AND (NOT _fbUnitError.bRaised) THEN
|
|
_fbUnitError.Raise(0);
|
|
END_IF
|
|
|
|
IF (NOT xError) AND _fbUnitError.bRaised THEN
|
|
_fbUnitError.Clear(0, FALSE);
|
|
END_IF
|
|
|
|
IF _fbUnitError.eConfirmationState = TcEventConfirmationState.WaitForConfirmation AND xConfirmAlarms THEN
|
|
_fbUnitError.Confirm(0);
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Output all components in auto mode
|
|
// ===============================
|
|
xAllComponentsInAuto := _xAllComponentsInAutomatic;]]></ST>
|
|
</Implementation>
|
|
<Method Name="FB_init" Id="{08f1cd44-6483-4d20-ab45-d1938e8ec885}">
|
|
<Declaration><![CDATA[METHOD FB_init : BOOL
|
|
VAR_INPUT
|
|
bInitRetains : BOOL; // if TRUE, the retain variables are initialized (warm start / cold start)
|
|
bInCopyCode : BOOL; // if TRUE, the instance afterwards gets moved into the copy code (online change)
|
|
|
|
sName : STRING;
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[_sName := sName;
|
|
|
|
// Create not all components in automatic mode alarm
|
|
_fbNotAllAutomaticAlarm.CreateEx(TC_EVENTS.General.NotAllCompInAutomatic, bWithConfirmation := FALSE, 0);
|
|
_fbNotAllAutomaticAlarm.ipArguments.Clear().AddString(_sName);
|
|
|
|
// Create unit error
|
|
_fbUnitError.CreateEx(stEventEntry := TC_EVENTS.General.UnitError, bWithConfirmation := TRUE, 0);
|
|
_fbUnitError.ipArguments.Clear().AddString(_sName);]]></ST>
|
|
</Implementation>
|
|
</Method>
|
|
<Property Name="Name" Id="{a82783d4-f1f5-481b-bbb0-7ea8279de793}">
|
|
<Declaration><![CDATA[PROPERTY Name : String]]></Declaration>
|
|
<Get Name="Get" Id="{62ca6bce-5aa4-40f1-aa68-f3e5d22ad4a4}">
|
|
<Declaration><![CDATA[VAR
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[Name := _sName;]]></ST>
|
|
</Implementation>
|
|
</Get>
|
|
<Set Name="Set" Id="{b2e0f6da-5412-45b8-aacd-c140a5beab95}">
|
|
<Declaration><![CDATA[VAR
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[_sName := Name;
|
|
|
|
// Create alarm message
|
|
_fbNotAllAutomaticAlarm.ipArguments.Clear().AddString(_sName);
|
|
_fbPosolytPumpInlet.Name :=CONCAT(_sName, ' - Posolyt segment inlet');
|
|
_fbNegolytPumpInlet.Name := CONCAT(_sName, ' - Negolyt segment inlet');]]></ST>
|
|
</Implementation>
|
|
</Set>
|
|
</Property>
|
|
<Action Name="StateMachine" Id="{2467f04e-fe89-4b6c-a53d-a49981dd0ce6}">
|
|
<Implementation>
|
|
<ST><![CDATA[// ===============================
|
|
// Run state machine for startup and shutdown
|
|
// ===============================
|
|
CASE _iState OF
|
|
0: // Off
|
|
// Start in enable
|
|
IF xEnable AND (NOT xStartBalancing) AND _xAllComponentsInAutomatic AND (NOT _xErrorActive) THEN
|
|
_xReleaseManualMode := FALSE;
|
|
_timUnitStartupWaitTime := GVL_CONFIG.timUnitStartupTime;
|
|
_iState := 10;
|
|
stHMIInterface.eStatus := E_COMPONENT_STATUS.STARTING;
|
|
END_IF
|
|
|
|
// Start in balancing mode
|
|
IF (NOT xEnable) AND xStartBalancing AND _xAllComponentsInAutomatic AND (NOT _xErrorActive) THEN
|
|
_xReleaseManualMode := FALSE;
|
|
xBalancingDone := FALSE;
|
|
_timUnitStartupWaitTime := GVL_CONFIG.timUnitBalancingStartupTime;
|
|
_iState := 10;
|
|
END_IF
|
|
|
|
IF _xErrorActive THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
10: // Open all valves and start pumps
|
|
_fbPosolytValveTankOutlet.ReqAutomaticOpen();
|
|
_fbNegolytValveTankOutlet.ReqAutomaticOpen();
|
|
|
|
_fbPosolytPumpInlet.ReqAutomaticStart();
|
|
_fbNegolytPumpInlet.ReqAutomaticStart();
|
|
_xEnableCheckForDeltaPSegmentInlet := TRUE;
|
|
_rSetpointNegolytPumpInlet := GVL_CONFIG.rPumpNegolytOnPower;
|
|
_rSetpointPosolytPumpInlet := GVL_CONFIG.rPumpPosolytOnPower;
|
|
|
|
xOff := FALSE;
|
|
_iState := 15;
|
|
|
|
15: // Wait for all valves to be open and all pumps to be running
|
|
IF _fbPosolytValveTankOutlet.IsOpen AND _fbNegolytValveTankOutlet.IsOpen AND _fbPosolytPumpInlet.xInTarget AND _fbNegolytPumpInlet.xInTarget THEN
|
|
IF (NOT _fbPosolytValveTankOutlet.xError) AND (NOT _fbNegolytValveTankOutlet.xError) AND (NOT _fbPosolytPumpInlet.xError) AND (NOT _fbNegolytPumpInlet.xError) THEN
|
|
_iState := 30;
|
|
END_IF
|
|
END_IF
|
|
|
|
// If enable signal is lost
|
|
IF ((NOT xEnable) AND (NOT xStartBalancing)) THEN
|
|
stHMIInterface.eStatus := E_COMPONENT_STATUS.SHUTDOWN;
|
|
_iState := 40;
|
|
END_IF
|
|
|
|
// If enable signal is lost, or there is an error, goto shutdown
|
|
IF _xErrorActive THEN
|
|
_xReleaseManualMode := TRUE;
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
IF (NOT xEnable) AND NOT xStartBalancing THEN
|
|
_iState := 51;
|
|
END_IF
|
|
|
|
30: // Wait some time
|
|
_tonStartupCheck(In := TRUE, PT := _timUnitStartupWaitTime);
|
|
|
|
// After some time, check if all values are ok
|
|
IF _tonStartupCheck.Q THEN
|
|
_tonStartupCheck(In := FALSE);
|
|
IF xEnable AND (NOT xStartBalancing) THEN
|
|
_iState := 31;
|
|
ELSIF (NOT xEnable) AND xStartBalancing THEN
|
|
xReady := TRUE;
|
|
_iState := 69;
|
|
END_IF
|
|
END_IF
|
|
|
|
// If enable signal is lost, goto shutdown
|
|
IF (NOT xEnable) AND (NOT xStartBalancing) THEN
|
|
stHMIInterface.eStatus := E_COMPONENT_STATUS.SHUTDOWN;
|
|
_iState := 40;
|
|
END_IF
|
|
|
|
IF _xErrorActive THEN
|
|
_iState := 900;
|
|
END_IF
|
|
|
|
31: // Check if voltage limit can be reached
|
|
_tonVoltageCheckTimeput(IN := TRUE);
|
|
|
|
IF (NOT _xErrorActive) AND (NOT _xWarningActive) THEN
|
|
CASE eStringOperatingMode OF
|
|
E_STRING_OPERATING_MODE.SAFETY_CHECK:
|
|
_xEnableVoltageLimitChecks := TRUE;
|
|
_tonVoltageCheckTimeput(IN := FALSE);
|
|
xReady := TRUE;
|
|
stHMIInterface.eStatus := E_COMPONENT_STATUS.ON;
|
|
_iState := 35;
|
|
|
|
E_STRING_OPERATING_MODE.PRECHARGE:
|
|
_tonVoltageCheckTimeput(IN := FALSE);
|
|
_xEnableVoltageLimitChecks := FALSE;
|
|
xReady := TRUE;
|
|
stHMIInterface.eStatus := E_COMPONENT_STATUS.ON;
|
|
_iState := 35;
|
|
|
|
ELSE
|
|
IF (_fbVoltageSegment.rScaledValue >= GVL_CONFIG.rMinimumUnitVoltage) THEN
|
|
_xEnableVoltageLimitChecks := TRUE;
|
|
xReady := TRUE;
|
|
_iState := 35;
|
|
END_IF
|
|
END_CASE
|
|
END_IF
|
|
// Check for minimum unit voltage
|
|
(*
|
|
IF ((_fbVoltageSegment.rScaledValue >= GVL_CONFIG.rMinimumUnitVoltage) OR xInSafetyCheckMode) AND (NOT _xErrorActive) AND (NOT _xWarningActive) THEN
|
|
_tonVoltageCheckTimeput(IN := FALSE);
|
|
xReady := TRUE;
|
|
|
|
// Only enable Voltage Checks if not in safety check mode
|
|
IF (NOT xInSafetyCheckMode) THEN
|
|
_xEnableVoltageLimitChecks := TRUE;
|
|
END_IF
|
|
|
|
// Continue on normal startup path
|
|
IF xEnable THEN
|
|
stHMIInterface.eStatus := E_COMPONENT_STATUS.ON;
|
|
_iState := 35;
|
|
END_IF
|
|
END_IF
|
|
*)
|
|
|
|
// Voltage check timeout
|
|
IF _tonVoltageCheckTimeput.Q OR _xErrorActive THEN
|
|
_tonVoltageCheckTimeput(IN := FALSE);
|
|
xError := TRUE;
|
|
_iState := 900;
|
|
END_IF
|
|
|
|
// If enable signal is lost, goto shutdown
|
|
IF (NOT xEnable) THEN
|
|
_iState := 40;
|
|
END_IF
|
|
|
|
35: // Unit in enabled state
|
|
_rSetpointNegolytPumpInlet := GVL_CONFIG.rPumpNegolytOnPower;
|
|
_rSetpointPosolytPumpInlet := GVL_CONFIG.rPumpPosolytOnPower;
|
|
|
|
IF (NOT xEnable) THEN
|
|
stHMIInterface.eStatus := E_COMPONENT_STATUS.SHUTDOWN;
|
|
_iState := 40;
|
|
END_IF
|
|
|
|
// Goto error shutdown if an error occured
|
|
IF _xErrorActive THEN
|
|
_iState := 900;
|
|
END_IF
|
|
|
|
40: // Close all valves
|
|
_fbNegolytValveTankOutlet.ReqAutomaticClose();
|
|
_fbPosolytValveTankOutlet.ReqAutomaticClose();
|
|
xReady := FALSE;
|
|
_iState := 45;
|
|
|
|
45: // Wait for valves to be closed
|
|
IF _fbNegolytValveTankOutlet.IsClosed AND _fbPosolytValveTankOutlet.IsClosed THEN
|
|
xInShutdownDischargeMode := TRUE;
|
|
IF (_fbVoltageSegment.rScaledValue > _rShutdownDischargeVoltageThreshold) THEN
|
|
xShutdownDischargeAllowed := TRUE;
|
|
ELSE
|
|
xShutdownDischargeAllowed := FALSE;
|
|
END_IF
|
|
_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
|
|
_xEnableVoltageLimitChecks := FALSE;
|
|
_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 > _rShutdownDischargeVoltageThreshold) AND xInverterEnabled THEN
|
|
xShutdownDischargeAllowed := TRUE;
|
|
ELSE
|
|
xShutdownDischargeAllowed := FALSE;
|
|
_xEnableVoltageLimitChecks := FALSE;
|
|
_rSetpointNegolytPumpInlet := GVL_CONFIG.rPumpNegolytDisChrgPower;
|
|
_rSetpointPosolytPumpInlet := GVL_CONFIG.rPumpPosolytDisChrgPower;
|
|
_xEnableCheckForDeltaPSegmentInlet := FALSE;
|
|
_iState := 51;
|
|
END_IF
|
|
|
|
// Check for restart condition
|
|
IF (xEnable OR xStartBalancing) AND (NOT _xErrorActive) THEN
|
|
xShutdownDischargeAllowed := FALSE;
|
|
xInShutdownDischargeMode := FALSE;
|
|
_iState := 0;
|
|
END_IF
|
|
|
|
IF _xErrorActive THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
51: // Discharge without inverter
|
|
_rSetpointNegolytPumpInlet := GVL_CONFIG.rPumpNegolytDisChrgPower;
|
|
_rSetpointPosolytPumpInlet := GVL_CONFIG.rPumpPosolytDisChrgPower;
|
|
|
|
IF (_fbVoltageSegment.rScaledValue <= GVL_CONFIG.rPumpshutoffThreshold) THEN
|
|
xShutdownDischargeAllowed := FALSE;
|
|
xInShutdownDischargeMode := FALSE;
|
|
_iState := 60;
|
|
END_IF
|
|
|
|
// Check for restart condition
|
|
IF xEnable AND (NOT _xErrorActive) THEN
|
|
xShutdownDischargeAllowed := FALSE;
|
|
xInShutdownDischargeMode := FALSE;
|
|
_iState := 0;
|
|
END_IF
|
|
|
|
// check for balancing condition
|
|
IF xStartBalancing AND (NOT _xErrorActive) THEN
|
|
xShutdownDischargeAllowed := FALSE;
|
|
xInShutdownDischargeMode := FALSE;
|
|
_iState := 0;
|
|
END_IF
|
|
|
|
IF _xErrorActive THEN
|
|
_iState := 1000;
|
|
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
|
|
xOff := TRUE;
|
|
_xReleaseManualMode := TRUE;
|
|
IF NOT _xErrorActive THEN
|
|
stHMIInterface.eStatus := E_COMPONENT_STATUS.OFF;
|
|
_iState := 0;
|
|
END_IF
|
|
END_IF
|
|
|
|
// Check for restart condition
|
|
IF xEnable AND (NOT _xErrorActive) THEN
|
|
stHMIInterface.eStatus := E_COMPONENT_STATUS.OFF;
|
|
_iState := 0;
|
|
END_IF
|
|
|
|
// Check for error
|
|
IF _xErrorActive THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
69: // Check for minimum voltage
|
|
IF (_fbVoltageSegment.rScaledValue <= GVL_CONFIG.rMinimumUnitVoltage) THEN
|
|
_iState := 900;
|
|
ELSE
|
|
_rBalancingTargetVoltage := rBalancingTargetVoltage;
|
|
_istate := 70;
|
|
END_IF
|
|
|
|
70: // Wait for segment voltage to be in the range of the target voltage
|
|
IF (_fbVoltageSegment.rScaledValue <= _rBalancingTargetVoltage) THEN
|
|
xBalancingDone := TRUE;
|
|
_iState := 71;
|
|
END_IF
|
|
|
|
// If enable signal is lost, goto shutdown
|
|
IF (NOT xStartBalancing) THEN
|
|
_iState := 40;
|
|
END_IF
|
|
|
|
IF _xErrorActive THEN
|
|
_iState := 900;
|
|
END_IF
|
|
|
|
71: // Close valves
|
|
_fbNegolytValveTankOutlet.ReqAutomaticClose();
|
|
_fbPosolytValveTankOutlet.ReqAutomaticClose();
|
|
xReady := FALSE;
|
|
_iState := 72;
|
|
|
|
72: // Wait for all valves to be closed
|
|
IF _fbNegolytValveTankOutlet.IsClosed AND _fbPosolytValveTankOutlet.IsClosed THEN
|
|
xInShutdownDischargeMode := TRUE;
|
|
_rSetpointNegolytPumpInlet := GVL_CONFIG.rPumpNegolytDisChrgPower;
|
|
_rSetpointPosolytPumpInlet := GVL_CONFIG.rPumpPosolytDisChrgPower;
|
|
_iState := 73;
|
|
END_IF
|
|
|
|
73: // Wait for start balancing signal to be off to prevent automatic restart
|
|
IF (NOT xStartBalancing) THEN
|
|
_iState := 50;
|
|
END_IF
|
|
|
|
700: // Debug step
|
|
IF (NOT xStartBalancing) THEN
|
|
_iState := 40;
|
|
END_IF
|
|
|
|
900: // Soft error shutdown
|
|
_fbNegolytValveTankOutlet.ReqAutomaticClose();
|
|
_fbPosolytValveTankOutlet.ReqAutomaticClose();
|
|
|
|
_xEnableCheckForDeltaPSegmentInlet := FALSE;
|
|
_rSetpointNegolytPumpInlet := GVL_CONFIG.rPumpNegolytDisChrgPower;
|
|
_rSetpointPosolytPumpInlet := GVL_CONFIG.rPumpPosolytDisChrgPower;
|
|
|
|
_fbNegolytPumpInlet.ReqAutomaticStart();
|
|
_fbPosolytPumpInlet.ReqAutomaticStart();
|
|
|
|
_xEnableVoltageLimitChecks := FALSE;
|
|
xShutdownDischargeAllowed := FALSE;
|
|
xInShutdownDischargeMode := FALSE;
|
|
xReady := FALSE;
|
|
|
|
_iState := 910;
|
|
|
|
910: // Wait for discharged or restart
|
|
IF (_fbVoltageSegment.rScaledValue <= GVL_CONFIG.rPumpshutoffThreshold) THEN
|
|
xShutdownDischargeAllowed := FALSE;
|
|
xInShutdownDischargeMode := FALSE;
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
// Check for restart condition
|
|
IF (NOT xEnable) AND xError THEN
|
|
xError := FALSE;
|
|
END_IF
|
|
|
|
IF (NOT xError) AND (xEnable OR xStartBalancing) THEN
|
|
_iState := 0;
|
|
END_IF
|
|
|
|
IF _xErrorActive THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
1000: // Error shutdown
|
|
stHMIInterface.eStatus := E_COMPONENT_STATUS.ERROR;
|
|
_fbNegolytValveTankOutlet.ReqAutomaticClose();
|
|
_fbPosolytValveTankOutlet.ReqAutomaticClose();
|
|
_rSetpointNegolytPumpInlet := GVL_CONFIG.rPumpNegolytDisChrgPower;
|
|
_rSetpointPosolytPumpInlet := GVL_CONFIG.rPumpPosolytDisChrgPower;
|
|
_xEnableVoltageLimitChecks := FALSE;
|
|
xShutdownDischargeAllowed := FALSE;
|
|
xInShutdownDischargeMode := FALSE;
|
|
xReady := FALSE;
|
|
xOff := TRUE;
|
|
xError := TRUE;
|
|
_iState := 1001;
|
|
|
|
1001: // Alarm active
|
|
// Only allow reset when enable is deactivated to avoid an
|
|
// automatic restart of the unit
|
|
IF (NOT _xErrorActive) AND (NOT xEnable) AND (NOT xStartBalancing) AND _xPumpsReady AND xConfirmAlarms THEN
|
|
xError := FALSE;
|
|
IF (_fbVoltageSegment.rScaledValue >= GVL_CONFIG.rPumpshutoffThreshold) THEN
|
|
_iState := 1002;
|
|
ELSE
|
|
_iState := 0;
|
|
END_IF
|
|
END_IF
|
|
|
|
1002:
|
|
_rSetpointNegolytPumpInlet := GVL_CONFIG.rPumpNegolytDisChrgPower;
|
|
_rSetpointPosolytPumpInlet := GVL_CONFIG.rPumpPosolytDisChrgPower;
|
|
|
|
_fbNegolytPumpInlet.ReqAutomaticStart();
|
|
_fbPosolytPumpInlet.ReqAutomaticStart();
|
|
_iState := 51;
|
|
END_CASE]]></ST>
|
|
</Implementation>
|
|
</Action>
|
|
</POU>
|
|
</TcPlcObject> |