132 lines
3.4 KiB
XML
132 lines
3.4 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<TcPlcObject Version="1.1.0.1">
|
|
<POU Name="FB_RampGenerator" Id="{eab75824-fb3c-460a-af65-da2b006c5dc1}" SpecialFunc="None">
|
|
<Declaration><![CDATA[// Must only be called once per cycle!
|
|
// Otherwise the Interpolation is wrong
|
|
{attribute 'analysis' := '-56'}
|
|
FUNCTION_BLOCK FB_RampGenerator
|
|
VAR_INPUT
|
|
// Current target value
|
|
rTarget : REAL;
|
|
|
|
// Minimum target value
|
|
rTargetMin : REAL;
|
|
|
|
// Maximum target value
|
|
rTargetMax : REAL;
|
|
|
|
// Ramp up time (min to max)
|
|
timRampUp : TIME;
|
|
|
|
// Ramp down time (max to min)
|
|
timRampDown : TIME;
|
|
END_VAR
|
|
VAR_OUTPUT
|
|
rSetpoint : REAL := 0;
|
|
|
|
// Indicates that the target value has been reached
|
|
xInTarget : BOOL;
|
|
END_VAR
|
|
VAR
|
|
// Cycle time in ms
|
|
_rCycleTime : REAL;
|
|
|
|
// Ramp up speed per cycle
|
|
// Units per ms
|
|
_rRampUpSpeed : REAL;
|
|
|
|
// Ramp down speed per cycle
|
|
// Units per ms
|
|
_rRampDownSpeed : REAL;
|
|
|
|
// Distance left to go
|
|
_rDistanceToGo : REAL;
|
|
|
|
// First cycle
|
|
_xFirstCycle : BOOL := TRUE;
|
|
|
|
_fbGetCurTaskIdx : GETCURTASKINDEX;
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[// Get task cycle time during first cycle
|
|
// Does not work in FB_init and also not with {attribute 'call_after_init'}
|
|
IF _xFirstCycle THEN
|
|
_xFirstCycle := FALSE;
|
|
// Get current task cycle time
|
|
_fbGetCurTaskIdx();
|
|
// Convert 100ns to 1ms
|
|
_rCycleTime := UDINT_TO_REAL(TwinCAT_SystemInfoVarList._TASKInfo[_fbGetCurTaskIdx.index].CycleTime) * 10E-5;
|
|
END_IF
|
|
|
|
// Clamp setpoint to min max values
|
|
{analysis -37}
|
|
rTarget := MAX(rTarget, rTargetMin);
|
|
rTarget := MIN(rTarget, rTargetMax);
|
|
{analysis +37}
|
|
|
|
// Calculate change rates
|
|
// TIME datatype is handled internally like a UDINT (32-bit). This leads to a resolution in milliseconds.
|
|
// [_rRampUpSpeed] = units per cycle
|
|
IF timRampUp <> T#0S THEN
|
|
_rRampUpSpeed := (rTargetMax - rTargetMin) * (_rCycleTime / TIME_TO_REAL(timRampUp));
|
|
ELSE
|
|
_rRampUpSpeed := rTargetMax;
|
|
END_IF
|
|
IF timRampDown <> T#0S THEN
|
|
_rRampDownSpeed := -(rTargetMax - rTargetMin) * (_rCycleTime / TIME_TO_REAL(timRampDown));
|
|
ELSE
|
|
_rRampDownSpeed := -rTargetMax;
|
|
END_IF
|
|
|
|
|
|
// Calculate distance left to go
|
|
_rDistanceToGo := rTarget - rSetpoint;
|
|
|
|
// Calculate new setpoint
|
|
IF (_rDistanceToGo > 0.0) THEN
|
|
IF (_rDistanceToGo > _rRampUpSpeed) THEN
|
|
rSetpoint := rSetpoint + _rRampUpSpeed;
|
|
ELSE
|
|
rSetpoint := rTarget;
|
|
END_IF
|
|
ELSIF (_rDistanceToGo < 0.0) THEN
|
|
IF (_rDistanceToGo < _rRampDownSpeed) THEN
|
|
rSetpoint := rSetpoint + _rRampDownSpeed;
|
|
ELSE
|
|
rSetpoint := rTarget;
|
|
END_IF
|
|
ELSE
|
|
rSetpoint := rTarget;
|
|
END_IF
|
|
|
|
// Check if we are in range of target range
|
|
IF ABS(rSetpoint-rTarget) <= 0.001 THEN
|
|
xInTarget := TRUE;
|
|
ELSE
|
|
xInTarget := FALSE;
|
|
END_IF ]]></ST>
|
|
</Implementation>
|
|
<Property Name="CycleTime" Id="{12c00f80-a9cf-4d1b-ac68-3c3e59228015}">
|
|
<Declaration><![CDATA[PROPERTY CycleTime : REAL]]></Declaration>
|
|
<Get Name="Get" Id="{06853e5f-48e3-4643-ae4f-e23a07d71695}">
|
|
<Declaration><![CDATA[VAR
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[CycleTime := _rCycleTime;]]></ST>
|
|
</Implementation>
|
|
</Get>
|
|
</Property>
|
|
<Method Name="SetStart" Id="{06f2b416-7cfb-4f46-94e3-4002d92fc703}">
|
|
<Declaration><![CDATA[METHOD SetStart
|
|
VAR_INPUT
|
|
rStartpoint : REAL;
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[rSetpoint := rStartpoint;]]></ST>
|
|
</Implementation>
|
|
</Method>
|
|
</POU>
|
|
</TcPlcObject> |