Projektdateien hinzufügen.
This commit is contained in:
155
PLC/POUs/FB_Module.TcPOU
Normal file
155
PLC/POUs/FB_Module.TcPOU
Normal file
@@ -0,0 +1,155 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
||||
<POU Name="FB_Module" Id="{87be924f-018d-4c09-997b-f0c0054414cc}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_Module
|
||||
VAR_INPUT
|
||||
// Emergency stop ok
|
||||
xEmergencyStopOk : BOOL;
|
||||
|
||||
// HMI Interface
|
||||
stHMIInterface : REFERENCE TO ST_MODULE_HMI_INTERFACE;
|
||||
|
||||
// Release alarms
|
||||
xReleaseErrors : BOOL;
|
||||
|
||||
// Release analog io limit errors
|
||||
xReleaseLimitErrors : BOOL;
|
||||
|
||||
// Input to confirm all errors
|
||||
xConfirmAlarms : BOOL;
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
// One unit has an error
|
||||
xError : BOOL;
|
||||
|
||||
// One unit has a warning
|
||||
xWarning : BOOL;
|
||||
END_VAR
|
||||
VAR
|
||||
_fbUnit1 : FB_Unit(CONCAT(_sName, ' Unit 1'));
|
||||
_fbUnit2 : FB_Unit(CONCAT(_sName, ' Unit 2'));
|
||||
_fbUnit3 : FB_Unit(CONCAT(_sName, ' Unit 3'));
|
||||
_fbUnit4 : FB_Unit(CONCAT(_sName, ' Unit 4'));
|
||||
|
||||
// Module name
|
||||
_sName : STRING;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Reset error and warning flag
|
||||
xError := FALSE;
|
||||
xWarning := FALSE;
|
||||
|
||||
// ===============================
|
||||
// Unit 1
|
||||
// ===============================
|
||||
_fbUnit1(
|
||||
stUnitConfig:= GVL_CONFIG.stUnitConfig,
|
||||
stHMIInterface:= stHMIInterface.stHMIInterfaceUnit1,
|
||||
xEmergencyStopOk:= xEmergencyStopOk,
|
||||
rSetpointPosolytPumpInlet:= GVL_CONFIG.rPumpPosolytOnPower,
|
||||
rSetpointNegolytPumpInlet:= GVL_CONFIG.rPumpNegolytOnPower,
|
||||
xReleaseErrors:= xReleaseErrors,
|
||||
xReleaseLimitErrors:= xReleaseLimitErrors,
|
||||
xConfirmAlarms:= xConfirmAlarms,
|
||||
_xWarningConfirmPending=> );
|
||||
|
||||
IF _fbUnit1.xWarning THEN
|
||||
xWarning := TRUE;
|
||||
END_IF
|
||||
|
||||
IF _fbUnit1.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Unit 2
|
||||
// ===============================
|
||||
_fbUnit2(
|
||||
stUnitConfig:= GVL_CONFIG.stUnitConfig,
|
||||
stHMIInterface:= stHMIInterface.stHMIInterfaceUnit2,
|
||||
xEmergencyStopOk:= xEmergencyStopOk,
|
||||
rSetpointPosolytPumpInlet:= GVL_CONFIG.rPumpPosolytOnPower,
|
||||
rSetpointNegolytPumpInlet:= GVL_CONFIG.rPumpNegolytOnPower,
|
||||
xReleaseErrors:= xReleaseErrors,
|
||||
xReleaseLimitErrors:= xReleaseLimitErrors,
|
||||
xConfirmAlarms:= xConfirmAlarms,
|
||||
_xWarningConfirmPending=> );
|
||||
|
||||
IF _fbUnit2.xWarning THEN
|
||||
xWarning := TRUE;
|
||||
END_IF
|
||||
|
||||
IF _fbUnit2.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Unit 3
|
||||
// ===============================
|
||||
_fbUnit3(
|
||||
stUnitConfig:= GVL_CONFIG.stUnitConfig,
|
||||
stHMIInterface:= stHMIInterface.stHMIInterfaceUnit3,
|
||||
xEmergencyStopOk:= xEmergencyStopOk,
|
||||
rSetpointPosolytPumpInlet:= GVL_CONFIG.rPumpPosolytOnPower,
|
||||
rSetpointNegolytPumpInlet:= GVL_CONFIG.rPumpNegolytOnPower,
|
||||
xReleaseErrors:= xReleaseErrors,
|
||||
xReleaseLimitErrors:= xReleaseLimitErrors,
|
||||
xConfirmAlarms:= xConfirmAlarms,
|
||||
_xWarningConfirmPending=> );
|
||||
|
||||
IF _fbUnit3.xWarning THEN
|
||||
xWarning := TRUE;
|
||||
END_IF
|
||||
|
||||
IF _fbUnit3.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Unit 4
|
||||
// ===============================
|
||||
_fbUnit4(
|
||||
stUnitConfig:= GVL_CONFIG.stUnitConfig,
|
||||
stHMIInterface:= stHMIInterface.stHMIInterfaceUnit4,
|
||||
xEmergencyStopOk:= xEmergencyStopOk,
|
||||
rSetpointPosolytPumpInlet:= GVL_CONFIG.rPumpPosolytOnPower,
|
||||
rSetpointNegolytPumpInlet:= GVL_CONFIG.rPumpNegolytOnPower,
|
||||
xReleaseErrors:= xReleaseErrors,
|
||||
xReleaseLimitErrors:= xReleaseLimitErrors,
|
||||
xConfirmAlarms:= xConfirmAlarms,
|
||||
_xWarningConfirmPending=> );
|
||||
|
||||
IF _fbUnit4.xWarning THEN
|
||||
xWarning := TRUE;
|
||||
END_IF
|
||||
|
||||
IF _fbUnit4.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="FB_init" Id="{369c1d27-76e4-45f8-9dbe-03524d3389df}">
|
||||
<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;]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<LineIds Name="FB_Module">
|
||||
<LineId Id="248" Count="92" />
|
||||
<LineId Id="188" Count="0" />
|
||||
</LineIds>
|
||||
<LineIds Name="FB_Module.FB_init">
|
||||
<LineId Id="7" Count="0" />
|
||||
</LineIds>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
124
PLC/POUs/FB_String.TcPOU
Normal file
124
PLC/POUs/FB_String.TcPOU
Normal file
@@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
||||
<POU Name="FB_String" Id="{46501225-f446-4674-bfed-3be64273e576}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_String
|
||||
VAR_INPUT
|
||||
// Module 1 HMI interface
|
||||
stHMIInterface : ST_STRING_HMI_INTERFACE;
|
||||
|
||||
// Emergency stop ok
|
||||
xEmergencyStopOk : BOOL;
|
||||
|
||||
// Release alarms
|
||||
xReleaseErrors : BOOL;
|
||||
|
||||
// Release analog io limit errors
|
||||
xReleaseLimitErrors : BOOL;
|
||||
|
||||
// Input to confirm all errors
|
||||
xConfirmAlarms : BOOL;
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
xError : BOOL;
|
||||
xWarning : BOOL;
|
||||
END_VAR
|
||||
VAR
|
||||
_fbModule1 : FB_Module(CONCAT(_sName, 'Module 1'));
|
||||
_fbModule2 : FB_Module(CONCAT(_sName, 'Module 2'));
|
||||
_fbModule3 : FB_Module(CONCAT(_sName, 'Module 3'));
|
||||
|
||||
// String name
|
||||
_sName : STRING;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// ===============================
|
||||
// Module 1
|
||||
// ===============================
|
||||
_fbModule1(
|
||||
xEmergencyStopOk:= xEmergencyStopOk,
|
||||
stHMIInterface:= stHMIInterface.stHMIInterfaceModule1,
|
||||
xReleaseErrors:= xReleaseErrors,
|
||||
xReleaseLimitErrors:= xReleaseLimitErrors,
|
||||
xConfirmAlarms:= xConfirmAlarms);
|
||||
|
||||
IF _fbModule1.xWarning THEN
|
||||
xWarning := TRUE;
|
||||
END_IF
|
||||
|
||||
IF _fbModule1.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Module 2
|
||||
// ===============================
|
||||
_fbModule2(
|
||||
xEmergencyStopOk:= xEmergencyStopOk,
|
||||
stHMIInterface:= stHMIInterface.stHMIInterfaceModule2,
|
||||
xReleaseErrors:= xReleaseErrors,
|
||||
xReleaseLimitErrors:= xReleaseLimitErrors,
|
||||
xConfirmAlarms:= xConfirmAlarms);
|
||||
|
||||
IF _fbModule2.xWarning THEN
|
||||
xWarning := TRUE;
|
||||
END_IF
|
||||
|
||||
IF _fbModule2.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Module 3
|
||||
// ===============================
|
||||
_fbModule3(
|
||||
xEmergencyStopOk:= xEmergencyStopOk,
|
||||
stHMIInterface:= stHMIInterface.stHMIInterfaceModule3,
|
||||
xReleaseErrors:= xReleaseErrors,
|
||||
xReleaseLimitErrors:= xReleaseLimitErrors,
|
||||
xConfirmAlarms:= xConfirmAlarms);
|
||||
|
||||
IF _fbModule3.xWarning THEN
|
||||
xWarning := TRUE;
|
||||
END_IF
|
||||
|
||||
IF _fbModule3.xError THEN
|
||||
xError := TRUE;
|
||||
END_IF]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="FB_init" Id="{9e8494eb-1b40-4be9-91c8-810ecbdf7f0c}">
|
||||
<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;]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<LineIds Name="FB_String">
|
||||
<LineId Id="69" Count="0" />
|
||||
<LineId Id="67" Count="1" />
|
||||
<LineId Id="47" Count="1" />
|
||||
<LineId Id="50" Count="3" />
|
||||
<LineId Id="58" Count="0" />
|
||||
<LineId Id="62" Count="0" />
|
||||
<LineId Id="64" Count="0" />
|
||||
<LineId Id="66" Count="0" />
|
||||
<LineId Id="63" Count="0" />
|
||||
<LineId Id="59" Count="2" />
|
||||
<LineId Id="71" Count="17" />
|
||||
<LineId Id="70" Count="0" />
|
||||
<LineId Id="90" Count="17" />
|
||||
<LineId Id="89" Count="0" />
|
||||
</LineIds>
|
||||
<LineIds Name="FB_String.FB_init">
|
||||
<LineId Id="7" Count="0" />
|
||||
</LineIds>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
535
PLC/POUs/FB_Unit.TcPOU
Normal file
535
PLC/POUs/FB_Unit.TcPOU
Normal file
@@ -0,0 +1,535 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.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;
|
||||
|
||||
// Emergency stop ok
|
||||
xEmergencyStopOk : BOOL;
|
||||
|
||||
// Setpoint posolyt pump inlet
|
||||
rSetpointPosolytPumpInlet : REAL;
|
||||
|
||||
// Setpoint negolyt pump inlet
|
||||
rSetpointNegolytPumpInlet : REAL;
|
||||
|
||||
// Release alarms
|
||||
xReleaseErrors : BOOL;
|
||||
|
||||
// Release analog io limit errors
|
||||
xReleaseLimitErrors : BOOL;
|
||||
|
||||
// Input to confirm all errors
|
||||
xConfirmAlarms : BOOL;
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
// Unit ready
|
||||
xReady : BOOL;
|
||||
|
||||
// Error active
|
||||
xError : BOOL;
|
||||
|
||||
// Warning active
|
||||
xWarning : BOOL;
|
||||
|
||||
// Warning confirmation still pending
|
||||
_xWarningConfirmPending : BOOL;
|
||||
END_VAR
|
||||
VAR
|
||||
// Check unit condition after some time during startup
|
||||
_timUnitStartupWaitTime : TIME := T#20S;
|
||||
|
||||
// Valves posolyt
|
||||
_fbPosolytValveTankOutlet : FB_Valve('Posolyt tank outlet');
|
||||
|
||||
// Valves negolyt
|
||||
_fbNegolytValveTankOutlet : FB_Valve('Negolyt tank outlet');
|
||||
|
||||
// Pumps posolyt
|
||||
_fbPosolytPumpInlet : FB_MotorAnalog('Posolyt segment inlet');
|
||||
|
||||
// Pumps negolyt
|
||||
_fbNegolytPumpInlet : FB_MotorAnalog('Negolyt segment inlet');
|
||||
|
||||
// Pressure sensors posolyt
|
||||
_fbPressurePosolytSegmentInlet : FB_AnalogInput('P1_P');
|
||||
_fbPressurePosolytTankInlet : FB_AnalogInput('P3_P');
|
||||
_fbPressurePosolytTankOutlet : FB_AnalogInput('P4_P');
|
||||
|
||||
// Pressure sensors negolyt
|
||||
_fbPressureNegolytSegmentInlet : FB_AnalogInput('P1_N');
|
||||
_fbPressureNegolytTankInlet : FB_AnalogInput('P3_N');
|
||||
_fbPressureNegolytTankOutlet : FB_AnalogInput('P4_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_0011;
|
||||
|
||||
// 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_0011;
|
||||
|
||||
// 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_0011;
|
||||
|
||||
// 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_0011;
|
||||
|
||||
// Error active
|
||||
_xErrorActive : BOOL;
|
||||
|
||||
// Warning active
|
||||
_xWarningActive : BOOL;
|
||||
|
||||
// Current state
|
||||
_iState: INT;
|
||||
|
||||
// All components in automatic mode
|
||||
_xAllComponentsInAutomatic : BOOL;
|
||||
|
||||
// Not all components in automatic mode alarm
|
||||
_fbNotAllAutomaticAlarm : FB_TcAlarm;
|
||||
|
||||
// Unit name
|
||||
_sName : STRING;
|
||||
|
||||
// Unit startup check timer
|
||||
_tonStartupCheck : TON;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Reset error active
|
||||
_xErrorActive := FALSE;
|
||||
|
||||
// Reset warning active
|
||||
_xWarningActive := FALSE;
|
||||
|
||||
// ===============================
|
||||
// Valve posolyt tank outlet
|
||||
// ===============================
|
||||
|
||||
// Safety Interlocks
|
||||
stHMIInterface.stPosolytValve.stInterlock.asSafetyINTLKName[0] := 'Emergency stop ok';
|
||||
_stPosolytValveTankOutletSIntlk.0 := xEmergencyStopOk;
|
||||
|
||||
// Valve fb
|
||||
_fbPosolytValveTankOutlet(
|
||||
xReleaseManualMode:= TRUE,
|
||||
wProcessINTLK:= _stPosolytValveTankOutletPIntlk,
|
||||
wProcessINTLKUsed:= _stPosolytValveTankOutletPIntlkUsed,
|
||||
wSafetyINTLK:= _stPosolytValveTankOutletSIntlk,
|
||||
wSafetyINTLKUsed:= _stPosolytValveTankOutletSIntlkUsed,
|
||||
xConfirmAlarms:= xConfirmAlarms,
|
||||
xReleaseErrors:= xReleaseErrors,
|
||||
stValveConfig:= stUnitConfig.stConfigPosolytValve,
|
||||
stHMIInterface:= stHMIInterface.stPosolytValve);
|
||||
|
||||
// Set error active if fb has error
|
||||
IF _fbPosolytValveTankOutlet.xError THEN
|
||||
_xErrorActive := TRUE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Valve negolyt tank outlet
|
||||
// ===============================
|
||||
|
||||
// Safety Interlocks
|
||||
stHMIInterface.stNegolytValve.stInterlock.asSafetyINTLKName[0] := 'Emergency stop ok';
|
||||
_stNegolytValveTankOutletSIntlk.0 := xEmergencyStopOk;
|
||||
|
||||
// Valve fb
|
||||
_fbNegolytValveTankOutlet(
|
||||
xReleaseManualMode:= TRUE,
|
||||
wProcessINTLK:= _stNegolytValveTankOutletPIntlk,
|
||||
wProcessINTLKUsed:= _stNegolytValveTankOutletPIntlkUsed,
|
||||
wSafetyINTLK:= _stNegolytValveTankOutletSIntlk,
|
||||
wSafetyINTLKUsed:= _stNegolytValveTankOutletSIntlkUsed,
|
||||
xConfirmAlarms:= xConfirmAlarms,
|
||||
xReleaseErrors:= xReleaseErrors,
|
||||
stValveConfig:= stUnitConfig.stConfigNegolytValve,
|
||||
stHMIInterface:= stHMIInterface.stNegolytValve);
|
||||
|
||||
// Set error active if fb has error
|
||||
IF _fbNegolytValveTankOutlet.xError THEN
|
||||
_xErrorActive := TRUE;
|
||||
END_IF
|
||||
|
||||
|
||||
// ===============================
|
||||
// Pump posolyt segment inlet
|
||||
// ===============================
|
||||
|
||||
// Safety Interlocks
|
||||
stHMIInterface.stPosolytPump.stInterlock.asSafetyINTLKName[0] := 'Emergency stop ok';
|
||||
_stPosolytPumpInletSIntlk.0 := xEmergencyStopOk;
|
||||
|
||||
// Process interlocks
|
||||
stHMIInterface.stPosolytPump.stInterlock.asProcessINTLKName[0] := 'At least one valve is open';
|
||||
_stPosolytPumpInletPIntlk.0 := _fbPosolytValveTankOutlet.IsOpen;
|
||||
|
||||
|
||||
// Valve fb
|
||||
_fbPosolytPumpInlet(
|
||||
xReleaseManualMode:= TRUE,
|
||||
wProcessINTLK:= _stPosolytPumpInletPIntlk,
|
||||
wProcessINTLKUsed:= _stPosolytPumpInletPIntlkUsed,
|
||||
wSafetyINTLK:= _stPosolytPumpInletSIntlk,
|
||||
wSafetyINTLKUsed:= _stPosolytPumpInletSIntlkUsed,
|
||||
xReleaseErrors:= xReleaseErrors,
|
||||
xConfirmAlarms:= xConfirmAlarms,
|
||||
rSPautomatic:= rSetpointPosolytPumpInlet,
|
||||
xReleaseAnalogInLimitErrors:= xReleaseLimitErrors,
|
||||
stMotorAnalogConfig:= stUnitConfig.stConfigPosolytPump,
|
||||
stHMIInterface:= stHMIInterface.stPosolytPump,
|
||||
xWarning=> );
|
||||
|
||||
// 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;]]></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;
|
||||
|
||||
_fbNotAllAutomaticAlarm.CreateEx(TC_EVENTS.General.NotAllCompInAutomatic, bWithConfirmation := FALSE, 0);
|
||||
_fbNotAllAutomaticAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<LineIds Name="FB_Unit">
|
||||
<LineId Id="4232" Count="29" />
|
||||
<LineId Id="4584" Count="0" />
|
||||
<LineId Id="4263" Count="102" />
|
||||
<LineId Id="4619" Count="0" />
|
||||
<LineId Id="4367" Count="46" />
|
||||
<LineId Id="4621" Count="22" />
|
||||
<LineId Id="4620" Count="0" />
|
||||
<LineId Id="4644" Count="1" />
|
||||
<LineId Id="4414" Count="0" />
|
||||
<LineId Id="4647" Count="0" />
|
||||
<LineId Id="4646" Count="0" />
|
||||
<LineId Id="4416" Count="17" />
|
||||
<LineId Id="4444" Count="26" />
|
||||
<LineId Id="4476" Count="33" />
|
||||
<LineId Id="4511" Count="17" />
|
||||
<LineId Id="4653" Count="0" />
|
||||
<LineId Id="4655" Count="2" />
|
||||
<LineId Id="4654" Count="0" />
|
||||
<LineId Id="4529" Count="4" />
|
||||
<LineId Id="4658" Count="0" />
|
||||
<LineId Id="4660" Count="2" />
|
||||
<LineId Id="4659" Count="0" />
|
||||
<LineId Id="4569" Count="0" />
|
||||
<LineId Id="4535" Count="12" />
|
||||
<LineId Id="4663" Count="0" />
|
||||
<LineId Id="4665" Count="2" />
|
||||
<LineId Id="4664" Count="0" />
|
||||
<LineId Id="4548" Count="6" />
|
||||
<LineId Id="4556" Count="6" />
|
||||
<LineId Id="2754" Count="0" />
|
||||
</LineIds>
|
||||
<LineIds Name="FB_Unit.FB_init">
|
||||
<LineId Id="11" Count="1" />
|
||||
<LineId Id="7" Count="1" />
|
||||
</LineIds>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
28
PLC/POUs/MAIN.TcPOU
Normal file
28
PLC/POUs/MAIN.TcPOU
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
||||
<POU Name="MAIN" Id="{bbd7302c-91ce-4697-9f4b-743f57ca5819}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[PROGRAM MAIN
|
||||
VAR
|
||||
_xEmergencyStopOk AT %I* : BOOL;
|
||||
_xReleaseErrors : BOOL;
|
||||
_xReleaseLimitsErrors : BOOL;
|
||||
_xConfirmAlarms : BOOL;
|
||||
_fbString : FB_String('String 1');
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[_fbString(
|
||||
stHMIInterface:= ,
|
||||
xEmergencyStopOk:= _xEmergencyStopOk,
|
||||
xReleaseErrors:= _xReleaseErrors,
|
||||
xReleaseLimitErrors:= _xReleaseLimitsErrors,
|
||||
xConfirmAlarms:= _xConfirmAlarms,
|
||||
xError=> ,
|
||||
xWarning=> );]]></ST>
|
||||
</Implementation>
|
||||
<LineIds Name="MAIN">
|
||||
<LineId Id="7" Count="6" />
|
||||
<LineId Id="2" Count="0" />
|
||||
</LineIds>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
628
PLC/POUs/Sunspec/FB_PowerSupplySunspec.TcPOU
Normal file
628
PLC/POUs/Sunspec/FB_PowerSupplySunspec.TcPOU
Normal file
@@ -0,0 +1,628 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
||||
<POU Name="FB_PowerSupplySunspec" Id="{a826dd09-442c-45c5-8ae3-9b71f293003c}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_PowerSupplySunspec
|
||||
VAR_INPUT
|
||||
sInverterIPAddr : STRING;
|
||||
xEnable : BOOL;
|
||||
rPower : REAL;
|
||||
xReset : BOOL;
|
||||
rMaxBattPower : REAL := 24_000; // 24kW
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
xCloseDCRelais AT %Q*: BOOL;
|
||||
rActDCCurrent : REAL;
|
||||
rActDCVoltage : REAL;
|
||||
xError : BOOL;
|
||||
xActive : BOOL;
|
||||
END_VAR
|
||||
VAR
|
||||
// Current state
|
||||
_iState : INT := 0;
|
||||
|
||||
// FB for reading Modbus holding registers
|
||||
_fbReadRegister : FB_MBReadRegs;
|
||||
|
||||
// FB for writing Modbus holding registers
|
||||
_fbWriteRegister : FB_MBWriteRegs;
|
||||
|
||||
// Timer for checking if the inverter started in a reasonable amount of time
|
||||
_tonInverterStartup : TON;
|
||||
|
||||
// converter max power scaling factor
|
||||
_iWMaxSF : INT;
|
||||
|
||||
// Unscaled converter max power
|
||||
_iWMax : UINT;
|
||||
|
||||
// Scaled converter max power
|
||||
_rWMax : REAL;
|
||||
|
||||
// Unscaled limit for converter power
|
||||
_iWMaxLimPct : INT;
|
||||
|
||||
// Scaling factor for power limiting
|
||||
_iWMaxLimPctSF : INT;
|
||||
|
||||
// Unscaled maximum power from type label
|
||||
_iWRTGSF : INT;
|
||||
|
||||
// Scaling for maximum power from type label
|
||||
_rWRTGScaling : REAL;
|
||||
|
||||
// Current state of the inverters internal statemachine
|
||||
_uiInverterState : UINT;
|
||||
|
||||
// Last written power to the inverter
|
||||
_rOldPower : REAL;
|
||||
|
||||
// Value to enable or dissable the Power limiting feature
|
||||
_uiMaxLimEn : UINT;
|
||||
|
||||
// Value for commanding the target state of the inverter
|
||||
_uiPCSSetOperation : UINT;
|
||||
|
||||
// Holds the state number in which an error occured
|
||||
_iErrorInState : INT;
|
||||
|
||||
// Time for polling for current dc values and check for inverter error
|
||||
_timPollingDelay : TIME := T#250MS;
|
||||
|
||||
// Timer for polling of current values
|
||||
_tonPollingTimer : TON;
|
||||
|
||||
// Current DC values (DCA, DCA_SF, DCV, DCV_SF) in word array for efficient modbus reading
|
||||
_awCurrentDCValues : ARRAY[0..3] OF WORD;
|
||||
|
||||
// Inverter error bits
|
||||
_dwErrorBits : DWORD;
|
||||
|
||||
// Inverter reset errors command
|
||||
_uiResetInverter : UINT := 1;
|
||||
|
||||
END_VAR
|
||||
VAR CONSTANT
|
||||
// Inverter statemachine status register
|
||||
// Size 1, enum16 (Range = 0 .. 65534, Not implemented = 0xFFFF)
|
||||
STATUS_REGISTER : WORD := 40108;
|
||||
|
||||
// Throttled power register
|
||||
// Size 1, int16 (Range = -32767 .. 32767, Not implemented 0x8000)
|
||||
W_MAX_LIM_PCT_REGISTER : WORD := 40187;
|
||||
|
||||
// Throttled power register scaling factor
|
||||
// Size 1, sunssf (int16) (Range = -10 .. 10, Not implemented 0x8000)
|
||||
W_MAX_LIM_PCT_SF_REGISTER : WORD := 40205;
|
||||
|
||||
// Control register to enable and dissable if the power throttleing should be active
|
||||
// Size1, enum16 (Range = 0 .. 65534, Not implemented = 0xFFFF)
|
||||
W_MAX_LIM_EN_REGISTER : WORD := 40191;
|
||||
|
||||
// Register to reset latched alarms in the inverter
|
||||
// Size 1, uint16 (Range = 0 .. 65534, Not implemented = 0xFFFF)
|
||||
PCS_ALARM_RESET_REGISTER : WORD := 40230;
|
||||
|
||||
// Control register to set the target state of the inverters state machine
|
||||
// Size 1, enum16 (Range = 0 .. 65534, Not implemented = 0xFFFF)
|
||||
PCS_SET_OPERATION_REGISTER : WORD := 40231;
|
||||
|
||||
// Maximum inverter output power
|
||||
// Size 1, uint16 (Range = 0 .. 65534, Not implemented = 0xFFFF)
|
||||
W_MAX_REGISTER : WORD := 40152;
|
||||
|
||||
// Maximum inverter output power scaling factor
|
||||
// Size 1, sunssf (int16) (Range = -10 .. 10, Not implemented 0x8000)
|
||||
W_MAX_SF_REGISTER : WORD := 40172;
|
||||
|
||||
// Maximum inverter output power from type label
|
||||
// Size 1, uint16 (Range = 0 .. 65534, Not implemented = 0xFFFF)
|
||||
W_RTG_REGISTER : WORD := 40125;
|
||||
|
||||
// Maximum inverter output power from type label scaling factor
|
||||
// Size 1, sunssf (int16) (Range = -10 .. 10, Not implemented 0x8000)
|
||||
W_RTG_SF_REGISTER : WORD := 40126;
|
||||
|
||||
// Start of register with the current dc values
|
||||
// Size 4
|
||||
DC_VALUES_START_REGISTER : WORD := 40097;
|
||||
|
||||
// Error bits register
|
||||
// Size 2
|
||||
EVT_1_REGISTER : WORD := 40110;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Clamp rPower to maximum allowed power
|
||||
IF (rPower > rMaxBattPower) THEN
|
||||
rPower := rMaxBattPower;
|
||||
END_IF
|
||||
|
||||
IF (rPower < -rMaxBattPower) THEN
|
||||
rPower := -rMaxBattPower;
|
||||
END_IF
|
||||
|
||||
// State machine
|
||||
CASE _iState OF
|
||||
0: // Off
|
||||
// If enable and INTLK Ok
|
||||
IF xEnable THEN
|
||||
_iState := 10;
|
||||
xCloseDCRelais := TRUE;
|
||||
END_IF
|
||||
|
||||
10: // Wait for inverter to be online and in state STANDBY(8)
|
||||
_fbReadRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= STATUS_REGISTER,
|
||||
cbLength:= SIZEOF(_uiInverterState),
|
||||
pDestAddr:= ADR(_uiInverterState),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> ,
|
||||
cbRead=> );
|
||||
|
||||
// Check if reading mudbus register is done
|
||||
IF NOT _fbReadRegister.bBusy THEN
|
||||
// If there was no error and the state is STANDBY(8) then continue
|
||||
IF NOT _fbReadRegister.bError AND _uiInverterState = 8 THEN
|
||||
_iState := 20;
|
||||
END_IF
|
||||
_fbReadRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
20: // Read inverter max power scaling
|
||||
_iErrorInState := _iState;
|
||||
_fbReadRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= W_MAX_SF_REGISTER,
|
||||
cbLength:= SIZEOF(_iWMaxSF),
|
||||
pDestAddr:= ADR(_iWMaxSF),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> ,
|
||||
cbRead=> );
|
||||
|
||||
// Check if reading mudbus register is done
|
||||
IF NOT _fbReadRegister.bBusy THEN
|
||||
// If there was no error then continue
|
||||
IF NOT _fbReadRegister.bError THEN
|
||||
_iState := 25;
|
||||
// Check for valid value
|
||||
IF (_iWMaxSF < -10) OR (_iWMaxSF > 10) OR (_iWMaxSF = 16#8000) THEN
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
ELSE
|
||||
xError := TRUE;
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
_fbReadRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
25: // Read inverter Max power limit scaling
|
||||
_iErrorInState := _iState;
|
||||
_fbReadRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= W_MAX_LIM_PCT_SF_REGISTER,
|
||||
cbLength:= SIZEOF(_iWMaxLimPctSF),
|
||||
pDestAddr:= ADR(_iWMaxLimPctSF),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> ,
|
||||
cbRead=> );
|
||||
|
||||
// Check if reading mudbus register is done
|
||||
IF NOT _fbReadRegister.bBusy THEN
|
||||
// If there was no error then continue
|
||||
IF NOT _fbReadRegister.bError THEN
|
||||
_iState := 30;
|
||||
// Check for valid value
|
||||
IF (_iWMaxLimPctSF < -10) OR (_iWMaxLimPctSF > 10) OR (_iWMaxLimPctSF = 16#8000) THEN
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
ELSE
|
||||
xError := TRUE;
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
_fbReadRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
30: // Read inverter max power
|
||||
_iErrorInState := _iState;
|
||||
_fbReadRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= W_MAX_REGISTER,
|
||||
cbLength:= SIZEOF(_iWMax),
|
||||
pDestAddr:= ADR(_iWMax),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> ,
|
||||
cbRead=> );
|
||||
|
||||
// Check if reading mudbus register is done
|
||||
IF NOT _fbReadRegister.bBusy THEN
|
||||
// If there was no error then continue
|
||||
IF NOT _fbReadRegister.bError THEN
|
||||
_iState := 40;
|
||||
// Reading a register with scaling factor = value * 10^SF
|
||||
_rWMax := _iWMax * EXPT(10,_iWMaxSF);
|
||||
|
||||
// Calculate power to write to register
|
||||
_iWMaxLimPct := LREAL_TO_INT(rPower * EXPT(10,_iWMaxLimPctSF) / _rWMax);
|
||||
ELSE
|
||||
xError := TRUE;
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
_fbReadRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
40: // Set power limit
|
||||
_iErrorInState := _iState;
|
||||
_fbWriteRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= W_MAX_LIM_PCT_REGISTER,
|
||||
cbLength:= SIZEOF(_iWMaxLimPct),
|
||||
pSrcAddr:= ADR(_iWMaxLimPct),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> );
|
||||
|
||||
// If writing modbus register is done
|
||||
IF NOT _fbWriteRegister.bBusy THEN
|
||||
// And there is no error, then continue
|
||||
IF NOT _fbWriteRegister.bError THEN
|
||||
_iState := 50;
|
||||
_rOldPower := rPower;
|
||||
_uiMaxLimEn := 1;
|
||||
ELSE
|
||||
xError := TRUE;
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
_fbWriteRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
50: // Enable Power limiting (THROTTLED)
|
||||
_iErrorInState := _iState;
|
||||
_fbWriteRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= W_MAX_LIM_EN_REGISTER,
|
||||
cbLength:= SIZEOF(_uiMaxLimEn),
|
||||
pSrcAddr:= ADR(_uiMaxLimEn),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> );
|
||||
|
||||
// If writing modbus register is done
|
||||
IF NOT _fbWriteRegister.bBusy THEN
|
||||
// And there is no error, then continue
|
||||
IF NOT _fbWriteRegister.bError THEN
|
||||
_iState := 60;
|
||||
_uiPCSSetOperation := 1;
|
||||
ELSE
|
||||
xError := TRUE;
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
_fbWriteRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
60: // Switch to THROTTLED mode
|
||||
_iErrorInState := _iState;
|
||||
_fbWriteRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= PCS_SET_OPERATION_REGISTER,
|
||||
cbLength:= SIZEOF(_uiPCSSetOperation),
|
||||
pSrcAddr:= ADR(_uiPCSSetOperation),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> );
|
||||
|
||||
// If writing modbus register is done
|
||||
IF NOT _fbWriteRegister.bBusy THEN
|
||||
// And there is no error, then continue
|
||||
IF NOT _fbWriteRegister.bError THEN
|
||||
_iState := 65;
|
||||
ELSE
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
_fbWriteRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
65: // Wait for error polling timer
|
||||
_tonPollingTimer(IN := TRUE, PT := _timPollingDelay);
|
||||
IF _tonPollingTimer.Q THEN
|
||||
_tonPollingTimer(IN := FALSE);
|
||||
_iState := 70;
|
||||
ELSIF ABS(rPower - _rOldPower) > 0.1 THEN
|
||||
_tonPollingTimer(IN := FALSE);
|
||||
// If power has ben changed, goto set power limit mode
|
||||
_iState := 40;
|
||||
END_IF
|
||||
|
||||
// check if inverter should shut down
|
||||
IF NOT xEnable THEN
|
||||
_uiPCSSetOperation := 3;
|
||||
// Goto shutdown sequence
|
||||
_iState := 200;
|
||||
END_IF
|
||||
|
||||
70: // Enabled, check for error
|
||||
_iErrorInState := _iState;
|
||||
_fbReadRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= STATUS_REGISTER,
|
||||
cbLength:= SIZEOF(_uiInverterState),
|
||||
pDestAddr:= ADR(_uiInverterState),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> ,
|
||||
cbRead=> );
|
||||
|
||||
// Check if reading mudbus register is done
|
||||
IF NOT _fbReadRegister.bBusy THEN
|
||||
// If there was no error and the converter has no error continue
|
||||
IF NOT _fbReadRegister.bError AND (_uiInverterState <> 7) THEN
|
||||
_iState := 80;
|
||||
IF (_uiInverterState = 4) OR (_uiInverterState = 5) THEN
|
||||
xActive := TRUE;
|
||||
ELSE
|
||||
xActive := FALSE;
|
||||
END_IF
|
||||
ELSE
|
||||
xError := TRUE;
|
||||
// Read error register
|
||||
_iState := 990;
|
||||
END_IF
|
||||
_fbReadRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
80: // Read current DC values
|
||||
_iErrorInState := _iState;
|
||||
_fbReadRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 4,
|
||||
nMBAddr:= DC_VALUES_START_REGISTER,
|
||||
cbLength:= SIZEOF(_awCurrentDCValues),
|
||||
pDestAddr:= ADR(_awCurrentDCValues),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> ,
|
||||
cbRead=> );
|
||||
|
||||
// Check if reading mudbus register is done
|
||||
IF NOT _fbReadRegister.bBusy THEN
|
||||
// If there was no error and the converter has no error continue
|
||||
IF NOT _fbReadRegister.bError THEN
|
||||
_iState := 65;
|
||||
rActDCCurrent := WORD_TO_UINT(_awCurrentDCValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[1]));
|
||||
rActDCVoltage := WORD_TO_UINT(_awCurrentDCValues[2]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[3]));
|
||||
ELSE
|
||||
// Read error register
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
_fbReadRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
200: // Shutdown sequence
|
||||
_iErrorInState := _iState;
|
||||
_fbWriteRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= PCS_SET_OPERATION_REGISTER,
|
||||
cbLength:= SIZEOF(_uiPCSSetOperation),
|
||||
pSrcAddr:= ADR(_uiPCSSetOperation),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> );
|
||||
|
||||
// If writing modbus register is done
|
||||
IF NOT _fbWriteRegister.bBusy THEN
|
||||
// And there is no error, then continue
|
||||
IF NOT _fbWriteRegister.bError THEN
|
||||
_iState := 210;
|
||||
rActDCCurrent := 0.0;
|
||||
rActDCVoltage := 0.0;
|
||||
ELSE
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
_fbWriteRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
210: // Wait for poll timer to
|
||||
_tonPollingTimer(IN := TRUE, PT := _timPollingDelay);
|
||||
IF _tonPollingTimer.Q THEN
|
||||
_tonPollingTimer(IN := FALSE);
|
||||
_iState := 220;
|
||||
END_IF
|
||||
|
||||
220: // Poll and wait for standby state
|
||||
_iErrorInState := _iState;
|
||||
_fbReadRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= STATUS_REGISTER,
|
||||
cbLength:= SIZEOF(_uiInverterState),
|
||||
pDestAddr:= ADR(_uiInverterState),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> ,
|
||||
cbRead=> );
|
||||
|
||||
// Check if reading mudbus register is done
|
||||
IF NOT _fbReadRegister.bBusy THEN
|
||||
// If there was no error and the converter has no error continue
|
||||
IF NOT _fbReadRegister.bError THEN
|
||||
_iState := 0;
|
||||
xActive := FALSE;
|
||||
xCloseDCRelais := FALSE;
|
||||
END_IF
|
||||
_fbReadRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
990: // Read error register
|
||||
_iErrorInState := _iState;
|
||||
_fbReadRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 2,
|
||||
nMBAddr:= EVT_1_REGISTER,
|
||||
cbLength:= SIZEOF(_dwErrorBits),
|
||||
pDestAddr:= ADR(_dwErrorBits),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> ,
|
||||
cbRead=> );
|
||||
|
||||
// Check if reading mudbus register is done
|
||||
IF NOT _fbReadRegister.bBusy THEN
|
||||
// If there was no error and the converter has no error continue
|
||||
IF NOT _fbReadRegister.bError THEN
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
_fbReadRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
1000: // Error state, wait for reset
|
||||
IF xReset AND (NOT xEnable) THEN
|
||||
_iState := 1010;
|
||||
END_IF
|
||||
|
||||
1010: // Try to clear all latched events
|
||||
_fbWriteRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= PCS_ALARM_RESET_REGISTER,
|
||||
cbLength:= SIZEOF(_uiResetInverter),
|
||||
pSrcAddr:= ADR(_uiResetInverter),
|
||||
bExecute:= TRUE,
|
||||
tTimeout:= T#5S,
|
||||
bBusy=> ,
|
||||
bError=> ,
|
||||
nErrId=> );
|
||||
|
||||
IF NOT _fbWriteRegister.bBusy THEN
|
||||
_iState := 0;
|
||||
_fbWriteRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
END_CASE]]></ST>
|
||||
</Implementation>
|
||||
<LineIds Name="FB_PowerSupplySunspec">
|
||||
<LineId Id="774" Count="70" />
|
||||
<LineId Id="1171" Count="0" />
|
||||
<LineId Id="845" Count="33" />
|
||||
<LineId Id="1172" Count="0" />
|
||||
<LineId Id="879" Count="33" />
|
||||
<LineId Id="1173" Count="0" />
|
||||
<LineId Id="913" Count="29" />
|
||||
<LineId Id="1174" Count="0" />
|
||||
<LineId Id="943" Count="28" />
|
||||
<LineId Id="1175" Count="0" />
|
||||
<LineId Id="972" Count="46" />
|
||||
<LineId Id="1127" Count="0" />
|
||||
<LineId Id="1019" Count="25" />
|
||||
<LineId Id="1097" Count="1" />
|
||||
<LineId Id="1100" Count="1" />
|
||||
<LineId Id="1099" Count="0" />
|
||||
<LineId Id="1045" Count="0" />
|
||||
<LineId Id="1176" Count="0" />
|
||||
<LineId Id="1046" Count="6" />
|
||||
<LineId Id="1063" Count="20" />
|
||||
<LineId Id="1090" Count="0" />
|
||||
<LineId Id="1092" Count="0" />
|
||||
<LineId Id="1084" Count="4" />
|
||||
<LineId Id="1062" Count="0" />
|
||||
<LineId Id="1093" Count="1" />
|
||||
<LineId Id="1102" Count="19" />
|
||||
<LineId Id="1166" Count="1" />
|
||||
<LineId Id="1122" Count="4" />
|
||||
<LineId Id="1054" Count="0" />
|
||||
<LineId Id="1295" Count="4" />
|
||||
<LineId Id="1128" Count="0" />
|
||||
<LineId Id="1300" Count="1" />
|
||||
<LineId Id="1129" Count="0" />
|
||||
<LineId Id="1132" Count="20" />
|
||||
<LineId Id="1163" Count="0" />
|
||||
<LineId Id="1294" Count="0" />
|
||||
<LineId Id="1161" Count="1" />
|
||||
<LineId Id="1130" Count="1" />
|
||||
<LineId Id="1055" Count="0" />
|
||||
<LineId Id="1177" Count="20" />
|
||||
<LineId Id="1199" Count="1" />
|
||||
<LineId Id="1169" Count="0" />
|
||||
<LineId Id="1265" Count="2" />
|
||||
<LineId Id="1269" Count="3" />
|
||||
<LineId Id="1274" Count="11" />
|
||||
<LineId Id="1273" Count="0" />
|
||||
<LineId Id="1289" Count="1" />
|
||||
<LineId Id="1293" Count="0" />
|
||||
<LineId Id="1291" Count="1" />
|
||||
<LineId Id="1056" Count="0" />
|
||||
<LineId Id="12" Count="0" />
|
||||
</LineIds>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
28
PLC/POUs/Sunspec/U_SUNSPEC_ERROR.TcDUT
Normal file
28
PLC/POUs/Sunspec/U_SUNSPEC_ERROR.TcDUT
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
||||
<DUT Name="U_SUNSPEC_ERROR" Id="{4000836c-9d7f-470c-9b50-f6d22b3eac05}">
|
||||
<Declaration><![CDATA[TYPE U_SUNSPEC_ERROR :
|
||||
UNION
|
||||
xGroundFault : BOOL;
|
||||
xDCOverVoltage : BOOL;
|
||||
xACDisconnected : BOOL;
|
||||
xDCDisconnected : BOOL;
|
||||
xGridDisconnected : BOOL;
|
||||
xCabinetOpen : BOOL;
|
||||
xManualShutdown : BOOL;
|
||||
xOverTemp : BOOL;
|
||||
xOverFrequency : BOOL;
|
||||
xUnderFrequency : BOOL;
|
||||
xACOverVoltage : BOOL;
|
||||
xACUnderVoltage : BOOL;
|
||||
xBlownStringFuse : BOOL;
|
||||
xUnderTemp : BOOL;
|
||||
xMemoryLoss : BOOL;
|
||||
xHWTestFailure : BOOL;
|
||||
xOtherAlarm : BOOL;
|
||||
xOtherWarning : BOOL;
|
||||
END_UNION
|
||||
END_TYPE
|
||||
]]></Declaration>
|
||||
</DUT>
|
||||
</TcPlcObject>
|
||||
Reference in New Issue
Block a user