237 lines
6.2 KiB
XML
237 lines
6.2 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<TcPlcObject Version="1.1.0.1">
|
|
<POU Name="FB_AnalogOutput" Id="{5ea9527b-d363-4c01-ba95-f8c298545979}" SpecialFunc="None">
|
|
<Declaration><![CDATA[FUNCTION_BLOCK FINAL FB_AnalogOutput
|
|
VAR_INPUT
|
|
// Setpoint
|
|
rSetpoint : REAL;
|
|
|
|
// config data for analog output scaling
|
|
stAnalogIOConfig : ST_ANALOG_IO_CONFIG;
|
|
|
|
// 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
|
|
iAnalogValue AT %Q* : INT;
|
|
|
|
// Error in function block
|
|
xError : BOOL;
|
|
END_VAR
|
|
VAR_IN_OUT
|
|
// HMI Interface
|
|
stHMIInterface : ST_HMI_ANALOG_VALUE;
|
|
END_VAR
|
|
VAR
|
|
// Setpoint
|
|
_rSetpointInternal : REAL;
|
|
|
|
// Name of the function block
|
|
_sName : STRING;
|
|
|
|
// Scaling factor for conversion
|
|
_rConversionFactor : REAL;
|
|
|
|
// Base offset for scaling factor
|
|
_rBaseOffset : REAL;
|
|
|
|
// Temporary calculated analog value
|
|
_rTempAnalogValue : REAL;
|
|
|
|
// Config error
|
|
_xConfigError : BOOL;
|
|
|
|
// Max process value
|
|
_rPVMax : REAL;
|
|
|
|
// Min process value
|
|
_rPVMin : REAL;
|
|
|
|
// Config error alarm
|
|
_fbAlarmConfigError : FB_AlarmMessage(stEventEntry := TC_EVENTS.AnalogOutput.ConfigError, xWithConfirmation := FALSE);
|
|
|
|
// Internal error flag
|
|
_xError : BOOL;
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[// ===============
|
|
// Handle not used
|
|
// ===============
|
|
|
|
IF (NOT stAnalogIOConfig.xUsed) THEN
|
|
// Clear all pending alarms if there are any
|
|
_fbAlarmConfigError(xActive := FALSE, xRelease := FALSE);
|
|
|
|
IF xError THEN
|
|
_xError := FALSE;
|
|
xError := FALSE;
|
|
END_IF
|
|
|
|
// Dont execute anything anymore
|
|
RETURN;
|
|
END_IF
|
|
|
|
// =========
|
|
// Prechecks
|
|
// =========
|
|
|
|
// Calculate scaling factors,
|
|
// scaling will be zero in case
|
|
// of invalid scaling parameters.
|
|
CalcScalingFactors();
|
|
|
|
|
|
// ===========================
|
|
// Config error alarm handling
|
|
// ===========================
|
|
|
|
_fbAlarmConfigError(
|
|
xActive:= _xConfigError,
|
|
xRelease:= xReleaseErrors,
|
|
xAcknowledge:= ,
|
|
timOnDelay:= ,
|
|
timOffDelay:= ,
|
|
xInUnitTestMode:= xInUnitTestMode);
|
|
|
|
IF _fbAlarmConfigError.Triggered THEN
|
|
_xError := TRUE;
|
|
END_IF
|
|
|
|
|
|
// ========================
|
|
// Analog value calculation
|
|
// ========================
|
|
|
|
// Clamp analogue input levels
|
|
_rSetpointInternal := MAX(rSetpoint, _rPVMin);
|
|
_rSetpointInternal := MIN(_rSetpointInternal, _rPVMax);
|
|
|
|
// Calc scaled value
|
|
_rTempAnalogValue := _rSetpointInternal * _rConversionFactor + _rBaseOffset;
|
|
iAnalogValue := REAL_TO_INT(_rTempAnalogValue);
|
|
|
|
|
|
// ====================
|
|
// Handle HMI interface
|
|
// ====================
|
|
|
|
stHMIInterface.xUsed := stAnalogIOConfig.xUsed;
|
|
stHMIInterface.sUnit := stAnalogIOConfig.sUnit;
|
|
stHMIInterface.rMin := stAnalogIOConfig.rPVMin;
|
|
stHMIInterface.rMax := stAnalogIOConfig.rPVMax;
|
|
|
|
IF _xError THEN
|
|
stHMIInterface.iStatus := E_HMI_ANALOG_VALUE_STATUS.ERROR;
|
|
ELSE
|
|
stHMIInterface.iStatus := E_HMI_ANALOG_VALUE_STATUS.OK;
|
|
END_IF
|
|
|
|
stHMIInterface.sName := _sName;
|
|
|
|
|
|
// ================
|
|
// Reset error flag
|
|
// ================
|
|
|
|
IF _xError AND xConfirmAlarms AND (NOT _xConfigError) AND (NOT _fbAlarmConfigError.Triggered) THEN
|
|
_xError := FALSE;
|
|
END_IF
|
|
|
|
|
|
// Copy internal signals to outputs
|
|
xError := _xError;]]></ST>
|
|
</Implementation>
|
|
<Method Name="CalcScalingFactors" Id="{7d8169fd-cf9b-4df6-b6f9-6740616693c1}">
|
|
<Declaration><![CDATA[METHOD PRIVATE CalcScalingFactors : BOOL
|
|
VAR
|
|
_rNum : REAL;
|
|
_rDenom : REAL;
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[// _lrConversionFactor := (udiAIMax - udiAIMin)/(rPVMax - rPVMin) + udiAIMin
|
|
// Splitted in two calculations to catch division by zero
|
|
_rNum := INT_TO_REAL(stAnalogIOConfig.iAIMax - stAnalogIOConfig.iAIMin);
|
|
_rDenom := (stAnalogIOConfig.rPVMax - stAnalogIOConfig.rPVMin);
|
|
|
|
// Do not divide by 0 or a negative number
|
|
IF _rDenom > 0.0 THEN
|
|
_rConversionFactor := _rNum/_rDenom;
|
|
_rBaseOffset := INT_TO_REAL(stAnalogIOConfig.iAIMin) - (_rConversionFactor * stAnalogIOConfig.rPVMin);
|
|
_rPVMax := stAnalogIOConfig.rPVMax;
|
|
_rPVMin := stAnalogIOConfig.rPVMin;
|
|
_xConfigError := FALSE;
|
|
ELSE
|
|
// Division by zero happened
|
|
// Or denom was negative
|
|
// Set scaling to zero
|
|
_rConversionFactor := 0.0;
|
|
_rBaseOffset := 0.0;
|
|
_rPVMax := 0.0;
|
|
_rPVMin := 0.0;
|
|
_xConfigError := TRUE;
|
|
END_IF]]></ST>
|
|
</Implementation>
|
|
</Method>
|
|
<Method Name="CreateAlarmMSG" Id="{874f5254-0ec6-4c5e-a9a6-0292ac71a964}">
|
|
<Declaration><![CDATA[METHOD PRIVATE CreateAlarmMSG
|
|
VAR_INPUT
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[{analysis -46}
|
|
_fbAlarmConfigError.Arguments.Clear().AddString(_sName);
|
|
{analysis +46}]]></ST>
|
|
</Implementation>
|
|
</Method>
|
|
<Method Name="FB_init" Id="{0b8b8fc1-2085-4a85-a9d5-deae06fafe01}">
|
|
<Declaration><![CDATA[//FB_Init ist immer implizit verfügbar und wird primär für die Initialisierung verwendet.
|
|
//Der Rückgabewert wird nicht ausgewertet. Für gezielte Einflussnahme können Sie
|
|
//die Methoden explizit deklarieren und darin mit dem Standard-Initialisierungscode
|
|
//zusätzlichen Code bereitstellen. Sie können den Rückgabewert auswerten.
|
|
METHOD FB_Init: BOOL
|
|
VAR_INPUT
|
|
bInitRetains: BOOL; // TRUE: Die Retain-Variablen werden initialisiert (Reset warm / Reset kalt)
|
|
bInCopyCode: BOOL; // TRUE: Die Instanz wird danach in den Kopiercode kopiert (Online-Change)
|
|
|
|
sName : STRING;
|
|
END_VAR]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[_sName := sName;
|
|
|
|
CreateAlarmMSG();]]></ST>
|
|
</Implementation>
|
|
</Method>
|
|
<Property Name="Name" Id="{33bc699d-7760-4934-8e7d-cd24d62ae4d2}">
|
|
<Declaration><![CDATA[PROPERTY Name : STRING(80)]]></Declaration>
|
|
<Get Name="Get" Id="{21d4b695-16bc-443c-9b7e-27e6c5e1de73}">
|
|
<Declaration><![CDATA[VAR
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[Name := _sName;]]></ST>
|
|
</Implementation>
|
|
</Get>
|
|
<Set Name="Set" Id="{c423a761-157c-4651-9a9a-3e5b0e891e86}">
|
|
<Declaration><![CDATA[VAR
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[_sName := Name;
|
|
|
|
// After a name change, all error messages have to be changed
|
|
CreateAlarmMSG();]]></ST>
|
|
</Implementation>
|
|
</Set>
|
|
</Property>
|
|
</POU>
|
|
</TcPlcObject> |