Added more components

This commit is contained in:
2025-11-13 09:19:39 +01:00
parent 4ad75a3534
commit ae9667622a
56 changed files with 7117 additions and 296 deletions

View File

@@ -0,0 +1,301 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_BlinkerTest" Id="{93a2f3b8-14aa-41c9-9ba1-1c60e3f7d9e3}" SpecialFunc="None">
<Declaration><![CDATA[{attribute 'analysis' := '-31'}
FUNCTION_BLOCK FB_BlinkerTest EXTENDS TcUnit.FB_TestSuite
VAR
// variables for 50Hz test
_fbBlinkerFreq50Hz : FB_Blinker;
_fbDelayFreq50HzOnTimer : TON;
_fbDelayFreq50HzOffTimer : TON;
_fbRtrigFreq50Hz : R_TRIG;
_iFreq50HzCounter : INT := 0;
// variables for 5Hz test
_fbBlinkerFreq5Hz : FB_Blinker;
_fbDelayFreq5HzOnTimer : TON;
_fbDelayFreq5HzOffTimer : TON;
_fbRtrigFreq5Hz : R_TRIG;
_iFreq5HzCounter : INT := 0;
// variables for 2Hz test
_fbBlinkerFreq2Hz : FB_Blinker;
_fbDelayFreq2HzOnTimer : TON;
_fbDelayFreq2HzOffTimer : TON;
_fbRtrigFreq2Hz : R_TRIG;
_iFreq2HzCounter : INT := 0;
// variables for 1Hz test
_fbBlinkerFreq1Hz : FB_Blinker;
_fbDelayFreq1HzOnTimer : TON;
_fbDelayFreq1HzOffTimer : TON;
_fbRtrigFreq1Hz : R_TRIG;
_iFreq1HzCounter : INT := 0;
// variables for 0.5Hz test
_fbBlinkerFreq0_5Hz : FB_Blinker;
_fbDelayFreq0_5HzOnTimer : TON;
_fbDelayFreq0_5HzOffTimer : TON;
_fbRtrigFreq0_5Hz : R_TRIG;
_iFreq0_5HzCounter : INT := 0;
// variables for 0.1Hz test
_fbBlinkerFreq0_1Hz : FB_Blinker;
_fbDelayFreq0_1HzOnTimer : TON;
_fbDelayFreq0_1HzOffTimer : TON;
_fbRtrigFreq0_1Hz : R_TRIG;
_iFreq0_1HzCounter : INT := 0;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// test blinker for different frequencies
TestOutputFrequency50Hz();
TestOutputFrequency5Hz();
TestOutputFrequency2Hz();
TestOutputFrequency1Hz();
TestOutputFrequency0_5Hz();
{analysis -140}
// TestOutputFrequency0_1Hz();]]></ST>
</Implementation>
<Method Name="TestOutputFrequency0_1Hz" Id="{c17bb511-c82a-42b8-a274-50330416d4e0}">
<Declaration><![CDATA[METHOD TestOutputFrequency0_1Hz
VAR
// blinker output
_xOut : BOOL;
END_VAR
VAR CONSTANT
// delay for timer
timDelay : TIME := T#5S;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestOutputFrequency0_1Hz');
// alternating timers (0.1Hz blinking frequency)
_fbDelayFreq0_1HzOnTimer(IN := NOT _fbDelayFreq0_1HzOffTimer.Q, PT := timDelay);
_fbDelayFreq0_1HzOffTimer(IN := _fbDelayFreq0_1HzOnTimer.Q, PT := timDelay);
_fbRtrigFreq0_1Hz(CLK := _fbDelayFreq0_1HzOnTimer.Q);
// run blinker
_fbBlinkerFreq0_1Hz(rFrequency := 0.1, xOut => _xOut);
// check results for each cycle depending on alternating timers
IF _fbDelayFreq0_1HzOnTimer.Q THEN
AssertTrue(_xOut, 'xOut is supposed to be true but is false.');
ELSE
AssertFalse(_xOut, 'xOut is supposed to be false but is true.');
END_IF
// increment counter when timer is done
IF _fbRtrigFreq0_1Hz.Q THEN
_iFreq0_1HzCounter := _iFreq0_1HzCounter + 1;
END_IF
// finish test after 5 blinking cycles
IF _iFreq0_1HzCounter > 5 THEN
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestOutputFrequency0_5Hz" Id="{6ceaefc3-45ad-4025-9305-7cee18dd0ee3}">
<Declaration><![CDATA[METHOD TestOutputFrequency0_5Hz
VAR
// blinker output
_xOut : BOOL;
END_VAR
VAR CONSTANT
// delay for timer
timDelay : TIME := T#1S;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestOutputFrequency0_5Hz');
// alternating timers (0.5Hz blinking frequency)
_fbDelayFreq0_5HzOnTimer(IN := NOT _fbDelayFreq0_5HzOffTimer.Q, PT := timDelay);
_fbDelayFreq0_5HzOffTimer(IN := _fbDelayFreq0_5HzOnTimer.Q, PT := timDelay);
_fbRtrigFreq0_5Hz(CLK := _fbDelayFreq0_5HzOnTimer.Q);
// run blinker
_fbBlinkerFreq0_5Hz(rFrequency := 0.5, xOut => _xOut);
// check results for each cycle depending on alternating timers
IF _fbDelayFreq0_5HzOnTimer.Q THEN
AssertTrue(_xOut, 'xOut is supposed to be true but is false.');
ELSE
AssertFalse(_xOut, 'xOut is supposed to be false but is true.');
END_IF
// increment counter when timer is done
IF _fbRtrigFreq0_5Hz.Q THEN
_iFreq0_5HzCounter := _iFreq0_5HzCounter + 1;
END_IF
// finish test after 5 blinking cycles
IF _iFreq0_5HzCounter > 5 THEN
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestOutputFrequency1Hz" Id="{d1f61e42-2489-495d-b533-6fba45f62c50}">
<Declaration><![CDATA[METHOD TestOutputFrequency1Hz
VAR
// blinker output
_xOut : BOOL;
END_VAR
VAR CONSTANT
// delay for timer
timDelay : TIME := T#500MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestOutputFrequency1Hz');
// alternating timers (1Hz blinking frequency)
_fbDelayFreq1HzOnTimer(IN := NOT _fbDelayFreq1HzOffTimer.Q, PT := timDelay);
_fbDelayFreq1HzOffTimer(IN := _fbDelayFreq1HzOnTimer.Q, PT := timDelay);
_fbRtrigFreq1Hz(CLK := _fbDelayFreq1HzOnTimer.Q);
// run blinker
_fbBlinkerFreq1Hz(rFrequency := 1.0, xOut => _xOut);
// check results for each cycle depending on alternating timers
IF _fbDelayFreq1HzOnTimer.Q THEN
AssertTrue(_xOut, 'xOut is supposed to be true but is false.');
ELSE
AssertFalse(_xOut, 'xOut is supposed to be false but is true.');
END_IF
// increment counter when timer is done
IF _fbRtrigFreq1Hz.Q THEN
_iFreq1HzCounter := _iFreq1HzCounter + 1;
END_IF
// finish test after 5 blinking cycles
IF _iFreq1HzCounter > 5 THEN
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestOutputFrequency2Hz" Id="{1e5023d2-a4d9-4826-ac00-229fc3919936}">
<Declaration><![CDATA[METHOD TestOutputFrequency2Hz
VAR
// blinker output
_xOut : BOOL;
END_VAR
VAR CONSTANT
// delay for timer
timDelay : TIME := T#250MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestOutputFrequency2Hz');
// alternating timers (2Hz blinking frequency)
_fbDelayFreq2HzOnTimer(IN := NOT _fbDelayFreq2HzOffTimer.Q, PT := timDelay);
_fbDelayFreq2HzOffTimer(IN := _fbDelayFreq2HzOnTimer.Q, PT := timDelay);
_fbRtrigFreq2Hz(CLK := _fbDelayFreq2HzOnTimer.Q);
// run blinker
_fbBlinkerFreq2Hz(rFrequency := 2.0, xOut => _xOut);
// check results for each cycle depending on alternating timers
IF _fbDelayFreq2HzOnTimer.Q THEN
AssertTrue(_xOut, 'xOut is supposed to be true but is false.');
ELSE
AssertFalse(_xOut, 'xOut is supposed to be false but is true.');
END_IF
// increment counter when timer is done
IF _fbRtrigFreq2Hz.Q THEN
_iFreq2HzCounter := _iFreq2HzCounter + 1;
END_IF
// finish test after 5 blinking cycles
IF _iFreq2HzCounter > 5 THEN
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestOutputFrequency50Hz" Id="{b4a8cd02-0a88-4b2c-9a24-0ee3a74bd6c1}">
<Declaration><![CDATA[METHOD TestOutputFrequency50Hz
VAR
// blinker output
_xOut : BOOL;
END_VAR
VAR CONSTANT
// delay for timer
timDelay : TIME := T#10MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestOutputFrequency50Hz');
// alternating timers (50Hz blinking frequency)
_fbDelayFreq50HzOnTimer(IN := NOT _fbDelayFreq50HzOffTimer.Q, PT := timDelay);
_fbDelayFreq50HzOffTimer(IN := _fbDelayFreq50HzOnTimer.Q, PT := timDelay);
_fbRtrigFreq50Hz(CLK := _fbDelayFreq50HzOnTimer.Q);
// run blinker
_fbBlinkerFreq50Hz(rFrequency := 50.0, xOut => _xOut);
// check results for each cycle depending on alternating timers
IF _fbDelayFreq50HzOnTimer.Q THEN
AssertTrue(_xOut, 'xOut is supposed to be true but is false.');
ELSE
AssertFalse(_xOut, 'xOut is supposed to be false but is true.');
END_IF
// increment counter when timer is done
IF _fbRtrigFreq50Hz.Q THEN
_iFreq50HzCounter := _iFreq50HzCounter + 1;
END_IF
// finish test after 5 blinking cycles
IF _iFreq50HzCounter > 5 THEN
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestOutputFrequency5Hz" Id="{d93914de-f931-4cc2-adcc-04e3043464c9}">
<Declaration><![CDATA[METHOD TestOutputFrequency5Hz
VAR
// blinker output
_xOut : BOOL;
END_VAR
VAR CONSTANT
// delay for timer
timDelay : TIME := T#100MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestOutputFrequency5Hz');
// alternating timers (5Hz blinking frequency)
_fbDelayFreq5HzOnTimer(IN := NOT _fbDelayFreq5HzOffTimer.Q, PT := timDelay);
_fbDelayFreq5HzOffTimer(IN := _fbDelayFreq5HzOnTimer.Q, PT := timDelay);
_fbRtrigFreq5Hz(CLK := _fbDelayFreq5HzOnTimer.Q);
// run blinker
_fbBlinkerFreq5Hz(rFrequency := 5.0, xOut => _xOut);
// check results for each cycle depending on alternating timers
IF _fbDelayFreq5HzOnTimer.Q THEN
AssertTrue(_xOut, 'xOut is supposed to be true but is false.');
ELSE
AssertFalse(_xOut, 'xOut is supposed to be false but is true.');
END_IF
// increment counter when timer is done
IF _fbRtrigFreq5Hz.Q THEN
_iFreq5HzCounter := _iFreq5HzCounter + 1;
END_IF
// finish test after 5 blinking cycles
IF _iFreq5HzCounter > 5 THEN
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_HashFNV1a_32BitTest" Id="{584d6db4-3042-4682-bf3c-6924d5cfd45e}" SpecialFunc="None">
<Declaration><![CDATA[{attribute 'analysis' := '-31'}
FUNCTION_BLOCK FB_HashFNV1a_32BitTest EXTENDS TcUnit.FB_TestSuite
VAR
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// run tests with different strings
TestHashString1();
TestHashString2();
TestHashString3();
TestHashString4();
TestHashString5();
{analysis -140}
// run test with special characters (not needed.)
// TestSpecialCharacter();]]></ST>
</Implementation>
<Method Name="TestHashString1" Id="{6848e3d2-7c66-46db-96ed-dbbf60aafca3}">
<Declaration><![CDATA[METHOD TestHashString1
VAR
// string input
_sString : STRING := 'Hallo Welt!';
// hash result
_udiActual : UDINT;
END_VAR
VAR CONSTANT
// expected hash
udiExpected : UDINT := 16#83258870;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestHashString1');
// run hash function
_udiActual := FC_HashFNV1a_32Bit(ADR(_sString));
// assert results
AssertEquals_UDINT(udiExpected, _udiActual, 'Did not return expected hash result.');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="TestHashString2" Id="{d1a187f2-69ef-4d7b-9820-3422b177f90e}">
<Declaration><![CDATA[METHOD TestHashString2
VAR
// string input
_sString : STRING := 'Ich schreibe ganz ganz viele Tests....';
// hash result
_udiActual : UDINT;
END_VAR
VAR CONSTANT
// expected hash
udiExpected : UDINT := 16#D732A024;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestHashString2');
// run hash function
_udiActual := FC_HashFNV1a_32Bit(ADR(_sString));
// assert results
AssertEquals_UDINT(udiExpected, _udiActual, 'Did not return expected hash result.');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="TestHashString3" Id="{73b939c5-9983-42c2-965b-e966bace91db}">
<Declaration><![CDATA[METHOD TestHashString3
VAR
// string input
_sString : STRING(255) := 'Dies soll ein ganz langer String werden. Dieses Vorgehen ist sinnvoll, damit die Grenzen der Hashfunktion getestet werden koennen. Ausserdem ist es interessant, ob Sonderzeichen wie: , , , , und ... funktionieren. Leider funktionieren diese nicht...';
// hash result
_udiActual : UDINT;
END_VAR
VAR CONSTANT
// expected hash
udiExpected : UDINT := 16#BD4EBCD2;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestHashString3');
// run hash function
_udiActual := FC_HashFNV1a_32Bit(ADR(_sString));
// assert results
AssertEquals_UDINT(udiExpected, _udiActual, 'Did not return expected hash result.');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="TestHashString4" Id="{889fd548-f653-4805-824c-e896f9bf9367}">
<Declaration><![CDATA[METHOD TestHashString4
VAR
// string input
_sString : STRING := 'Hallo Welt!';
// hash result
_udiActual : UDINT;
END_VAR
VAR CONSTANT
// expected hash
udiExpected : UDINT := 16#83258870;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestHashString4');
// run hash function
_udiActual := FC_HashFNV1a_32Bit(ADR(_sString));
// assert results
AssertEquals_UDINT(udiExpected, _udiActual, 'Did not return expected hash result.');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="TestHashString5" Id="{a29b8c4b-5d3e-4229-941d-f616140007f0}">
<Declaration><![CDATA[METHOD TestHashString5
VAR
// string input
_sString : STRING := 'Matthias hat dieses Programm Leistungsoptimiert!';
// hash result
_udiActual : UDINT;
END_VAR
VAR CONSTANT
// expected hash
udiExpected : UDINT := 16#D442FBA9;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestHashString5');
// run hash function
_udiActual := FC_HashFNV1a_32Bit(ADR(_sString));
// assert results
AssertEquals_UDINT(udiExpected, _udiActual, 'Did not return expected hash result.');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="TestSpecialCharacter" Id="{80e59124-8e21-4287-a17c-f0f64d1dd87b}">
<Declaration><![CDATA[METHOD TestSpecialCharacter
VAR
// string input
_sString : STRING := 'äöüß';
// hash result
_udiActual : UDINT;
END_VAR
VAR CONSTANT
// expected hash
udiExpected : UDINT := 16#2891249a;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestSpecialCharacter');
// run hash function
_udiActual := FC_HashFNV1a_32Bit(ADR(_sString));
// assert results
AssertEquals_UDINT(udiExpected, _udiActual, 'Handling of special charater is not possible');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,276 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_PT1Test" Id="{70928114-b90c-4509-80ef-931fbb32faf9}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_PT1Test EXTENDS TcUnit.FB_TestSuite
VAR
// variables for test using T1 = 50 ms
_fbPT1_StepPT1_50 : FB_PT1;
_xInitStepPT1_50 : BOOL := FALSE;
_alrExpectedValuesStepPT1_50 : ARRAY[1..20] OF LREAL;
_iCounterStepPT1_50 : INT := 1;
// variables for test using T1 = 168 ms
_fbPT1_StepPT1_168 : FB_PT1;
_xInitStepPT1_168 : BOOL := FALSE;
_alrExpectedValuesStepPT1_168 : ARRAY[1..20] OF LREAL;
_iCounterStepPT1_168 : INT := 1;
// variables for test using T1 = 15 ms and a step of 2.345
_fbPT1_StepPT1_15_2345 : FB_PT1;
_xInitStepPT1_15_2345 : BOOL := FALSE;
_alrExpectedValuesStepPT1_15_2345 : ARRAY[1..20] OF LREAL;
_iCounterStepPT1_15_2345 : INT := 1;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// test readout of task cycle time
TestCycleTimeReadout();
// test step responses for different time constants
TestOutputStepResponseT1_50ms();
TestOutputStepResponseT1_168ms();
TestOutputStepResponseStep2dot345_T1_15ms();]]></ST>
</Implementation>
<Method Name="TestCycleTimeReadout" Id="{904f47d5-67b3-4556-aaef-cec669b6e988}">
<Declaration><![CDATA[{warning disable C0394}
METHOD TestCycleTimeReadout
VAR
// pt1 instance
_fbPT1 : FB_PT1;
// task index instance
_fbGetCurTaskIdx : GETCURTASKINDEX;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestCycleTimeReadout');
// read current cycle time and abort test in case of cycletime not 10 ms.
_fbGetCurTaskIdx();
IF ((UDINT_TO_REAL(TwinCAT_SystemInfoVarList._TASKInfo[_fbGetCurTaskIdx.index].CycleTime) * 10E-5) - 10.0) > 0.0001 THEN
AssertTrue(FALSE, 'Project cycle time not set to 10ms!');
ELSE
_fbPT1(
lrInput := 0,
timT := T#10MS,
lrOutput => );
// Project should be set to 10ms cycle time for this test to work
AssertEquals_LREAL(Expected := 10.0, Actual := _fbPT1.CycleTime, Delta := 0.01, 'Cycle time is not equal to project cycle time (10ms)');
END_IF
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="TestOutputStepResponseStep2dot345_T1_15ms" Id="{6ad357cb-7b1c-47ef-888c-e7cf604e0662}">
<Declaration><![CDATA[{warning disable C0394}
{attribute 'analysis' := '-26'}
METHOD TestOutputStepResponseStep2dot345_T1_15ms
VAR
// pt1 output
_lrOutput : LREAL;
// error message
_sMessage : STRING := 'Step ';
END_VAR
VAR CONSTANT
// pt1 setpoint
lrSetpoint : LREAL := 2.345;
// delta for assertion
lrDelta : LREAL := 0.0001;
// T1
timT : TIME := T#15MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestOutputStepResponseStep2dot345_T1_15ms');
// init expected values for 20 cyclic calls
IF NOT _xInitStepPT1_15_2345 THEN
_xInitStepPT1_15_2345 := TRUE;
_alrExpectedValuesStepPT1_15_2345[1] := 0.938;
_alrExpectedValuesStepPT1_15_2345[2] := 1.5008;
_alrExpectedValuesStepPT1_15_2345[3] := 1.83848;
_alrExpectedValuesStepPT1_15_2345[4] := 2.041088;
_alrExpectedValuesStepPT1_15_2345[5] := 2.1626528;
_alrExpectedValuesStepPT1_15_2345[6] := 2.23559168;
_alrExpectedValuesStepPT1_15_2345[7] := 2.279355008;
_alrExpectedValuesStepPT1_15_2345[8] := 2.305613005;
_alrExpectedValuesStepPT1_15_2345[9] := 2.321367803;
_alrExpectedValuesStepPT1_15_2345[10] := 2.330820682;
_alrExpectedValuesStepPT1_15_2345[11] := 2.336492409;
_alrExpectedValuesStepPT1_15_2345[12] := 2.339895445;
_alrExpectedValuesStepPT1_15_2345[13] := 2.341937267;
_alrExpectedValuesStepPT1_15_2345[14] := 2.34316236;
_alrExpectedValuesStepPT1_15_2345[15] := 2.343897416;
_alrExpectedValuesStepPT1_15_2345[16] := 2.34433845;
_alrExpectedValuesStepPT1_15_2345[17] := 2.34460307;
_alrExpectedValuesStepPT1_15_2345[18] := 2.344761842;
_alrExpectedValuesStepPT1_15_2345[19] := 2.344857105;
_alrExpectedValuesStepPT1_15_2345[20] := 2.344914263;
END_IF
// run PT1
_fbPT1_StepPT1_15_2345(
lrInput := lrSetpoint,
timT := timT,
lrOutput => _lrOutput);
// set error message according to current step
_sMessage := CONCAT(_sMessage, TO_STRING(_iCounterStepPT1_15_2345));
_sMessage := CONCAT(_sMessage, ' did not return expected value.');
// check values of current step
AssertEquals_LREAL(Expected := _alrExpectedValuesStepPT1_15_2345[_iCounterStepPT1_15_2345], Actual := _lrOutput, Delta := lrDelta, _sMessage);
_iCounterStepPT1_15_2345 := _iCounterStepPT1_15_2345 + 1;
// finish test after 20 cycles
IF _iCounterStepPT1_15_2345 > 20 THEN
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestOutputStepResponseT1_168ms" Id="{95beda9c-524a-46f3-bd27-507fc0dda2e0}">
<Declaration><![CDATA[{warning disable C0394}
{attribute 'analysis' := '-26'}
METHOD TestOutputStepResponseT1_168ms
VAR
// pt1 output
_lrOutput : LREAL;
// error message
_sMessage : STRING := 'Step ';
END_VAR
VAR CONSTANT
// pt1 setpoint
lrSetpoint : LREAL := 1;
// delta for assertion
lrDelta : LREAL := 0.0001;
// T1
timT : TIME := T#168MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestOutputStepResponseT1_168ms');
// init expected values for 20 cyclic calls
IF NOT _xInitStepPT1_168 THEN
_xInitStepPT1_168 := TRUE;
_alrExpectedValuesStepPT1_168[1] := 0.056179775;
_alrExpectedValuesStepPT1_168[2] := 0.109203383;
_alrExpectedValuesStepPT1_168[3] := 0.159248137;
_alrExpectedValuesStepPT1_168[4] := 0.206481388;
_alrExpectedValuesStepPT1_168[5] := 0.251061085;
_alrExpectedValuesStepPT1_168[6] := 0.293136305;
_alrExpectedValuesStepPT1_168[7] := 0.332847749;
_alrExpectedValuesStepPT1_168[8] := 0.370328212;
_alrExpectedValuesStepPT1_168[9] := 0.405703032;
_alrExpectedValuesStepPT1_168[10] := 0.439090502;
_alrExpectedValuesStepPT1_168[11] := 0.470602271;
_alrExpectedValuesStepPT1_168[12] := 0.500343717;
_alrExpectedValuesStepPT1_168[13] := 0.528414295;
_alrExpectedValuesStepPT1_168[14] := 0.554907874;
_alrExpectedValuesStepPT1_168[15] := 0.579913049;
_alrExpectedValuesStepPT1_168[16] := 0.60351344;
_alrExpectedValuesStepPT1_168[17] := 0.625787966;
_alrExpectedValuesStepPT1_168[18] := 0.646811114;
_alrExpectedValuesStepPT1_168[19] := 0.666653186;
_alrExpectedValuesStepPT1_168[20] := 0.685380535;
END_IF
// run PT1
_fbPT1_StepPT1_168(
lrInput := lrSetpoint,
timT := timT,
lrOutput => _lrOutput);
// set error message according to current step
_sMessage := CONCAT(_sMessage, TO_STRING(_iCounterStepPT1_168));
_sMessage := CONCAT(_sMessage, ' did not return expected value.');
// check values of current step
AssertEquals_LREAL(Expected := _alrExpectedValuesStepPT1_168[_iCounterStepPT1_168], Actual := _lrOutput, Delta := lrDelta, _sMessage);
_iCounterStepPT1_168 := _iCounterStepPT1_168 + 1;
// finish test after 20 cycles
IF _iCounterStepPT1_168 > 20 THEN
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestOutputStepResponseT1_50ms" Id="{13fc9847-7f4d-4bad-80e0-d8a65864a692}">
<Declaration><![CDATA[{warning disable C0394}
{attribute 'analysis' := '-26'}
METHOD TestOutputStepResponseT1_50ms
VAR
// pt1 output
_lrOutput : LREAL;
// error message
_sMessage : STRING := 'Step ';
END_VAR
VAR CONSTANT
// pt1 setpoint
lrSetpoint : LREAL := 1;
// delta for assertion
lrDelta : LREAL := 0.0001;
// T1
timT : TIME := T#50MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestOutputStepResponseT1_50ms');
// init expected values for 20 cyclic calls
IF NOT _xInitStepPT1_50 THEN
_xInitStepPT1_50 := TRUE;
_alrExpectedValuesStepPT1_50[1] := 0.166666667;
_alrExpectedValuesStepPT1_50[2] := 0.305555556;
_alrExpectedValuesStepPT1_50[3] := 0.421296296;
_alrExpectedValuesStepPT1_50[4] := 0.517746914;
_alrExpectedValuesStepPT1_50[5] := 0.598122428;
_alrExpectedValuesStepPT1_50[6] := 0.665102023;
_alrExpectedValuesStepPT1_50[7] := 0.720918353;
_alrExpectedValuesStepPT1_50[8] := 0.767431961;
_alrExpectedValuesStepPT1_50[9] := 0.806193301;
_alrExpectedValuesStepPT1_50[10] := 0.838494417;
_alrExpectedValuesStepPT1_50[11] := 0.865412014;
_alrExpectedValuesStepPT1_50[12] := 0.887843345;
_alrExpectedValuesStepPT1_50[13] := 0.906536121;
_alrExpectedValuesStepPT1_50[14] := 0.922113434;
_alrExpectedValuesStepPT1_50[15] := 0.935094528;
_alrExpectedValuesStepPT1_50[16] := 0.945912107;
_alrExpectedValuesStepPT1_50[17] := 0.954926756;
_alrExpectedValuesStepPT1_50[18] := 0.962438963;
_alrExpectedValuesStepPT1_50[19] := 0.968699136;
_alrExpectedValuesStepPT1_50[20] := 0.973915947;
END_IF
// run PT1
_fbPT1_StepPT1_50(
lrInput := lrSetpoint,
timT := timT,
lrOutput => _lrOutput);
// set error message according to current step
_sMessage := CONCAT(_sMessage, TO_STRING(_iCounterStepPT1_50));
_sMessage := CONCAT(_sMessage, ' did not return expected value.');
// check values of current step
AssertEquals_LREAL(Expected := _alrExpectedValuesStepPT1_50[_iCounterStepPT1_50], Actual := _lrOutput, Delta := lrDelta, _sMessage);
_iCounterStepPT1_50 := _iCounterStepPT1_50 + 1;
// finish test after 20 cycles
IF _iCounterStepPT1_50 > 20 THEN
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,473 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_RampGeneratorTest" Id="{883a6789-24bc-434e-bdcd-11047d9142bc}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_RampGeneratorTest EXTENDS TcUnit.FB_TestSuite
VAR
// variables for max clamp test
_fbRMPMaxClamp : FB_RampGenerator;
_fbDelayMaxClamp : TON;
_fbDelayMaxClampBuffer : TON;
// variables for min clamp test
_fbRMPMinClamp : FB_RampGenerator;
_fbDelayMinClamp : TON;
_fbDelayMinClampBuffer : TON;
_xInitMinClamp : BOOL := FALSE;
// variables for ramp down timing test
_fbRMPRampDownTime : FB_RampGenerator;
_fbDelayRampDownTime : TON;
// variables for ramp up timing test
_fbRMPRampUpTime : FB_RampGenerator;
_fbDelayRampUpTime : TON;
// variables for ramp down continuity test
_fbRMPRampDownContinuity : FB_RampGenerator;
_fbDelayRampDownContinuity : TON;
_rNextExpectedDown : REAL := 0;
// variables for ramp up continuity test
_fbRMPRampUpContinuity : FB_RampGenerator;
_fbDelayRampUpContinuity : TON;
_rNextExpectedUp : REAL := 0;
// variables for in target up test
_fbRMPInTargetResultUp : FB_RampGenerator;
_fbDelayInTargetResultUp : TON;
// variables for in target down test
_fbRMPInTargetResultDown : FB_RampGenerator;
_fbDelayInTargetResultDown : TON;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// test for correct cycle time and it's readout
TestCycleTimeReadout();
// test clamping
TestMaxClamping();
TestMinClamping();
// test ramp up/down
TestRampUpTime();
TestRampUpContinuity();
TestRampDownTime();
TestRampDownContinuity();
// test inTarget
TestInTargetResultUp();
TestInTargetResultDown();]]></ST>
</Implementation>
<Method Name="TestCycleTimeReadout" Id="{adf8238e-e5ed-478c-ac22-37930b46e697}">
<Declaration><![CDATA[{warning disable C0394}
METHOD TestCycleTimeReadout
VAR
// ramp generator instance
_fbRampGen : FB_RampGenerator;
// task index instance
_fbGetCurTaskIdx : GETCURTASKINDEX;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestCycleTimeReadout');
// read current cycle time and abort test in case of cycletime not 10 ms.
_fbGetCurTaskIdx();
IF ((UDINT_TO_REAL(TwinCAT_SystemInfoVarList._TASKInfo[_fbGetCurTaskIdx.index].CycleTime) * 10E-5) - 10.0) > 0.001 THEN
AssertTrue(FALSE, 'Project cycle time not set to 10ms!');
ELSE
_fbRampGen(
rTarget:= 0.0,
rTargetMin:= 0.0,
rTargetMax:= 100.0,
timRampUp:= T#5S,
timRampDown:= T#5S,
rSetpoint=> ,
xInTarget=> );
// Project should be set to 10ms cycle time for this test to work
AssertEquals_REAL(Expected := 10.0, Actual := _fbRampGen.CycleTime, Delta := 0.01, 'Cycle time is not equal to project cycle time (10ms)');
END_IF
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="TestInTargetResultDown" Id="{d659dd70-b87c-48f4-9d7b-df95aaef8540}">
<Declaration><![CDATA[{warning disable C0394}
METHOD TestInTargetResultDown
VAR
// in target result
_xInTarget : BOOL;
// current ramp setpoint
_rSetpoint : REAL;
END_VAR
VAR CONSTANT
// delay until in target should be reached
timDelay : TIME := T#990MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestInTargetResultDown');
// timer until InTarget is supposed to be reached
_fbDelayInTargetResultDown(IN := TRUE, PT := timDelay);
// run RampGenerator
_fbRMPInTargetResultDown(
rTarget := -1,
rTargetMin := -1,
rTargetMax := 1,
timRampUp := T#2S,
timRampDown := T#2S,
rSetpoint => _rSetpoint,
xInTarget => _xInTarget);
// check for whether InTarget is reached at the specified time
IF NOT _fbDelayInTargetResultDown.Q THEN
AssertFalse(_xInTarget, 'InTarget reached earlier then expected.');
ELSE
AssertTrue(_xInTarget, 'InTarget not reached in time.');
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestInTargetResultUp" Id="{41467b7e-bd5d-4d30-abee-4fe231a34fce}">
<Declaration><![CDATA[{warning disable C0394}
METHOD TestInTargetResultUp
VAR
// in target result
_xInTarget : BOOL;
// current ramp setpoint
_rSetpoint : REAL;
END_VAR
VAR CONSTANT
// delay until in target should be reached
timDelay : TIME := T#740MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestInTargetResultUp');
// timer until InTarget is supposed to be reached
_fbDelayInTargetResultUp(IN := TRUE, PT := timDelay);
// run RampGenerator
_fbRMPInTargetResultUp(
rTarget := 1,
rTargetMin := -1,
rTargetMax := 1,
timRampUp := T#1S500MS,
timRampDown := T#1S500MS,
rSetpoint => _rSetpoint,
xInTarget => _xInTarget);
// check for whether InTarget is reached at the specified time
IF NOT _fbDelayInTargetResultUp.Q THEN
AssertFalse(_xInTarget, 'InTarget reached earlier then expected.');
ELSE
AssertTrue(_xInTarget, 'InTarget not reached in time.');
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestMaxClamping" Id="{65cd0699-a59f-4537-9fbd-e53ee8fb2124}">
<Declaration><![CDATA[{warning disable C0394}
METHOD TestMaxClamping
VAR
// current ramp setpoint
_rSetpoint : REAL;
END_VAR
VAR CONSTANT
// expected clamped value
rExpected : REAL := 5;
// delta for assertion
rDelta : REAL := 0.0001;
// delay until clamping is reached
timDelayRamp : TIME := T#500MS;
// delay to check for value changes after clamping
timDelay : TIME := T#1S;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestMaxClamping');
// timer until until clamping is reach + timeBuffer afterwards to check whether is stays clamped or not
_fbDelayMaxClamp(IN := TRUE, PT := timDelayRamp);
_fbDelayMaxClampBuffer(IN := TRUE, PT := timDelay);
// run RampGenerator
_fbRMPMaxClamp(
rTarget := 10,
rTargetMin := 0,
rTargetMax := 5,
timRampUp := T#500MS,
timRampDown := T#500MS,
rSetpoint => _rSetpoint,
xInTarget =>);
// check for clamping
IF NOT _fbDelayMaxClamp.Q THEN
// too early
AssertTrue(_rSetpoint < rExpected,'Clamped value reached before expected time');
ELSE
// after expected rampTime
IF NOT _fbDelayMaxClampBuffer.Q THEN
AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value did not stay on or did not reach MaxTarget');
ELSE
TEST_FINISHED();
END_IF
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestMinClamping" Id="{e7c98271-509c-4227-870c-3cb3245da266}">
<Declaration><![CDATA[{warning disable C0394}
METHOD TestMinClamping
VAR
// current ramp setpoint
_rSetpoint : REAL;
END_VAR
VAR CONSTANT
// expected clamped value
rExpected : REAL := 5;
// delta for assertion
rDelta : REAL := 0.0001;
// delay until clamping is reached
timDelayRamp : TIME := T#500MS;
// delay to check for value changes after clamping
timDelay : TIME := T#1S;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestMinClamping');
// init start at top cap
IF NOT _xInitMinClamp THEN
_fbRMPMinClamp.SetStart(10);
_xInitMinClamp := TRUE;
END_IF
// timer until until clamping is reach + timeBuffer afterwards to check whether is stays clamped or not
_fbDelayMinClamp(IN := TRUE, PT := timDelayRamp);
_fbDelayMinClampBuffer(IN := TRUE, PT := timDelay);
// run RampGenerator
_fbRMPMinClamp(
rTarget := 0,
rTargetMin := 5,
rTargetMax := 10,
timRampUp := T#500MS,
timRampDown := T#500MS,
rSetpoint => _rSetpoint,
xInTarget =>);
// check for clamping
IF NOT _fbDelayMinClamp.Q THEN
// too early
AssertTrue(_rSetpoint >= (rExpected - rDelta), 'Clamped value reached before expected time');
ELSE
// after expected rampTime
IF NOT _fbDelayMinClampBuffer.Q THEN
AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value did not stay on or did not reach MinTarget');
ELSE
TEST_FINISHED();
END_IF
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestRampDownContinuity" Id="{dcb7f0b0-2158-4cf1-af71-745bee5bf2bd}">
<Declaration><![CDATA[{warning disable C0394}
METHOD TestRampDownContinuity
VAR
// current ramp setpoint
_rSetpoint : REAL;
// calculated ramp speed
_rMyRampSpeed : REAL;
END_VAR
VAR CONSTANT
// expected final value
rExpected : REAL := -9.4564;
// delta for assertion
rDelta : REAL := 0.0001;
// delay until final value is reached
timDelay : TIME := T#470MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestRampDownContinuity');
// ramp timer, calc speed & calc next expected ramp step
_fbDelayRampDownContinuity(IN := TRUE, PT := timDelay);
_rMyRampSpeed := 20 * (10 / TIME_TO_REAL(T#1S));
_rNextExpectedDown := _rNextExpectedDown - _rMyRampSpeed;
// run RampGenerator
_fbRMPRampDownContinuity(
rTarget := -9.4564,
rTargetMin := -10,
rTargetMax := 10,
timRampUp := T#1S,
timRampDown := T#1S,
rSetpoint => _rSetpoint,
xInTarget =>);
// check for current expected value
IF NOT _fbDelayRampDownContinuity.Q THEN
AssertEquals_REAL(Expected := _rNextExpectedDown, Actual := _rSetpoint, Delta := rDelta, 'Expected current value was not achieved.');
ELSE
// check for final value
AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value was not reached in time.');
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestRampDownTime" Id="{c4784967-e4fc-415b-8fa5-fb9ce6bb34f7}">
<Declaration><![CDATA[{warning disable C0394}
METHOD TestRampDownTime
VAR
// current ramp setpoint
_rSetpoint : REAL;
END_VAR
VAR CONSTANT
// expected final value
rExpected : REAL := -7.4367;
// delta for assertions
rDelta : REAL := 0.0001;
// delay until final value is reached
timDelay : TIME := T#74MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestRampDownTime');
// timer until bottom of ramp is supposed to be reached
_fbDelayRampDownTime(IN := TRUE, PT := timDelay);
// run RampGenerator
_fbRMPRampDownTime(
rTarget := -7.4367,
rTargetMin := -10,
rTargetMax := 10,
timRampUp := T#500MS,
timRampDown := T#100MS,
rSetpoint => _rSetpoint,
xInTarget =>);
// check whether final value is reach on time or before
IF NOT _fbDelayRampDownTime.Q THEN
AssertTrue(_rSetpoint > (rExpected - rDelta),'Value reached before expected time.');
ELSE
AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value was not reached in time.');
TEST_FINISHED();
END_IF
]]></ST>
</Implementation>
</Method>
<Method Name="TestRampUpContinuity" Id="{3771104c-32d2-4bae-b36b-27a109bac10f}">
<Declaration><![CDATA[{warning disable C0394}
METHOD TestRampUpContinuity
VAR
// current ramp setpoint
_rSetpoint : REAL;
// calculated ramp speed
_rMyRampSpeed : REAL;
END_VAR
VAR CONSTANT
// expected final value
rExpected : REAL := 8.673;
// delta for assertions
rDelta : REAL := 0.0001;
// delay until final value is reached
timDelay : TIME := T#860MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestRampUpContinuity');
// ramp timer, calc speed & calc next expected ramp step
_fbDelayRampUpContinuity(IN := TRUE, PT := timDelay);
_rMyRampSpeed := 16.567 * (10 / TIME_TO_REAL(T#1S650MS));
_rNextExpectedUp := _rNextExpectedUp + _rMyRampSpeed;
// run RampGenerator
_fbRMPRampUpContinuity(
rTarget := 8.673,
rTargetMin := -7,
rTargetMax := 9.567,
timRampUp := T#1S650MS,
timRampDown := T#1S,
rSetpoint => _rSetpoint,
xInTarget =>);
// check for current expected value
IF NOT _fbDelayRampUpContinuity.Q THEN
AssertEquals_REAL(Expected := _rNextExpectedUp, Actual := _rSetpoint, Delta := rDelta, 'Expected current value was not achieved.');
ELSE
// check for final value
AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value was not reached in time.');
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="TestRampUpTime" Id="{79d093cd-b7fc-4c92-b138-2dee08eb11bc}">
<Declaration><![CDATA[{warning disable C0394}
METHOD TestRampUpTime
VAR
// current ramp setpoint
_rSetpoint : REAL;
END_VAR
VAR CONSTANT
// expected final value
rExpected : REAL := 8.3456;
// delta for assertions
rDelta : REAL := 0.0001;
// delay until final value is reached
timDelay : TIME := T#440MS;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('TestRampUpTime');
// timer until bottom of ramp is supposed to be reached
_fbDelayRampUpTime(IN := TRUE, PT := timDelay);
// run RampGenerator
_fbRMPRampUpTime(
rTarget := 8.3456,
rTargetMin := -10,
rTargetMax := 10,
timRampUp := T#1S70MS,
timRampDown := T#100MS,
rSetpoint => _rSetpoint,
xInTarget =>);
// check whether final value is reach on time or before
IF NOT _fbDelayRampUpTime.Q THEN
AssertTrue(_rSetpoint < rExpected,'Value reached before expected time.');
ELSE
AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value was not reached in time.');
TEST_FINISHED();
END_IF]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>