Files
BasicComponents/PLC/POUs/Components/Motor/FB_MotorBecker.TcPOU
2025-11-13 09:19:39 +01:00

497 lines
13 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_MotorBecker" Id="{6ad1d5ad-7633-46cc-9d09-24bf8179e070}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FINAL FB_MotorBecker
VAR_INPUT
// Start motor from automatic
xAutomaticStart : BOOL;
// Automatic setpoint
rSPAutomatic : REAL;
// Analog motor config data
stMotorConfig : ST_MOTOR_BECKER_CONFIG;
// Inverter statusword
udiStatusword AT %I* : UDINT;
// Motor speed process value
rProcessValue AT %I* : REAL;
// Errorword 1
udiErrorword1 AT %I* : UDINT;
// Errorword 2
udiErrorword2 AT %I* : UDINT;
// Release or block change to manual mode
xReleaseManualMode : BOOL;
// Process interlocks
wProcessINTLK : T_INTERLOCK;
// Used process interlocks
wProcessINTLKUsed: T_INTERLOCK;
// Safety interlocks
wSafetyINTLK : T_INTERLOCK;
// Used safety interlocks
wSafetyINTLKUsed: T_INTERLOCK;
// Motor circuit breaker ok
xMCBOk AT %I* : BOOL;
// Repair switch ok
xRepairSwitchOk AT %I* : BOOL;
// Global switch to dissable all errors
xReleaseErrors : BOOL := TRUE;
// Input to confirm all errors
xConfirmAlarms : BOOL;
// Input to tell the fb thats ist used inside a unit test
// FB will not throw error messages
{attribute 'hide'}
xInUnitTestMode : BOOL := FALSE;
END_VAR
VAR_OUTPUT
// Controlword
udiControlword AT %Q* : UDINT;
// Motor frequency setpoint
rMotorFrequency AT %Q* : REAL;
// Motor in target speed
xInTarget : BOOL;
// Warning output
xWarning : BOOL;
// Error output
xError : BOOL;
END_VAR
VAR_IN_OUT
stHMIInterface : ST_HMI_ANALOG_MOTOR_DATA;
END_VAR
VAR
// Internal command for manual mode start request
_xManualStart : BOOL := FALSE;
// Manual mode active
_xManualModeActive : BOOL := FALSE;
// Automatic mode active
_xAutomaticModeActive : BOOL := TRUE;
// Internal start command
_xStart : BOOL;
// Internal setpoint
_rSetpoint : REAL;
// Setpoint from ramp generator in target range
_xRampGenInTarget : BOOL;
// Calculated allowed window for process value
_rPVTargetMax : REAL;
_rPVTargetMin : REAL;
// Ramp generator for start and stop ramp
_fbRamp : FB_RampGenerator;
// Motor MCB tripped
_xMCBTripped : BOOL;
// Motor repair switch tripped
_xRepairSwitchOpenLatched : BOOL;
// Sum of all activated process interlocks latched
_xSafetyINTLKOk : BOOL;
// Sum of all activated process interlocks
_xProcessINTLKOk : BOOL;
// Motor running internal state
_xMotorRunning : BOOL;
// Motor stopped internal state
_xMotorStopped : BOOL;
// Alarm handler for MCB tripped
_fbAlarmMCBTripped : FB_TcAlarm;
_fbMCBTrippedDelayedSignal : FB_ReleaseSignal;
// Alarm handler for repair switch not closed
_fbAlarmRepairSwitchOpen : FB_TcAlarm;
// Error handlers
_fbAlarmNotInTarget : FB_TcAlarm;
_fbNotInRange : FB_ReleaseSignal;
// Helper for statusword
_dwStatusword : DWORD;
// Helper for control word
_dwControlword : DWORD;
// Motor error active
_xError : BOOL;
// Name of the motor
_sName : STRING;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// ===============
// Handle not used
// ===============
IF (NOT stMotorConfig.xUsed) THEN
// Clear all pending alarms if there are any
IF _fbAlarmMCBTripped.bRaised THEN
_fbAlarmMCBTripped.Clear(0, TRUE);
END_IF
IF _fbAlarmRepairSwitchOpen.bRaised THEN
_fbAlarmRepairSwitchOpen.Clear(0, TRUE);
END_IF
IF _fbAlarmNotInTarget.bRaised THEN
_fbAlarmNotInTarget.Clear(0, TRUE);
END_IF
RETURN;
END_IF
// ===========================
// Reset safetyinterlocks flag
// ===========================
IF xConfirmAlarms AND (NOT _xSafetyINTLKOk) THEN
_xSafetyINTLKOk := TRUE;
END_IF
// Check interlocks
CheckInterlocks();
// =================
// Handle HMI inputs
// =================
HandleHMIInput();
// ==============================
// Check if all interlocks are ok
// ==============================
// Only reset manual command if safetyinterlocks are not ok
IF (NOT _xSafetyINTLKOk) AND _xManualStart THEN
// Also reset manual open command if safetyinterlocks are set
_xManualStart := FALSE;
END_IF
// =====================================
// Handle starting and stopping of motor
// =====================================
_xStart := _xProcessINTLKOk AND _xSafetyINTLKOk AND ((_xManualStart AND _xManualModeActive AND (NOT _xAutomaticModeActive)) OR ( xAutomaticStart AND _xAutomaticModeActive AND (NOT _xManualModeActive)));
IF _xStart THEN
IF _xManualModeActive AND (NOT _xAutomaticModeActive) THEN
_rSetpoint := stHMIInterface.stSetpoint.rValue;
ELSIF _xAutomaticModeActive AND (NOT _xManualModeActive) THEN
_rSetpoint := rSPAutomatic;
ELSE
_rSetpoint := 0.0;
END_IF
ELSE
_rSetpoint := 0.0;
END_IF
// Clamp setpoint
_rSetpoint := MAX(stMotorConfig.rTargetMin, _rSetpoint);
_rSetpoint := MIN(stMotorConfig.rTargetMax, _rSetpoint);
// Start stop motor
IF _xStart THEN
// Enable 1
_dwControlword.0 := 1;
// Enable PWM (austrudeln)
_dwControlword.1 := 1;
// Disable fast stop
_dwControlword.2 := 1;
// Seems to be the same as bit 1 and 2
_dwControlword.3 := 1;
_dwControlword.4 := 1;
// Release setpoint
_dwControlword.6 := 1;
// Control via ethercat
_dwControlword.10 := 1;
ELSE
// Enable 1
_dwControlword.0 := 0;
// Enable PWM (austrudeln)
_dwControlword.1 := 1;
// Disable fast stop
_dwControlword.2 := 1;
// Seems to be the same as bit 1 and 2
_dwControlword.3 := 1;
_dwControlword.4 := 1;
// Release setpoint
_dwControlword.6 := 0;
// Control via ethercat
_dwControlword.10 := 1;
END_IF
_dwStatusword := UDINT_TO_DWORD(udiControlword);
// Wait for frequency converter to be enabled when we should start the motor
// before starting the ramp
IF _dwStatusword.0 // Ready to switch on
AND _dwStatusword.1 // Ready for operation
AND _dwStatusword.2 // Operational
AND _dwStatusword.4 // No off 2
AND _dwStatusword.5 // No off 3
AND (NOT _dwStatusword.6) // PWM blocked
AND (NOT _dwStatusword.3) THEN // No error active
END_IF
_fbRamp(
rTarget:= _rSetpoint,
rTargetMin:= stMotorConfig.rTargetMin,
rTargetMax:= stMotorConfig.rTargetMax,
timRampUp:= stMotorConfig.timRampUpTime,
timRampDown:= stMotorConfig.timRampDownTime,
rSetpoint=> _rSetpoint,
xInTarget=> _xRampGenInTarget);
// Calculate target tolerance
_rPVTargetMax := _rSetpoint + stMotorConfig.rTargetTolerance;
_rPVTargetMin := _rSetpoint - stMotorConfig.rTargetTolerance;
// =============
// Handle alarms
// =============
_fbMCBTrippedDelayedSignal(
xSignal:= (NOT xMCBOk),
xRelease:= stMotorConfig.xHasMCBFeedback AND xReleaseErrors,
timOnDelay:= ,
timOffDelay:= ,
xReleaseSignal=> );
// ================
// Reset error flag
// ================
// ================================
// Copy internal signals to outputs
// ================================
udiControlword := DWORD_TO_UDINT(_dwControlword);
xError := _xError;
// ==================
// Handle HMI outputs
// ==================]]></ST>
</Implementation>
<Method Name="CheckInterlocks" Id="{df278299-6ae1-4de0-a0dd-2a6c6fe155af}">
<Declaration><![CDATA[METHOD PRIVATE FINAL CheckInterlocks
VAR
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[// Set interlocks ok
_xProcessINTLKOk := TRUE;
// Check if all active interlocks are ok
IF ((wProcessINTLK AND wProcessINTLKUsed) XOR wProcessINTLKUsed) > 0 THEN
_xProcessINTLKOk := FALSE;
END_IF
// Check safety interlocks
// Safety interlocks will not automatically reset
// They need to be reset via the xConfirmAlarms input
IF ((wSafetyINTLK AND wSafetyINTLKUsed) XOR wSafetyINTLKUsed) > 0 THEN
_xSafetyINTLKOk := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="CreateAlarmMSG" Id="{51bd55f4-6ff2-43af-9b06-6b00c317590c}">
<Declaration><![CDATA[METHOD PRIVATE CreateAlarmMSG
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Reset MCB tripped parameter
_fbAlarmMCBTripped.ipArguments.Clear().AddString(_sName);
// Reset Repair switch open parameter
_fbAlarmRepairSwitchOpen.ipArguments.Clear().AddString(_sName);
_fbAlarmNotInTarget.ipArguments.Clear().AddString(_sName);
]]></ST>
</Implementation>
</Method>
<Method Name="FB_init" Id="{f631cde4-5e68-41ff-9cf4-981cfb26ac03}">
<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[// Name of the function block
_sName := sName;
// Create MCB tripped error
_fbAlarmMCBTripped.CreateEx(stEventEntry := TC_EVENTS.Motor.MCBTripped, TRUE, 0);
// Create repair switch error
_fbAlarmRepairSwitchOpen.CreateEx(stEventEntry := TC_EVENTS.Motor.RepairSwitchOpen, TRUE, 0);
// Create not in target range alarm message
_fbAlarmNotInTarget.CreateEx(stEventEntry := TC_EVENTS.Motor.NotInTarget, bWithConfirmation := TRUE, 0);
// Create alarm messages
CreateAlarmMSG();]]></ST>
</Implementation>
</Method>
<Method Name="HandleHMIInput" Id="{faa08927-4f54-4ff8-952d-185a586720f8}">
<Declaration><![CDATA[METHOD PRIVATE HandleHMIInput
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[{warning disable C0371}
// Handle automatic mode request
IF stHMIInterface.stAutomaticButton.xRequest AND (NOT _xAutomaticModeActive) THEN
_xAutomaticModeActive := TRUE;
_xManualModeActive := FALSE;
END_IF
IF stHMIInterface.stAutomaticButton.xRequest THEN
stHMIInterface.stAutomaticButton.xRequest := FALSE;
END_IF
// Handle manual mode request
IF stHMIInterface.stManualButton.xRequest AND (NOT _xManualModeActive) AND xReleaseManualMode THEN
_xAutomaticModeActive := FALSE;
_xManualModeActive := TRUE;
// Copy last requested valve state into manual
_xManualStart := xAutomaticStart;
stHMIInterface.stSetpoint.rValue := rSPautomatic;
END_IF
IF stHMIInterface.stManualButton.xRequest THEN
stHMIInterface.stManualButton.xRequest := FALSE;
END_IF
// Handle start request
IF stHMIInterface.stStartButton.xRequest AND _xManualModeActive AND _xProcessINTLKOk AND _xSafetyINTLKOk THEN
_xManualStart := TRUE;
END_IF
IF stHMIInterface.stStartButton.xRequest THEN
stHMIInterface.stStartButton.xRequest := FALSE;
END_IF
// Handle stop request
IF stHMIInterface.stStopButton.xRequest AND _xManualModeActive THEN
_xManualStart := FALSE;
END_IF
IF stHMIInterface.stStopButton.xRequest THEN
stHMIInterface.stStopButton.xRequest := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="HandleHMIOutputs" Id="{94e6a928-a0fe-415b-a749-82ef7bb664cb}">
<Declaration><![CDATA[METHOD PRIVATE HandleHMIOutputs
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Copy setpoint min max
stHMIInterface.stSetpoint.rMin := stMotorConfig.rTargetMin;
stHMIInterface.stSetpoint.rMax := stMotorConfig.rTargetMax;]]></ST>
</Implementation>
</Method>
<Property Name="Name" Id="{df07aafd-aaef-4848-9ad0-67f926a1c07c}">
<Declaration><![CDATA[{attribute 'analysis' := '-23'}
PROPERTY Name : STRING]]></Declaration>
<Get Name="Get" Id="{bad90e91-d5f6-49f1-bb66-233ae84af444}">
<Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[Name := _sName;]]></ST>
</Implementation>
</Get>
<Set Name="Set" Id="{995fbf14-9a6c-4644-8204-b1aafcfead5f}">
<Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_sName := Name;
]]></ST>
</Implementation>
</Set>
</Property>
<Property Name="ProcessInterlocksOK" Id="{666a9de5-5207-4562-a6d4-843121e8555a}">
<Declaration><![CDATA[PROPERTY ProcessInterlocksOK : BOOL
]]></Declaration>
<Get Name="Get" Id="{b4c317e2-b02e-4348-87b1-407f40fbb27b}">
<Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[ProcessInterlocksOK := _xProcessINTLKOk;]]></ST>
</Implementation>
</Get>
</Property>
<Method Name="ReqAutomaticMode" Id="{7c1e32af-c936-48bc-92a2-a5719444ed8b}">
<Declaration><![CDATA[METHOD ReqAutomaticMode
]]></Declaration>
<Implementation>
<ST><![CDATA[_xAutomaticModeActive := TRUE;
_xManualModeActive := FALSE;]]></ST>
</Implementation>
</Method>
<Method Name="ReqManualMode" Id="{9b47097e-7518-44f6-8350-29161ed7891b}">
<Declaration><![CDATA[METHOD ReqManualMode
]]></Declaration>
<Implementation>
<ST><![CDATA[IF xReleaseManualMode THEN
_xManualModeActive := TRUE;
_xAutomaticModeActive := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Property Name="SafetyInterlocksOK" Id="{197ebc7f-6847-4ed2-abf6-761b78adf519}">
<Declaration><![CDATA[{attribute 'analysis' := '-31'}
PROPERTY SafetyInterlocksOK : BOOL]]></Declaration>
<Get Name="Get" Id="{b8f43bb8-2d37-40c1-b6a0-879caa30f816}">
<Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[SafetyInterlocksOK := _xSafetyINTLKOk;]]></ST>
</Implementation>
</Get>
</Property>
</POU>
</TcPlcObject>