Added more components
This commit is contained in:
469
PLC/POUs/Unittests/AOTests/FB_AnalogOutputTest.TcPOU
Normal file
469
PLC/POUs/Unittests/AOTests/FB_AnalogOutputTest.TcPOU
Normal file
@@ -0,0 +1,469 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<POU Name="FB_AnalogOutputTest" Id="{ebe472aa-270b-4ff7-b47b-01e41ab792c6}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_AnalogOutputTest EXTENDS TcUnit.FB_TestSuite
|
||||
VAR_INPUT
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
END_VAR
|
||||
VAR
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// test invalid parameter
|
||||
TestConfigErrorDivisionByZero();
|
||||
TestConfigErrorNegativMaxMinusMin();
|
||||
|
||||
// test HMI
|
||||
TestHMIOutput();
|
||||
|
||||
// test functionality itself
|
||||
TestOutputScaling();
|
||||
|
||||
// test clamping
|
||||
TestSetpointUpperCap();
|
||||
TestSetpointLowerCap();
|
||||
|
||||
// test unused
|
||||
TestUnused();]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="TestConfigErrorDivisionByZero" Id="{eb0c63a7-066d-4e01-b0f9-aedc1022b328}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestConfigErrorDivisionByZero
|
||||
VAR
|
||||
// analog output instance
|
||||
_fbAnalogOutput : FB_AnalogOutput('');
|
||||
|
||||
// analog output config
|
||||
_stAnalogOutputConfig : ST_ANALOG_IO_CONFIG;
|
||||
|
||||
// analog output hmi data
|
||||
_stHMIInterface : ST_HMI_ANALOG_VALUE;
|
||||
|
||||
// conversion result
|
||||
_iAnalogOutput : INT;
|
||||
|
||||
// fb error
|
||||
_xError : BOOL;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestConfigErrorDivisionByZero');
|
||||
|
||||
// denom = udiAIMax - udiAIMin
|
||||
// Test if no crash occurs when denom equals zero
|
||||
_stAnalogOutputConfig.iAIMax := 4095;
|
||||
_stAnalogOutputConfig.iAIMin := 0;
|
||||
_stAnalogOutputConfig.rPVMax := 0;
|
||||
_stAnalogOutputConfig.rPVMin := 0;
|
||||
|
||||
// run analog scaling
|
||||
_fbAnalogOutput(
|
||||
rSetpoint := 100,
|
||||
stAnalogIOConfig := _stAnalogOutputConfig,
|
||||
xReleaseErrors := ,
|
||||
xConfirmAlarms := ,
|
||||
stHMIInterface := _stHMIInterface,
|
||||
iAnalogValue => _iAnalogOutput,
|
||||
xError => _xError,
|
||||
xInUnitTestMode := TRUE);
|
||||
|
||||
// evaluate Error and result to zero
|
||||
AssertTrue(_xError, 'There should be an error when trying to divide by zero.');
|
||||
AssertEquals_INT(Expected := 0, Actual := _iAnalogOutput, 'Output is expected to be zero when trying to divide by zero');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestConfigErrorNegativMaxMinusMin" Id="{6f3e2737-a3ba-4909-b974-955bc0e635c3}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestConfigErrorNegativMaxMinusMin
|
||||
VAR
|
||||
// analog output instance
|
||||
_fbAnalogOutput : FB_AnalogOutput('');
|
||||
|
||||
// analog output config
|
||||
_stAnalogOutputConfig : ST_ANALOG_IO_CONFIG;
|
||||
|
||||
// analog output hmi data
|
||||
_stHMIInterface : ST_HMI_ANALOG_VALUE;
|
||||
|
||||
// conversion result
|
||||
_iAnalogOutput : INT;
|
||||
|
||||
// fb error
|
||||
_xError : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestConfigErrorNegativMaxMinusMin');
|
||||
|
||||
// denom = udiAIMax - udiAIMin
|
||||
// Test if no crash occurs when denom is smaller than zero
|
||||
_stAnalogOutputConfig.iAIMax := 4095;
|
||||
_stAnalogOutputConfig.iAIMin := 0;
|
||||
_stAnalogOutputConfig.rPVMax := 0;
|
||||
_stAnalogOutputConfig.rPVMin := 1;
|
||||
|
||||
|
||||
// run analog scaling
|
||||
_fbAnalogOutput(
|
||||
rSetpoint := 100,
|
||||
stAnalogIOConfig := _stAnalogOutputConfig,
|
||||
xReleaseErrors := ,
|
||||
xConfirmAlarms := ,
|
||||
stHMIInterface := _stHMIInterface,
|
||||
iAnalogValue => _iAnalogOutput,
|
||||
xError => _xError,
|
||||
xInUnitTestMode := TRUE);
|
||||
|
||||
// evaluate Error and result to zero
|
||||
AssertTrue(_xError, 'There should be an error when trying to divide by zero.');
|
||||
AssertEquals_INT(Expected := 0, Actual := _iAnalogOutput, 'Output is expected to be zero when trying to divide by negative number.');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestHMIOutput" Id="{6b0d589b-625b-471a-8f08-48db4bd05305}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestHMIOutput
|
||||
VAR
|
||||
// analog output instance
|
||||
_fbAnalogOutput : FB_AnalogOutput('Name');
|
||||
|
||||
// analog output config
|
||||
_stAnalogOutputConfig : ST_ANALOG_IO_CONFIG;
|
||||
|
||||
// analog output hmi data
|
||||
_stHMIInterface : ST_HMI_ANALOG_VALUE;
|
||||
|
||||
// conversion result
|
||||
_iAnalogOutput : INT;
|
||||
|
||||
// fb error
|
||||
_xError : BOOL;
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
// expected hmi values
|
||||
sName : STRING := 'Name';
|
||||
sUnit : STRING := 'm/s';
|
||||
iOk : INT := 1;
|
||||
iError : INT := 2;
|
||||
|
||||
// delta for assertion
|
||||
rDelta : REAL := 0.01;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestHMIOutput');
|
||||
|
||||
// some example settings
|
||||
_stAnalogOutputConfig.iAIMax := 4095; //12 bit max
|
||||
_stAnalogOutputConfig.iAIMin := 0;
|
||||
_stAnalogOutputConfig.rPVMax := 100;
|
||||
_stAnalogOutputConfig.rPVMin := 50;
|
||||
_stAnalogOutputConfig.sUnit := sUnit;
|
||||
|
||||
// run analog scaling
|
||||
_fbAnalogOutput(
|
||||
rSetpoint := 60, //60 * 81,9 - 4095 = 819
|
||||
stAnalogIOConfig := _stAnalogOutputConfig,
|
||||
xReleaseErrors := ,
|
||||
xConfirmAlarms := ,
|
||||
stHMIInterface := _stHMIInterface,
|
||||
iAnalogValue => _iAnalogOutput,
|
||||
xError => _xError,
|
||||
xInUnitTestMode := TRUE);
|
||||
|
||||
// due to only moving real, a delta of 0.01 should be sufficient.
|
||||
// testing all HMI values
|
||||
AssertEquals_REAL(Expected := _stAnalogOutputConfig.rPVMax, Actual := _stHMIInterface.rMax, Delta := rDelta,'rMax was not passed to HMI correctly.');
|
||||
AssertEquals_REAL(Expected := _stAnalogOutputConfig.rPVMin, Actual := _stHMIInterface.rMin, Delta := rDelta,'rMin was not passed to HMI correctly.');
|
||||
// rValue from HMI Interface functions as an Input to the FB. If the FB would write it back we would have a loop!
|
||||
{analysis -140}
|
||||
//AssertEquals_REAL(Expected := rExpected, Actual := stHMIInterface.rValue, Delta := rDelta,'rValue was not passed to HMI correctly.');
|
||||
{analysis +140}
|
||||
AssertEquals_STRING(Expected := sName, Actual := _stHMIInterface.sName, 'sName was not passed to HMI correctly.');
|
||||
AssertEquals_STRING(Expected := sUnit, Actual := _stHMIInterface.sUnit, 'sUnit was not passed to HMI correctly.');
|
||||
AssertTrue(_stHMIInterface.xUsed, 'xUsed is not passed to HMI correctly.');
|
||||
AssertEquals_INT(Expected := iOk, Actual := _stHMIInterface.iStatus, 'Status is Error when OK was expected.');
|
||||
|
||||
// testing error passtrough (div by zero)
|
||||
_stAnalogOutputConfig.rPVMax := 0;
|
||||
_stAnalogOutputConfig.rPVMin := 0;
|
||||
|
||||
// run analog scaling
|
||||
_fbAnalogOutput(
|
||||
rSetpoint := 0,
|
||||
stAnalogIOConfig := _stAnalogOutputConfig,
|
||||
xReleaseErrors := ,
|
||||
xConfirmAlarms := ,
|
||||
stHMIInterface := _stHMIInterface,
|
||||
iAnalogValue => _iAnalogOutput,
|
||||
xError => _xError);
|
||||
|
||||
// reading error from HMI interface
|
||||
AssertEquals_INT(Expected := iError, Actual := _stHMIInterface.iStatus, 'Status is OK when Error was expected.');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestOutputScaling" Id="{60f43e92-2d83-42da-8c76-29a4e23f243d}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestOutputScaling
|
||||
VAR
|
||||
// analog output instance
|
||||
_fbAnalogOutput : FB_AnalogOutput('');
|
||||
|
||||
// analog output config
|
||||
_stAnalogOutputConfig : ST_ANALOG_IO_CONFIG;
|
||||
|
||||
// analog output hmi data
|
||||
_stHMIInterface : ST_HMI_ANALOG_VALUE;
|
||||
|
||||
// conversion result
|
||||
_iAnalogOutput : INT;
|
||||
|
||||
// fb error
|
||||
_xError : BOOL;
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
// expected conversion results
|
||||
iExpected1 : INT := 819;
|
||||
iExpected2 : INT := 3071;
|
||||
iExpected3 : INT := 354;
|
||||
iExpected4 : INT := 4013;
|
||||
iExpected5 : INT := 2058;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestOutputScaling');
|
||||
|
||||
// some example settings
|
||||
_stAnalogOutputConfig.iAIMax := 4095; //12 bit max
|
||||
_stAnalogOutputConfig.iAIMin := 0;
|
||||
_stAnalogOutputConfig.rPVMax := 100;
|
||||
_stAnalogOutputConfig.rPVMin := 50;
|
||||
|
||||
// run first value
|
||||
_fbAnalogOutput(
|
||||
rSetpoint := 60, //60 * 81,9 - 4095 = 819
|
||||
stAnalogIOConfig := _stAnalogOutputConfig,
|
||||
xReleaseErrors := ,
|
||||
xConfirmAlarms := ,
|
||||
stHMIInterface := _stHMIInterface,
|
||||
iAnalogValue => _iAnalogOutput,
|
||||
xError => _xError,
|
||||
xInUnitTestMode := TRUE);
|
||||
|
||||
// and evaluate result
|
||||
AssertFalse(_xError, 'There should not be an error here.');
|
||||
AssertEquals_INT(Expected := iExpected1, Actual := _iAnalogOutput,'Result was not calculated correctly.');
|
||||
|
||||
// run second value
|
||||
_fbAnalogOutput(
|
||||
rSetpoint := 87.5, //87,5 * 81,9 - 4095 = 3071
|
||||
stAnalogIOConfig := _stAnalogOutputConfig,
|
||||
xReleaseErrors := ,
|
||||
xConfirmAlarms := ,
|
||||
stHMIInterface := _stHMIInterface,
|
||||
iAnalogValue => _iAnalogOutput,
|
||||
xError => _xError);
|
||||
|
||||
// and evaluate result
|
||||
AssertFalse(_xError, 'There should not be an error here.');
|
||||
AssertEquals_INT(Expected := iExpected2, Actual := _iAnalogOutput,'Result was not calculated correctly.');
|
||||
|
||||
// run third value
|
||||
_fbAnalogOutput(
|
||||
rSetpoint := 54.321, //54,321 * 81,9 - 4095 = 354
|
||||
stAnalogIOConfig := _stAnalogOutputConfig,
|
||||
xReleaseErrors := ,
|
||||
xConfirmAlarms := ,
|
||||
stHMIInterface := _stHMIInterface,
|
||||
iAnalogValue => _iAnalogOutput,
|
||||
xError => _xError);
|
||||
|
||||
// and evaluate result
|
||||
AssertFalse(_xError, 'There should not be an error here.');
|
||||
AssertEquals_INT(Expected := iExpected3, Actual := _iAnalogOutput,'Result was not calculated correctly.');
|
||||
|
||||
// run forth value
|
||||
_fbAnalogOutput(
|
||||
rSetpoint := 99, //99 * 81,9 - 4095 = 4013
|
||||
stAnalogIOConfig := _stAnalogOutputConfig,
|
||||
xReleaseErrors := ,
|
||||
xConfirmAlarms := ,
|
||||
stHMIInterface := _stHMIInterface,
|
||||
iAnalogValue => _iAnalogOutput,
|
||||
xError => _xError);
|
||||
|
||||
// and evaluate result
|
||||
AssertFalse(_xError, 'There should not be an error here.');
|
||||
AssertEquals_INT(Expected := iExpected4, Actual := _iAnalogOutput,'Result was not calculated correctly.');
|
||||
|
||||
// run fifth value
|
||||
_fbAnalogOutput(
|
||||
rSetpoint := 75.12345, // 75,12345 * 81,9 - 4095 = 2058
|
||||
stAnalogIOConfig := _stAnalogOutputConfig,
|
||||
xReleaseErrors := ,
|
||||
xConfirmAlarms := ,
|
||||
stHMIInterface := _stHMIInterface,
|
||||
iAnalogValue => _iAnalogOutput,
|
||||
xError => _xError);
|
||||
|
||||
// and evaluate result
|
||||
AssertFalse(_xError, 'There should not be an error here.');
|
||||
AssertEquals_INT(Expected := iExpected5, Actual := _iAnalogOutput,'Result was not calculated correctly.');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestSetpointLowerCap" Id="{807912d5-bba1-425b-bbaa-8753f0659a61}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestSetpointLowerCap
|
||||
VAR
|
||||
// analog output instance
|
||||
_fbAnalogOutput : FB_AnalogOutput('');
|
||||
|
||||
// analog output config
|
||||
_stAnalogOutputConfig : ST_ANALOG_IO_CONFIG;
|
||||
|
||||
// analog output hmi data
|
||||
_stHMIInterface : ST_HMI_ANALOG_VALUE;
|
||||
|
||||
// conversion result
|
||||
_iAnalogOutput : INT;
|
||||
|
||||
// fb error
|
||||
_xError : BOOL;
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
// expected lower cap result
|
||||
iExpected : INT := 0;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestSetpointLowerCap');
|
||||
|
||||
// some example settings
|
||||
_stAnalogOutputConfig.iAIMax := 4095; //12 bit max
|
||||
_stAnalogOutputConfig.iAIMin := 0;
|
||||
_stAnalogOutputConfig.rPVMax := 100;
|
||||
_stAnalogOutputConfig.rPVMin := 50;
|
||||
|
||||
// run with setpoint lower than lower cap
|
||||
_fbAnalogOutput(
|
||||
rSetpoint := 30,
|
||||
stAnalogIOConfig := _stAnalogOutputConfig,
|
||||
xReleaseErrors := ,
|
||||
xConfirmAlarms := ,
|
||||
stHMIInterface := _stHMIInterface,
|
||||
iAnalogValue => _iAnalogOutput,
|
||||
xError => _xError,
|
||||
xInUnitTestMode := TRUE);
|
||||
|
||||
// evaluate wethere the result is the equivalent of lower cap or not
|
||||
AssertFalse(_xError, 'There should not be an error here.');
|
||||
AssertEquals_INT(Expected := iExpected, Actual := _iAnalogOutput,'Setpoint was expected to be capped.');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestSetpointUpperCap" Id="{286c1c76-f998-4c94-9225-155b9dc5d782}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestSetpointUpperCap
|
||||
VAR
|
||||
// analog output instance
|
||||
_fbAnalogOutput : FB_AnalogOutput('');
|
||||
|
||||
// analog output config
|
||||
_stAnalogOutputConfig : ST_ANALOG_IO_CONFIG;
|
||||
|
||||
// analog output hmi data
|
||||
_stHMIInterface : ST_HMI_ANALOG_VALUE;
|
||||
|
||||
// conversion result
|
||||
_iAnalogOutput : INT;
|
||||
|
||||
// fb error
|
||||
_xError : BOOL;
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
// expected upper cap result
|
||||
iExpected : INT := 4095;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestSetpointUpperCap');
|
||||
|
||||
// some example settings
|
||||
_stAnalogOutputConfig.iAIMax := 4095; //12 bit max
|
||||
_stAnalogOutputConfig.iAIMin := 0;
|
||||
_stAnalogOutputConfig.rPVMax := 100;
|
||||
_stAnalogOutputConfig.rPVMin := 50;
|
||||
|
||||
// run with setpoint higher than upper cap
|
||||
_fbAnalogOutput(
|
||||
rSetpoint := 110,
|
||||
stAnalogIOConfig := _stAnalogOutputConfig,
|
||||
xReleaseErrors := ,
|
||||
xConfirmAlarms := ,
|
||||
stHMIInterface := _stHMIInterface,
|
||||
iAnalogValue => _iAnalogOutput,
|
||||
xError => _xError,
|
||||
xInUnitTestMode := TRUE);
|
||||
|
||||
// evaluate wethere the result is the equivalent of upper cap or not
|
||||
AssertFalse(_xError, 'There should not be an error here.');
|
||||
AssertEquals_INT(Expected := iExpected, Actual := _iAnalogOutput,'Setpoint was expected to be capped.');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestUnused" Id="{5c9c0209-9c4b-4d43-90e6-a77c731cebf3}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestUnused
|
||||
VAR
|
||||
// analog output instance
|
||||
_fbAnalogOutput : FB_AnalogOutput('');
|
||||
|
||||
// analog output config
|
||||
_stAnalogOutputConfig : ST_ANALOG_IO_CONFIG;
|
||||
|
||||
// analog output hmi data
|
||||
_stHMIInterface : ST_HMI_ANALOG_VALUE;
|
||||
|
||||
// conversion result
|
||||
_iAnalogOutput : INT;
|
||||
|
||||
// fb error
|
||||
_xError : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestUnused');
|
||||
|
||||
// some example settings
|
||||
_stAnalogOutputConfig.xUsed := FALSE;
|
||||
|
||||
// run analog output
|
||||
_fbAnalogOutput(
|
||||
rSetpoint := 100,
|
||||
stAnalogIOConfig := _stAnalogOutputConfig,
|
||||
xReleaseErrors := ,
|
||||
xConfirmAlarms := ,
|
||||
stHMIInterface := _stHMIInterface,
|
||||
iAnalogValue => _iAnalogOutput,
|
||||
xError => _xError,
|
||||
xInUnitTestMode := TRUE);
|
||||
|
||||
// test for error and output (should not be present and 0 when unused)
|
||||
AssertFalse(_xError, 'There should not be an error when unused.');
|
||||
AssertEquals_INT(Expected := 0, Actual := _iAnalogOutput, 'Output is expected to be zero when unused');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
547
PLC/POUs/Unittests/AnalogValveTests/FB_ValveAnalog_Test.TcPOU
Normal file
547
PLC/POUs/Unittests/AnalogValveTests/FB_ValveAnalog_Test.TcPOU
Normal file
@@ -0,0 +1,547 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<POU Name="FB_ValveAnalog_Test" Id="{9dc8ec77-f523-463e-8c0f-b11bbdcadb17}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_ValveAnalog_Test EXTENDS TcUnit.FB_TestSuite
|
||||
VAR
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Automatic Mode
|
||||
SwitchToAutomaticMode();
|
||||
|
||||
// Manual Mode
|
||||
SwitchToManualMode();
|
||||
|
||||
// Test interlocks
|
||||
TestProcessInterlocks();
|
||||
TestProcessINTLKsInAutomaticMode();
|
||||
TestProcessINTLKsInManualMode();
|
||||
|
||||
// Check feedback signals
|
||||
CheckOpenCloseFeedbacks();
|
||||
|
||||
// Test Open/Close Valves
|
||||
OpenCloseValveInAutomaticMode();
|
||||
OpenCloseValveInManualMode();
|
||||
|
||||
// check range errors
|
||||
CheckNotInRangeError();
|
||||
CheckOverrange();
|
||||
CheckUnderrange();]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="CheckNotInRangeError" Id="{f10fdc9b-52ba-49cf-9c89-aee87b8a1ee1}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD CheckNotInRangeError
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_ValveAnalog('');
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveAnalogConfig;
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_ANALOG_VALVE_DATA;
|
||||
|
||||
// valve error output
|
||||
_xError : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('CheckNotInRangeError');
|
||||
|
||||
// config valve to
|
||||
_stValveConfig.xHasAnalogFeedback := TRUE;
|
||||
_stValveConfig.rTargetTolerance := 5;
|
||||
_stValveConfig.timNotInRange := T#0S;
|
||||
_stValveConfig.stAnalogInputConfig.iAIMax :=4095;
|
||||
_stValveConfig.stAnalogInputConfig.iAIMin :=0;
|
||||
_stValveConfig.stAnalogInputConfig.rPVMax :=100;
|
||||
_stValveConfig.stAnalogInputConfig.rPVMin :=0;
|
||||
|
||||
// Set in automatic mode and open valve
|
||||
_fbValve.ReqAutomaticMode();
|
||||
_fbValve.rSPAutomatic := 100;
|
||||
|
||||
// needs one cycle to write values (scaled feedback ~75, tolerance 95 to 105)
|
||||
_fbValve(xAutomaticOpen := TRUE, stValveConfig := _stValveConfig, stHMIInterface := _stHMIValve, iFeedbackValue := 3000, xError => _xError, xInUnitTestMode := TRUE);
|
||||
|
||||
// assert result
|
||||
AssertTrue(_xError, 'Expected NotInRangeError, got no error.');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="CheckOpenCloseFeedbacks" Id="{ce54a6cd-7831-4ab3-aa0c-464e9a0018d6}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD CheckOpenCloseFeedbacks
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_ValveAnalog('');
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveAnalogConfig;
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_ANALOG_VALVE_DATA;
|
||||
|
||||
// valve feedback
|
||||
_xOpenFeedback : BOOL := FALSE;
|
||||
_xCloseFeedback : BOOL := FALSE;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('CheckOpenCloseFeedbacks');
|
||||
|
||||
// set open+close feedback to present, analog feedback to false
|
||||
_stValveConfig.xHasAnalogFeedback := FALSE;
|
||||
_stValveConfig.xHasOpenFeedback := TRUE;
|
||||
_stValveConfig.xHasClosedFeedback := TRUE;
|
||||
|
||||
// Test feedbacks in manual mode
|
||||
_xOpenFeedback := FALSE;
|
||||
_xCloseFeedback := FALSE;
|
||||
_fbValve.xReleaseManualMode := TRUE;
|
||||
_fbValve.ReqManualMode();
|
||||
_fbValve(xOpenFeedback := _xOpenFeedback, xCloseFeedback := _xCloseFeedback, stHMIInterface := _stHMIValve, stValveConfig := _stValveConfig, xInUnitTestMode := TRUE);
|
||||
|
||||
|
||||
// We should now be in manual mode
|
||||
AssertTrue(Condition := _fbValve.IsInManualMode, Message := 'Valve did not changed to manual mode');
|
||||
|
||||
|
||||
// Test closed
|
||||
_xOpenFeedback := FALSE;
|
||||
_xCloseFeedback := TRUE;
|
||||
_fbValve(xOpenFeedback := _xOpenFeedback, xCloseFeedback := _xCloseFeedback, stHMIInterface := _stHMIValve, stValveConfig := _stValveConfig, xInUnitTestMode := TRUE);
|
||||
AssertTrue(Condition := _fbValve.IsClosed, Message := 'Valve should be closed');
|
||||
AssertFalse(Condition := _fbValve.IsOpen, Message := 'Valve should not be open');
|
||||
|
||||
// Test opened
|
||||
_xOpenFeedback := TRUE;
|
||||
_xCloseFeedback := FALSE;
|
||||
_stHMIValve.stSetpoint.rValue := 100.0;
|
||||
_fbValve(xOpenFeedback := _xOpenFeedback, xCloseFeedback := _xCloseFeedback, stHMIInterface := _stHMIValve, stValveConfig := _stValveConfig, xInUnitTestMode := TRUE);
|
||||
AssertTrue(Condition := _fbValve.IsOpen, Message := 'Valve should be open');
|
||||
AssertFalse(Condition := _fbValve.IsClosed, Message := 'Valve should not be closed');
|
||||
|
||||
// Test open and close
|
||||
_xOpenFeedback := TRUE;
|
||||
_xCloseFeedback := TRUE;
|
||||
_fbValve(xOpenFeedback := _xOpenFeedback, xCloseFeedback := _xCloseFeedback, stHMIInterface := _stHMIValve, stValveConfig := _stValveConfig, xInUnitTestMode := TRUE);
|
||||
AssertFalse(Condition := _fbValve.IsClosed OR _fbValve.IsOpen, Message := 'Valve should not signal open or closed with both feedback signals high');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="CheckOverrange" Id="{6a8f595e-e480-42ad-a991-d9700b5e80d0}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD CheckOverrange
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_ValveAnalog('');
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveAnalogConfig;
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_ANALOG_VALVE_DATA;
|
||||
|
||||
// valve error output
|
||||
_xError : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('CheckOverrange');
|
||||
|
||||
// set delay to zero to make single cycle test possible (AnalogInput is tested individually)
|
||||
_stValveConfig.stAnalogInputEWConfig.stDelays.timHardwareSignalLevelOn := T#0S;
|
||||
_stValveConfig.xHasAnalogFeedback := TRUE;
|
||||
|
||||
// needs one cycle to write values, xOverrange must be connected.
|
||||
_fbValve(
|
||||
stValveConfig := _stValveConfig,
|
||||
stHMIInterface := _stHMIValve,
|
||||
xFeedbackOverrange := TRUE,
|
||||
xError => _xError,
|
||||
xInUnitTestMode := TRUE);
|
||||
|
||||
// assert result
|
||||
AssertTrue(_xError, 'Expected Overrange error, got no error.');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="CheckUnderrange" Id="{4d7e06e3-a833-4b91-a285-8e2fb59100bd}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD CheckUnderrange
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_ValveAnalog('');
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveAnalogConfig;
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_ANALOG_VALVE_DATA;
|
||||
|
||||
// valve error output
|
||||
_xError : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('CheckUnderrange');
|
||||
|
||||
// set delay to zero to make single cycle test possible (AnalogInput is tested individually)
|
||||
_stValveConfig.stAnalogInputEWConfig.stDelays.timHardwareSignalLevelOn := T#0S;
|
||||
_stValveConfig.xHasAnalogFeedback := TRUE;
|
||||
|
||||
// needs one cycle to write values, xUnderrange must be connected.
|
||||
_fbValve(
|
||||
stValveConfig := _stValveConfig,
|
||||
stHMIInterface := _stHMIValve,
|
||||
xFeedbackUnderrange := TRUE,
|
||||
xError => _xError,
|
||||
xInUnitTestMode := TRUE);
|
||||
|
||||
// assert result
|
||||
AssertTrue(_xError, 'Expected Underrange error, got no error.');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="OpenCloseValveInAutomaticMode" Id="{fc3da46f-724a-400a-ab82-86cb17e3d842}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD OpenCloseValveInAutomaticMode
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_ValveAnalog('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_ANALOG_VALVE_DATA;
|
||||
|
||||
// valve state
|
||||
_xResult : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('OpenCloseValveInAutomaticMode');
|
||||
|
||||
// Set in automatic mode
|
||||
_fbValve.ReqAutomaticMode();
|
||||
|
||||
// Open valve
|
||||
_fbValve.rSPAutomatic := 100;
|
||||
|
||||
// Needs one cycle to write outputs
|
||||
_fbValve(xAutomaticOpen := TRUE, stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
|
||||
// evaluate valve state
|
||||
_xResult := _fbValve.IsOpen AND NOT _fbValve.IsClosed;
|
||||
AssertTrue(_xResult, 'Valve did not open in Automatic Mode');
|
||||
|
||||
// Close valve
|
||||
_fbValve.rSPAutomatic := 0;
|
||||
|
||||
// Needs one cycle to write outputs
|
||||
_fbValve(xAutomaticOpen := FALSE, stHMIInterface := _stHMIValve);
|
||||
|
||||
// evaluate valve state
|
||||
_xResult := _fbValve.IsClosed AND NOT _fbValve.IsOpen;
|
||||
AssertTrue(_xResult, 'Valve did not close in Automatic Mode');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="OpenCloseValveInManualMode" Id="{1349619a-f843-4cf9-9143-1a752f089a58}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD OpenCloseValveInManualMode
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_ValveAnalog('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_ANALOG_VALVE_DATA;
|
||||
|
||||
// valve state
|
||||
_xResult : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('OpenCloseValveInManualMode');
|
||||
|
||||
// release manual mode
|
||||
_fbValve.xReleaseManualMode := TRUE;
|
||||
|
||||
// Set in manual mode
|
||||
_fbValve.ReqManualMode();
|
||||
|
||||
// Open valve and call block
|
||||
_stHMIValve.stSetpoint.rValue := 100;
|
||||
_stHMIValve.stOpenButton.xRequest := TRUE;
|
||||
_fbValve(stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
|
||||
// evaluate valve state
|
||||
_xResult := _fbValve.IsOpen AND NOT _fbValve.IsClosed;
|
||||
AssertTrue(_xResult, 'Valve did not open in Manual Mode');
|
||||
|
||||
// Close valve and call block
|
||||
_stHMIValve.stCloseButton.xRequest := TRUE;
|
||||
_fbValve(stHMIInterface := _stHMIValve);
|
||||
|
||||
// evaluate valve state
|
||||
_xResult := _fbValve.IsClosed AND NOT _fbValve.IsOpen;
|
||||
AssertTrue(_xResult, 'Valve did not close in Manual Mode');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="SwitchToAutomaticMode" Id="{7c51a185-7dd4-4b8d-9873-f1eaa22c97e6}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD SwitchToAutomaticMode
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_ValveAnalog('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_ANALOG_VALVE_DATA;
|
||||
|
||||
// valve state
|
||||
_xResult : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('SwitchToAutomaticMode');
|
||||
|
||||
// request switch to automatic mode
|
||||
_fbValve.ReqAutomaticMode();
|
||||
|
||||
// call valve block
|
||||
_fbValve(stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
|
||||
// assert valve mode
|
||||
_xResult := _fbValve.IsInAutomaticMode;
|
||||
AssertTrue(_xResult, 'Valve did not change into Automatic Mode');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="SwitchToManualMode" Id="{84f7ce91-9e5d-4bc0-8681-d7a35657e9a9}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD SwitchToManualMode
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_ValveAnalog('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_ANALOG_VALVE_DATA;
|
||||
|
||||
// valve state
|
||||
_xResult : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('SwitchToManualMode');
|
||||
|
||||
// Test switch without xReleaseManualMode
|
||||
_fbValve.xReleaseManualMode := FALSE;
|
||||
_fbValve.ReqManualMode();
|
||||
_fbValve(stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
_xResult := NOT _fbValve.IsInManualMode;
|
||||
AssertTrue(_xResult, 'Valve changed to Manual Mode but this mode was not released');
|
||||
|
||||
// Test with xReleaseManualMode
|
||||
_fbValve.xReleaseManualMode := TRUE;
|
||||
_fbValve.ReqManualMode();
|
||||
_fbValve(stHMIInterface := _stHMIValve);
|
||||
_xResult := _fbValve.IsInManualMode;
|
||||
AssertTrue(_xResult, 'Valve did not changed to Manual Mode');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestProcessInterlocks" Id="{2152677d-8778-48f4-98dc-366509ac6287}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
{attribute 'analysis' := '-81'}
|
||||
METHOD TestProcessInterlocks
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_ValveAnalog('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_ANALOG_VALVE_DATA;
|
||||
|
||||
// valve state
|
||||
_xResult : BOOL;
|
||||
|
||||
// current interlock
|
||||
_usiCounter : USINT;
|
||||
|
||||
// Init all entries to TRUE
|
||||
_wInterlocks : T_INTERLOCK := 2#1111_1111_1111_1111;//[GVL_VALVE.MAX_INTERLOCKS(TRUE)];
|
||||
_wInterlocksUsed : T_INTERLOCK := 2#1111_1111_1111_1111;
|
||||
|
||||
// induvidual interlock test result
|
||||
_axInterlockTestResultFalse : ARRAY[0..GVL_CONFIGS.MAX_INTERLOCKS-1] OF BOOL;
|
||||
_axInterlockTestResultTrue : ARRAY[0..GVL_CONFIGS.MAX_INTERLOCKS-1] OF BOOL;
|
||||
|
||||
// comulated interlock test result
|
||||
_xInterlocksFalseOK : BOOL;
|
||||
_xInterlocksTrueOK : BOOL;
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
// loop iterations for interlock test
|
||||
usiEndValue : USINT := GVL_CONFIGS.MAX_INTERLOCKS-1;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Test interlocks as reutrn value
|
||||
TEST('TestProcessInterlocks');
|
||||
|
||||
// call valve block and evaluate interlocks
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
_xResult := _fbValve.ProcessInterlocksOK;
|
||||
|
||||
AssertTrue(_xResult, 'Interlocks not Ok but should be');
|
||||
|
||||
// Test each interlock individually
|
||||
// Save the result in the two following variables
|
||||
_xInterlocksFalseOK := TRUE;
|
||||
_xInterlocksTrueOK := TRUE;
|
||||
|
||||
FOR _usiCounter := 0 TO usiEndValue DO
|
||||
|
||||
// Test one interlock for false and then disable it
|
||||
_wInterlocks := SHL(_wInterlocks, 1);
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Save result in an array for later debugging if necessary
|
||||
_axInterlockTestResultFalse[_usiCounter] := _fbValve.ProcessInterlocksOK;
|
||||
|
||||
// Save global result
|
||||
IF _fbValve.ProcessInterlocksOK THEN
|
||||
_xInterlocksFalseOK := FALSE;
|
||||
END_IF
|
||||
// Disable this interlock after testing it
|
||||
_wInterlocksUsed := SHL(_wInterlocksUsed, 1);
|
||||
|
||||
// Test if, after disabling the interlock, the interlocks are ok again
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Save result in an array for later debugging if necessary
|
||||
_axInterlockTestResultTrue[_usiCounter] := _fbValve.ProcessInterlocksOK;
|
||||
|
||||
// Save global result
|
||||
IF NOT _fbValve.ProcessInterlocksOK THEN
|
||||
_xInterlocksTrueOK := FALSE;
|
||||
END_IF
|
||||
END_FOR
|
||||
|
||||
// Test False interlocks result
|
||||
AssertTrue(_xInterlocksFalseOK, 'Interlock should not be ok but are');
|
||||
|
||||
// Test False interlocks result
|
||||
AssertTrue(_xInterlocksTrueOK, 'Interlock should be ok but are not');
|
||||
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestProcessINTLKsInAutomaticMode" Id="{468a3341-78b1-4d81-96e1-32c340664094}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestProcessINTLKsInAutomaticMode
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_ValveAnalog('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_ANALOG_VALVE_DATA;
|
||||
|
||||
// valve analog config
|
||||
_stAnalogValveConfig : ST_ValveAnalogConfig;
|
||||
|
||||
// valve interlocks
|
||||
_wInterlocks : T_INTERLOCK;
|
||||
_wInterlocksUsed : T_INTERLOCK;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestProcessINTLKsInAutomaticMode');
|
||||
_wInterlocks.0 := 1;
|
||||
_wInterlocksUsed.0 := 1;
|
||||
|
||||
// Switch to automatic mode
|
||||
_fbValve.ReqAutomaticMode();
|
||||
_fbValve(wProcessINTLK := _wInterlocks, stValveConfig := _stAnalogValveConfig, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
|
||||
// Open valve in automatic mode
|
||||
_fbValve.rSPAutomatic := 100;
|
||||
_fbValve(xAutomaticOpen := TRUE, wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Test if valve is open, when not we have an intermediate error
|
||||
// which should have been found by another test
|
||||
IF _fbValve.IsOpen THEN
|
||||
// Activate an interlock
|
||||
_wInterlocks.0 := 0;
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Valve should now be closed
|
||||
AssertFalse(Condition := _fbValve.IsOpen, Message := 'Valve should not be open with active Interlock');
|
||||
AssertTrue(Condition := _fbValve.IsClosed, Message := 'Close output not active with active Interlock');
|
||||
AssertEquals_INT(Expected := 0, Actual := _fbValve.iSetpoint, Message := 'Analog output should be zero');
|
||||
ELSE
|
||||
AssertTrue(Condition := _fbValve.IsOpen, Message := 'Valve did not open before the test');
|
||||
END_IF
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestProcessINTLKsInManualMode" Id="{65a15a58-c0c0-4568-a4e1-3f436c3d6baa}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestProcessINTLKsInManualMode
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_ValveAnalog('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_ANALOG_VALVE_DATA;;
|
||||
|
||||
// valve interlocks
|
||||
_wInterlocks : T_INTERLOCK;
|
||||
_wInterlocksUsed : T_INTERLOCK;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestProcessINTLKsInManualMode');
|
||||
_wInterlocks.0 := 1;
|
||||
_wInterlocksUsed.0 := 1;
|
||||
|
||||
// Switch to manual mode
|
||||
_fbValve.xReleaseManualMode := TRUE;
|
||||
_fbValve.ReqManualMode();
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
|
||||
// Open valve in manual mode
|
||||
_stHMIValve.stSetpoint.rValue := 100.0;
|
||||
_stHMIValve.stOpenButton.xRequest := TRUE;
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Test if valve is open, when not we have an intermediate error
|
||||
// which should have been found by another test
|
||||
IF _fbValve.IsOpen THEN
|
||||
// Activate an interlock
|
||||
_wInterlocks.0 := 0;
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Valve should now be closed
|
||||
AssertFalse(Condition := _fbValve.IsOpen, Message := 'Valve should not be open with active Interlock');
|
||||
AssertTrue(Condition := _fbValve.IsClosed, Message := 'Close output not active with active Interlock');
|
||||
AssertEquals_INT(Expected := 0, Actual := _fbValve.iSetpoint, Message := 'Analog output should be zero');
|
||||
ELSE
|
||||
AssertTrue(Condition := _fbValve.IsOpen, Message := 'Valve did not open before the test');
|
||||
END_IF
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
188
PLC/POUs/Unittests/ReleaseSignalTests/FB_ReleaseSignalTest.TcPOU
Normal file
188
PLC/POUs/Unittests/ReleaseSignalTests/FB_ReleaseSignalTest.TcPOU
Normal file
@@ -0,0 +1,188 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<POU Name="FB_ReleaseSignalTest" Id="{8b18b04a-432b-48e8-9173-e18ffc6e0a72}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_ReleaseSignalTest EXTENDS TcUnit.FB_TestSuite
|
||||
VAR
|
||||
// variables for onTimeTest
|
||||
_fbReleaseSignalWithOnTime : FB_ReleaseSignal;
|
||||
_fbOnTimer : TON;
|
||||
_xTestWithOnTimeFinished : BOOL := FALSE;
|
||||
|
||||
// variables for offTimeTest
|
||||
_fbReleaseSignalWithOffTime : FB_ReleaseSignal;
|
||||
_fbOffTimer : TON;
|
||||
_xTestWithOffTimeFinished : BOOL := FALSE;
|
||||
_xSignalForOffTest : BOOL := TRUE;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// run tests with different time behaviour
|
||||
TestWithoutTime();
|
||||
TestWithOnTime();
|
||||
TestWithOffTime();]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="TestWithOffTime" Id="{59bccf19-8c18-4516-9bfc-d8ecab97a196}">
|
||||
<Declaration><![CDATA[METHOD TestWithOffTime
|
||||
VAR
|
||||
// result
|
||||
_xReturnValue : BOOL;
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
// off timing
|
||||
timOffTime : TIME := T#100MS;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestWithOffTime');
|
||||
|
||||
// Test off time delay
|
||||
_fbReleaseSignalWithOffTime(
|
||||
xSignal:= _xSignalForOffTest,
|
||||
xRelease:= TRUE,
|
||||
timOnDelay:= T#0MS,
|
||||
timOffDelay:= timOffTime,
|
||||
xReleaseSignal=> _xReturnValue);
|
||||
|
||||
// Start timer after which the output of the Signal fb will be checked
|
||||
_fbOffTimer(IN := TRUE, PT := (timOffTime + T#50MS));
|
||||
|
||||
IF _xSignalForOffTest THEN
|
||||
_xSignalForOffTest := FALSE;
|
||||
END_IF
|
||||
|
||||
// Signal must be true at the start of the test
|
||||
// If not, abort the test
|
||||
IF _xSignalForOffTest AND (NOT _xReturnValue) THEN
|
||||
AssertTrue(Condition := _xReturnValue, Message := 'Signal not true at start of test');
|
||||
_xTestWithOffTimeFinished := TRUE;
|
||||
END_IF
|
||||
|
||||
// Check value after a time which is longer than the signal delay time
|
||||
IF NOT _fbOffTimer.Q THEN
|
||||
IF (NOT _xReturnValue) THEN
|
||||
AssertFalse(Condition := _xReturnValue, Message := 'Signal was false before the time was over');
|
||||
_fbOnTimer.IN := FALSE;
|
||||
_xTestWithOffTimeFinished := TRUE;
|
||||
END_IF
|
||||
ELSE
|
||||
AssertFalse(Condition := _xReturnValue, Message := 'Signal was not false after the time elapsed');
|
||||
_fbOnTimer.IN := FALSE;
|
||||
_xTestWithOffTimeFinished := TRUE;
|
||||
END_IF
|
||||
|
||||
IF _xTestWithOffTimeFinished THEN
|
||||
TEST_FINISHED();
|
||||
END_IF]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestWithOnTime" Id="{adc27bca-ad94-40db-8c4a-cead392adedc}">
|
||||
<Declaration><![CDATA[METHOD TestWithOnTime
|
||||
VAR
|
||||
// result
|
||||
_xReturnValue : BOOL;
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
// on timing
|
||||
timOnTime : TIME := T#100MS;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestWithOnTime');
|
||||
|
||||
// Test on time delay
|
||||
_fbReleaseSignalWithOnTime(
|
||||
xSignal:= TRUE,
|
||||
xRelease:= TRUE,
|
||||
timOnDelay:= timOnTime,
|
||||
timOffDelay:= T#0MS,
|
||||
xReleaseSignal=> _xReturnValue);
|
||||
|
||||
// Start timer after which the output of the Signal fb will be checked
|
||||
_fbOnTimer(IN := TRUE, PT := (timOnTime + T#50MS));
|
||||
|
||||
// Check value after a time which is longer than the signal delay time
|
||||
IF NOT _fbOnTimer.Q THEN
|
||||
IF _xReturnValue THEN
|
||||
AssertTrue(Condition := _xReturnValue, Message := 'Signal was true before the time was over');
|
||||
_fbOnTimer.IN := FALSE;
|
||||
_xTestWithOnTimeFinished := TRUE;
|
||||
END_IF
|
||||
ELSE
|
||||
AssertTrue(Condition := _xReturnValue, Message := 'Signal was not true after the time elapsed');
|
||||
_fbOnTimer.IN := FALSE;
|
||||
_xTestWithOnTimeFinished := TRUE;
|
||||
END_IF
|
||||
|
||||
IF _xTestWithOnTimeFinished THEN
|
||||
TEST_FINISHED();
|
||||
END_IF]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestWithoutTime" Id="{394513b0-dc3f-4f97-9cfc-0254521f5ce3}">
|
||||
<Declaration><![CDATA[METHOD TestWithoutTime
|
||||
VAR
|
||||
// reslease signal instance
|
||||
_fbReleaseSignal : FB_ReleaseSignal;
|
||||
|
||||
// input signal
|
||||
_xSignal : BOOL;
|
||||
|
||||
// expected result
|
||||
_xExpected : BOOL;
|
||||
|
||||
// release result
|
||||
_xReturnValue : BOOL;
|
||||
|
||||
// release signal
|
||||
_xRelease : BOOL := TRUE;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestWithoutTime');
|
||||
|
||||
// Test with active release
|
||||
_xRelease := TRUE;
|
||||
|
||||
// Test low signal
|
||||
_xSignal := FALSE;
|
||||
_xExpected := FALSE;
|
||||
_fbReleaseSignal(
|
||||
xSignal:= _xSignal,
|
||||
xRelease:= _xRelease,
|
||||
timOnDelay:= T#0MS,
|
||||
timOffDelay:= T#0MS,
|
||||
xReleaseSignal=> _xReturnValue);
|
||||
|
||||
AssertEquals(Expected:= _xExpected, Actual:= _xReturnValue, Message:= 'Signal is not false');
|
||||
|
||||
|
||||
// Test high signal
|
||||
_xSignal := TRUE;
|
||||
_xExpected := TRUE;
|
||||
_fbReleaseSignal(
|
||||
xSignal:= _xSignal,
|
||||
xRelease:= _xRelease,
|
||||
timOnDelay:= T#0MS,
|
||||
timOffDelay:= T#0MS,
|
||||
xReleaseSignal=> _xReturnValue);
|
||||
|
||||
AssertEquals(Expected:= _xExpected, Actual:= _xReturnValue, Message:= 'Signal is not true');
|
||||
|
||||
// Test with inactive release
|
||||
_xRelease := FALSE;
|
||||
_xSignal := TRUE;
|
||||
_xExpected := FALSE;
|
||||
_fbReleaseSignal(
|
||||
xSignal:= _xSignal,
|
||||
xRelease:= _xRelease,
|
||||
timOnDelay:= T#0MS,
|
||||
timOffDelay:= T#0MS,
|
||||
xReleaseSignal=> _xReturnValue);
|
||||
|
||||
AssertEquals(Expected:= _xExpected, Actual:= _xReturnValue, Message:= 'Signal is not false with no active release');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
301
PLC/POUs/Unittests/UtilitiesTests/FB_BlinkerTest.TcPOU
Normal file
301
PLC/POUs/Unittests/UtilitiesTests/FB_BlinkerTest.TcPOU
Normal 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>
|
||||
178
PLC/POUs/Unittests/UtilitiesTests/FB_HashFNV1a_32BitTest.TcPOU
Normal file
178
PLC/POUs/Unittests/UtilitiesTests/FB_HashFNV1a_32BitTest.TcPOU
Normal 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>
|
||||
276
PLC/POUs/Unittests/UtilitiesTests/FB_PT1Test.TcPOU
Normal file
276
PLC/POUs/Unittests/UtilitiesTests/FB_PT1Test.TcPOU
Normal 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>
|
||||
473
PLC/POUs/Unittests/UtilitiesTests/FB_RampGeneratorTest.TcPOU
Normal file
473
PLC/POUs/Unittests/UtilitiesTests/FB_RampGeneratorTest.TcPOU
Normal 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>
|
||||
282
PLC/POUs/Unittests/ValveTests/FB_ValveTestHMI.TcPOU
Normal file
282
PLC/POUs/Unittests/ValveTests/FB_ValveTestHMI.TcPOU
Normal file
@@ -0,0 +1,282 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<POU Name="FB_ValveTestHMI" Id="{78a34e73-74e3-480e-93ae-396774638baf}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_ValveTestHMI EXTENDS TcUnit.FB_TestSuite
|
||||
VAR_INPUT
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
END_VAR
|
||||
VAR
|
||||
// valve instance for Open/Close-Test
|
||||
_fbValveOC : FB_Valve('');
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TestManualButtonRelease();
|
||||
TestManualButtonModeChange();
|
||||
TestManualModeButtonOpenClose();
|
||||
TestManualModeOpenRelease();]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="TestManualButtonModeChange" Id="{4fa4418c-a1e9-4136-b912-1dfb82f3064a}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestManualButtonModeChange
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveConfig;
|
||||
|
||||
// valve interlocks
|
||||
_wInterlocks : T_INTERLOCK;
|
||||
_wInterlocksUsed : T_INTERLOCK;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestManualButtonModeChange');
|
||||
|
||||
// set manual request button on HMI and call valve block
|
||||
_stHMIValve.stManualButton.xRequest := TRUE;
|
||||
_fbValve(
|
||||
xReleaseManualMode:= TRUE,
|
||||
wProcessINTLK:= _wInterlocks,
|
||||
wProcessINTLKUsed:= _wInterlocksUsed,
|
||||
stHMIInterface:= _stHMIValve,
|
||||
xError=> ,
|
||||
xOpenFeedback:= ,
|
||||
xCloseFeedback:= ,
|
||||
xReleaseErrors:= ,
|
||||
xConfirmAlarms:= ,
|
||||
stValveConfig:= _stValveConfig,
|
||||
xOpenValve=> ,
|
||||
xCloseValve=> );
|
||||
|
||||
// Valve should now be in manual mode and xRequest should have been reset
|
||||
AssertTrue(Condition := _fbValve.IsInManualMode, Message := 'Valve did not change to manual mode');
|
||||
AssertFalse(Condition := _stHMIValve.stManualButton.xRequest, Message := 'Valve did not reset the manual mode button request');
|
||||
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestManualButtonRelease" Id="{6966094d-e9b6-4f8b-a399-9dea4a3eee19}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestManualButtonRelease
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveConfig;
|
||||
|
||||
// valve interlocks
|
||||
_wInterlocks : T_INTERLOCK;
|
||||
_wInterlocksUsed : T_INTERLOCK;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestManualButtonRelease');
|
||||
|
||||
// Test no release for HMI mode change
|
||||
_fbValve(
|
||||
xReleaseManualMode:= FALSE,
|
||||
wProcessINTLK:= _wInterlocks,
|
||||
wProcessINTLKUsed:= _wInterlocksUsed,
|
||||
stHMIInterface:= _stHMIValve,
|
||||
xError=> ,
|
||||
xOpenFeedback:= ,
|
||||
xCloseFeedback:= ,
|
||||
xReleaseErrors:= ,
|
||||
xConfirmAlarms:= ,
|
||||
stValveConfig:= _stValveConfig,
|
||||
xOpenValve=> ,
|
||||
xCloseValve=> );
|
||||
|
||||
AssertFalse(Condition := _stHMIValve.stManualButton.xRelease, Message := 'Manual mode button was released but should not have been');
|
||||
|
||||
|
||||
// Test release for HMI mode change
|
||||
_fbValve(
|
||||
xReleaseManualMode:= TRUE,
|
||||
wProcessINTLK:= _wInterlocks,
|
||||
wProcessINTLKUsed:= _wInterlocksUsed,
|
||||
stHMIInterface:= _stHMIValve,
|
||||
xError=> ,
|
||||
xOpenFeedback:= ,
|
||||
xCloseFeedback:= ,
|
||||
xReleaseErrors:= ,
|
||||
xConfirmAlarms:= ,
|
||||
stValveConfig:= ,
|
||||
xOpenValve=> ,
|
||||
xCloseValve=> );
|
||||
|
||||
AssertTrue(Condition := _stHMIValve.stManualButton.xRelease, Message := 'Manual mode button was not released but should have been');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestManualModeButtonOpenClose" Id="{5447550c-d5f0-42c9-bcfd-b2ef662685c8}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestManualModeButtonOpenClose
|
||||
VAR
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveConfig;
|
||||
|
||||
// valve interlocks
|
||||
_wInterlocks : T_INTERLOCK;
|
||||
_wInterlocksUsed : T_INTERLOCK;
|
||||
|
||||
// hmi button feedback
|
||||
_eExpectedOpenButtonFeedback : E_HMI_BUTTON_FEEDBACK;
|
||||
_eExpectedCloseButtonFeedback : E_HMI_BUTTON_FEEDBACK;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestManualModeButtonOpenClose');
|
||||
|
||||
// set manual request button on HMI and call valve block
|
||||
_stHMIValve.stManualButton.xRequest := TRUE;
|
||||
_fbValveOC(
|
||||
xReleaseManualMode:= TRUE,
|
||||
wProcessINTLK:= _wInterlocks,
|
||||
wProcessINTLKUsed:= _wInterlocksUsed,
|
||||
stHMIInterface:= _stHMIValve,
|
||||
xError=> ,
|
||||
xOpenFeedback:= ,
|
||||
xCloseFeedback:= ,
|
||||
xReleaseErrors:= ,
|
||||
xConfirmAlarms:= ,
|
||||
stValveConfig:= _stValveConfig,
|
||||
xOpenValve=> ,
|
||||
xCloseValve=> );
|
||||
|
||||
// Valve should now be in manual mode
|
||||
AssertTrue(Condition := _fbValveOC.IsInManualMode, Message := 'Valve did not change to manual mode pre test');
|
||||
|
||||
// Request open from HMI and call valve block
|
||||
_stHMIValve.stOpenButton.xRequest := TRUE;
|
||||
_fbValveOC(
|
||||
xReleaseManualMode:= TRUE,
|
||||
wProcessINTLK:= _wInterlocks,
|
||||
wProcessINTLKUsed:= _wInterlocksUsed,
|
||||
stHMIInterface:= _stHMIValve,
|
||||
xError=> ,
|
||||
xOpenFeedback:= ,
|
||||
xCloseFeedback:= ,
|
||||
xReleaseErrors:= ,
|
||||
xConfirmAlarms:= ,
|
||||
stValveConfig:= ,
|
||||
xOpenValve=> ,
|
||||
xCloseValve=> );
|
||||
|
||||
// test for valve state and HMI feedback
|
||||
AssertTrue(Condition := _fbValveOC.xOpenValve, Message := 'Valve did not open as requested by hmi button');
|
||||
AssertFalse(Condition := _stHMIValve.stOpenButton.xRequest, Message := 'Valve did not reset open request');
|
||||
_eExpectedOpenButtonFeedback := E_HMI_BUTTON_FEEDBACK.ACTIVE;
|
||||
_eExpectedCloseButtonFeedback := E_HMI_BUTTON_FEEDBACK.NONE;
|
||||
AssertEquals(Expected := _eExpectedOpenButtonFeedback, Actual := _stHMIValve.stOpenButton.eFeedback, Message := 'Valve did not send correct open button feedback signal while open');
|
||||
AssertEquals(Expected := _eExpectedCloseButtonFeedback, Actual := _stHMIValve.stCloseButton.eFeedback, Message := 'Valve did not send correct close button feedback signal while open');
|
||||
|
||||
// Request close from HMI and call valve block
|
||||
_stHMIValve.stCloseButton.xRequest := TRUE;
|
||||
_fbValveOC(
|
||||
xReleaseManualMode:= TRUE,
|
||||
wProcessINTLK:= _wInterlocks,
|
||||
wProcessINTLKUsed:= _wInterlocksUsed,
|
||||
stHMIInterface:= _stHMIValve,
|
||||
xError=> ,
|
||||
xOpenFeedback:= ,
|
||||
xCloseFeedback:= ,
|
||||
xReleaseErrors:= ,
|
||||
xConfirmAlarms:= ,
|
||||
stValveConfig:= ,
|
||||
xOpenValve=> ,
|
||||
xCloseValve=> );
|
||||
|
||||
// test for valve state and HMI feedback
|
||||
AssertTrue(Condition := _fbValveOC.xCloseValve, Message := 'Valve did not close as requested by hmi button');
|
||||
AssertFalse(Condition := _stHMIValve.stCloseButton.xRequest, Message := 'Valve did not reset close request');
|
||||
_eExpectedOpenButtonFeedback := E_HMI_BUTTON_FEEDBACK.NONE;
|
||||
_eExpectedCloseButtonFeedback := E_HMI_BUTTON_FEEDBACK.ACTIVE;
|
||||
AssertEquals(Expected := _eExpectedCloseButtonFeedback, Actual := _stHMIValve.stCloseButton.eFeedback, Message := 'Valve did not send correct close button feedback signal while closed');
|
||||
AssertEquals(Expected := _eExpectedOpenButtonFeedback, Actual := _stHMIValve.stOpenButton.eFeedback, Message := 'Valve did not send correct open button feedback signal while closed');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestManualModeOpenRelease" Id="{7b7870a1-a0b3-45c8-af76-55d8712c17bf}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestManualModeOpenRelease
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveConfig;
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
// valve interlocks
|
||||
wInterlocks : T_INTERLOCK := 0;
|
||||
wInterlocksUsed : T_INTERLOCK := 1;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestManualModeOpenRelease');
|
||||
|
||||
// set manual request button on HMI and call valve block
|
||||
_stHMIValve.stManualButton.xRequest := TRUE;
|
||||
_fbValve(
|
||||
xReleaseManualMode:= TRUE,
|
||||
wProcessINTLK:= wInterlocks,
|
||||
wProcessINTLKUsed:= wInterlocksUsed,
|
||||
stHMIInterface:= _stHMIValve,
|
||||
xError=> ,
|
||||
xOpenFeedback:= ,
|
||||
xCloseFeedback:= ,
|
||||
xReleaseErrors:= ,
|
||||
xConfirmAlarms:= ,
|
||||
stValveConfig:= _stValveConfig,
|
||||
xOpenValve=> ,
|
||||
xCloseValve=> );
|
||||
|
||||
// Valve should now be in manual mode
|
||||
AssertTrue(Condition := _fbValve.IsInManualMode, Message := 'Valve did not change to manual mode pre test');
|
||||
|
||||
// Valve should not realease open button with active interlock
|
||||
AssertFalse(Condition := _stHMIValve.stOpenButton.xRelease, Message := 'Valve did release open button but should not');
|
||||
|
||||
// Test if request is denied by valve with active interlocks
|
||||
_stHMIValve.stOpenButton.xRequest := TRUE;
|
||||
_fbValve(
|
||||
xReleaseManualMode:= TRUE,
|
||||
wProcessINTLK:= wInterlocks,
|
||||
wProcessINTLKUsed:= wInterlocksUsed,
|
||||
stHMIInterface:= _stHMIValve,
|
||||
xError=> ,
|
||||
xOpenFeedback:= ,
|
||||
xCloseFeedback:= ,
|
||||
xReleaseErrors:= ,
|
||||
xConfirmAlarms:= ,
|
||||
stValveConfig:= ,
|
||||
xOpenValve=> ,
|
||||
xCloseValve=> );
|
||||
|
||||
AssertFalse(Condition := _fbValve.xOpenValve, Message := 'Valve did not block manual open command with active interlock');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
77
PLC/POUs/Unittests/ValveTests/FB_ValveTestTimoutClose.TcPOU
Normal file
77
PLC/POUs/Unittests/ValveTests/FB_ValveTestTimoutClose.TcPOU
Normal file
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<POU Name="FB_ValveTestTimoutClose" Id="{676995cc-e0f8-4711-82b2-410116e6831b}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_ValveTestTimoutClose EXTENDS TcUnit.FB_TestSuite
|
||||
VAR
|
||||
// feedback result
|
||||
_xOpenFeedback : BOOL := FALSE;
|
||||
_xCloseFeedback : BOOL := FALSE;
|
||||
|
||||
// valve instance
|
||||
_fbValveTimeout : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// test timings
|
||||
_fbTimeoutCloseTestTimer : TON := (PT := T#200MS);
|
||||
_fbDelayFeedbackSignalTimer : TON := (PT := T#50MS);
|
||||
|
||||
// test finished
|
||||
_xTestTimeoutFinished : BOOL;
|
||||
|
||||
// current test state
|
||||
_iState : INT;
|
||||
|
||||
// vlave config
|
||||
_stValveConfig : ST_ValveConfig := (timTimeoutOpen := t#0MS, timTimeoutClose := T#100MS);
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TestClose();]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="TestClose" Id="{b2dc7638-d362-4caf-a205-a2aede6d9720}">
|
||||
<Declaration><![CDATA[METHOD TestClose
|
||||
VAR_INPUT
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestClose');
|
||||
|
||||
CASE _iState OF
|
||||
0:
|
||||
// request automatic close and start timers
|
||||
_fbValveTimeout(xAutomaticOpen := FALSE, stHMIInterface := _stHMIValve);
|
||||
_fbTimeoutCloseTestTimer.IN := TRUE;
|
||||
_fbDelayFeedbackSignalTimer.IN := TRUE;
|
||||
_iState := 10;
|
||||
|
||||
10:
|
||||
// set close feedback after 50ms and call valve block
|
||||
_xOpenFeedback := FALSE;
|
||||
_xCloseFeedback := _fbValveTimeout.xCloseValve AND _fbDelayFeedbackSignalTimer.Q;
|
||||
_fbValveTimeout(xOpenFeedback := _xOpenFeedback, xCloseFeedback := _xCloseFeedback, stHMIInterface := _stHMIValve, stValveConfig := _stValveConfig);
|
||||
|
||||
// test timeout after 200ms
|
||||
IF _fbTimeoutCloseTestTimer.Q THEN
|
||||
_iState := 20;
|
||||
_fbDelayFeedbackSignalTimer.IN := FALSE;
|
||||
_fbTimeoutCloseTestTimer.IN := FALSE;
|
||||
END_IF
|
||||
|
||||
20:
|
||||
// assert IsClosed and no error
|
||||
_xTestTimeoutFinished := TRUE;
|
||||
AssertTrue(Condition := _fbValveTimeout.IsClosed AND NOT _fbValveTimeout.xError, Message := 'Valve threw close timeout error');
|
||||
END_CASE
|
||||
|
||||
// call timer
|
||||
_fbTimeoutCloseTestTimer();
|
||||
_fbDelayFeedbackSignalTimer();
|
||||
|
||||
IF _xTestTimeoutFinished THEN
|
||||
TEST_FINISHED();
|
||||
END_IF]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
78
PLC/POUs/Unittests/ValveTests/FB_ValveTestTimoutOpen.TcPOU
Normal file
78
PLC/POUs/Unittests/ValveTests/FB_ValveTestTimoutOpen.TcPOU
Normal file
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<POU Name="FB_ValveTestTimoutOpen" Id="{49e1a729-e622-4855-a7d7-67a9f99d1550}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_ValveTestTimoutOpen EXTENDS TcUnit.FB_TestSuite
|
||||
VAR
|
||||
// valve feedback
|
||||
_xOpenFeedback : BOOL := FALSE;
|
||||
_xCloseFeedback : BOOL := FALSE;
|
||||
|
||||
// valve instance
|
||||
_fbValveTimeout : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// test timings
|
||||
_fbTimeoutOpenTestTimer : TON := (PT := T#200MS);
|
||||
_fbDelayFeedbackSignalTimer : TON := (PT := T#50MS);
|
||||
|
||||
// test finished
|
||||
_xTestTimeoutFinished : BOOL;
|
||||
|
||||
// current test state
|
||||
_iState : INT;
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveConfig := (timTimeoutOpen := t#100MS, timTimeoutClose := T#0MS);
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TestOpen();]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="TestOpen" Id="{4f96f391-c47b-4572-833e-9be45b3993f5}">
|
||||
<Declaration><![CDATA[METHOD TestOpen
|
||||
VAR_INPUT
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestOpen');
|
||||
|
||||
CASE _iState OF
|
||||
0:
|
||||
// request automatic open and start timers
|
||||
_fbValveTimeout(xAutomaticOpen := TRUE, stHMIInterface := _stHMIValve);
|
||||
_fbTimeoutOpenTestTimer.IN := TRUE;
|
||||
_fbDelayFeedbackSignalTimer.IN := TRUE;
|
||||
_iState := 10;
|
||||
|
||||
10:
|
||||
// set open feedback after 50ms and call valve block
|
||||
_xOpenFeedback := _fbValveTimeout.xOpenValve AND _fbDelayFeedbackSignalTimer.Q;
|
||||
_xCloseFeedback := FALSE;
|
||||
_fbValveTimeout(xOpenFeedback := _xOpenFeedback, xCloseFeedback := _xCloseFeedback, stHMIInterface := _stHMIValve, stValveConfig := _stValveConfig);
|
||||
|
||||
// test timeout after 200ms
|
||||
IF _fbTimeoutOpenTestTimer.Q THEN
|
||||
_iState := 20;
|
||||
_fbDelayFeedbackSignalTimer.IN := FALSE;
|
||||
_fbTimeoutOpenTestTimer.IN := FALSE;
|
||||
END_IF
|
||||
|
||||
20:
|
||||
// assert IsOpen and no error
|
||||
_xTestTimeoutFinished := TRUE;
|
||||
AssertTrue(Condition := _fbValveTimeout.IsOpen AND NOT _fbValveTimeout.xError, Message := 'Valve threw open timeout error');
|
||||
END_CASE
|
||||
|
||||
// call timer
|
||||
_fbTimeoutOpenTestTimer();
|
||||
_fbDelayFeedbackSignalTimer();
|
||||
|
||||
IF _xTestTimeoutFinished THEN
|
||||
TEST_FINISHED();
|
||||
END_IF]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<POU Name="FB_ValveTestTriggerTimoutClose" Id="{492c2d14-a1aa-412e-b759-1e35a3301e66}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_ValveTestTriggerTimoutClose EXTENDS TcUnit.FB_TestSuite
|
||||
VAR
|
||||
// valve feedback
|
||||
_xOpenFeedback : BOOL := FALSE;
|
||||
_xCloseFeedback : BOOL := FALSE;
|
||||
|
||||
// valve instance
|
||||
_fbValveTimeout : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// test timings
|
||||
_fbTimeoutCloseTestTimer : TON := (PT := T#100MS);
|
||||
_fbDelayFeedbackSignalTimer : TON := (PT := T#200MS);
|
||||
|
||||
// test finished
|
||||
_xTestTimeoutFinished : BOOL;
|
||||
|
||||
// current test state
|
||||
_iState : INT;
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveConfig := (timTimeoutOpen := t#0MS, timTimeoutClose := T#100MS, xHasClosedFeedback := TRUE);
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TestTriggerTimeoutClose();]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="TestTriggerTimeoutClose" Id="{cc9351d2-a43b-4e56-9e5b-6d2747045073}">
|
||||
<Declaration><![CDATA[METHOD TestTriggerTimeoutClose
|
||||
VAR_INPUT
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestTriggerTimeoutClose');
|
||||
|
||||
CASE _iState OF
|
||||
0:
|
||||
// request automatic close and start timers
|
||||
_fbValveTimeout(xAutomaticOpen := FALSE, stHMIInterface := _stHMIValve);
|
||||
_fbTimeoutCloseTestTimer.IN := TRUE;
|
||||
_fbDelayFeedbackSignalTimer.IN := TRUE;
|
||||
_iState := 10;
|
||||
|
||||
10:
|
||||
// both feedback false and call valve block
|
||||
_xOpenFeedback := FALSE;
|
||||
_xCloseFeedback := FALSE;
|
||||
_fbValveTimeout(xOpenFeedback := _xOpenFeedback, xCloseFeedback := _xCloseFeedback, xInUnitTestMode := TRUE, stHMIInterface := _stHMIValve, stValveConfig := _stValveConfig);
|
||||
|
||||
// test timeout after 200ms
|
||||
IF _fbTimeoutCloseTestTimer.Q THEN
|
||||
_iState := 20;
|
||||
_fbDelayFeedbackSignalTimer.IN := FALSE;
|
||||
_fbTimeoutCloseTestTimer.IN := FALSE;
|
||||
END_IF
|
||||
|
||||
20:
|
||||
// assert error
|
||||
_xTestTimeoutFinished := TRUE;
|
||||
AssertTrue(Condition := _fbValveTimeout.xError, Message := 'Valve did not throw an close timeout error');
|
||||
END_CASE
|
||||
|
||||
// call timer
|
||||
_fbTimeoutCloseTestTimer();
|
||||
_fbDelayFeedbackSignalTimer();
|
||||
|
||||
IF _xTestTimeoutFinished THEN
|
||||
TEST_FINISHED();
|
||||
END_IF]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<POU Name="FB_ValveTestTriggerTimoutOpen" Id="{3357d110-5f1d-4d49-b94c-6c4cc8f6b306}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_ValveTestTriggerTimoutOpen EXTENDS TcUnit.FB_TestSuite
|
||||
VAR
|
||||
// valve feedback
|
||||
_xOpenFeedback : BOOL := FALSE;
|
||||
_xCloseFeedback : BOOL := FALSE;
|
||||
|
||||
// valve instance
|
||||
_fbValveTimeout : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// test timings
|
||||
_fbTimeoutOpenTestTimer : TON := (PT := T#100MS);
|
||||
_fbDelayFeedbackSignalTimer : TON := (PT := T#200MS);
|
||||
|
||||
// test finished
|
||||
_xTestTimeoutFinished : BOOL;
|
||||
|
||||
// current test state
|
||||
_iState : INT;
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveConfig := (timTimeoutOpen := t#100MS, timTimeoutClose := T#0MS, xHasOpenFeedback := TRUE);
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TestTriggerTimeoutOpen();]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="TestTriggerTimeoutOpen" Id="{2b990579-8e3f-4c9d-9f7f-cb96af520f83}">
|
||||
<Declaration><![CDATA[METHOD TestTriggerTimeoutOpen
|
||||
VAR_INPUT
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestTriggerTimeoutOpen');
|
||||
|
||||
CASE _iState OF
|
||||
0:
|
||||
// request automatic open and start timers
|
||||
_fbValveTimeout(xAutomaticOpen := TRUE, stHMIInterface := _stHMIValve);
|
||||
_fbTimeoutOpenTestTimer.IN := TRUE;
|
||||
_fbDelayFeedbackSignalTimer.IN := TRUE;
|
||||
_fbValveTimeout.xInUnitTestMode := TRUE;
|
||||
_iState := 10;
|
||||
|
||||
10:
|
||||
// both feedback false and call valve block
|
||||
_xOpenFeedback := FALSE;
|
||||
_xCloseFeedback := FALSE;
|
||||
_fbValveTimeout(xOpenFeedback := _xOpenFeedback, xCloseFeedback := _xCloseFeedback, xInUnitTestMode := TRUE, stHMIInterface := _stHMIValve, stValveConfig := _stValveConfig);
|
||||
|
||||
// test timeout after 200ms
|
||||
IF _fbTimeoutOpenTestTimer.Q THEN
|
||||
_iState := 20;
|
||||
_fbDelayFeedbackSignalTimer.IN := FALSE;
|
||||
_fbTimeoutOpenTestTimer.IN := FALSE;
|
||||
END_IF
|
||||
|
||||
20:
|
||||
// assert error
|
||||
_xTestTimeoutFinished := TRUE;
|
||||
AssertTrue(Condition := _fbValveTimeout.xError, Message := 'Valve did not throw an open timeout error');
|
||||
END_CASE
|
||||
|
||||
// call timer
|
||||
_fbTimeoutOpenTestTimer();
|
||||
_fbDelayFeedbackSignalTimer();
|
||||
|
||||
IF _xTestTimeoutFinished THEN
|
||||
TEST_FINISHED();
|
||||
END_IF]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
427
PLC/POUs/Unittests/ValveTests/FB_Valve_Test.TcPOU
Normal file
427
PLC/POUs/Unittests/ValveTests/FB_Valve_Test.TcPOU
Normal file
@@ -0,0 +1,427 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1">
|
||||
<POU Name="FB_Valve_Test" Id="{1304864d-3fed-4e82-bcdb-9dc7e4b2a441}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_Valve_Test EXTENDS TcUnit.FB_TestSuite
|
||||
VAR
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Automatic Mode
|
||||
SwitchToAutomaticMode();
|
||||
OpenValveInAutomaticMode();
|
||||
|
||||
// Manual Mode
|
||||
SwitchToManualMode();
|
||||
OpenValveInManualMode();
|
||||
|
||||
// Test interlocks
|
||||
TestProcessInterlocks();
|
||||
TestProcessINTLKsInAutomaticMode();
|
||||
TestProcessINTLKsInManualMode();
|
||||
|
||||
// Check feedback signals
|
||||
CheckOpenCloseFeedbacks();
|
||||
]]></ST>
|
||||
</Implementation>
|
||||
<Method Name="CheckOpenCloseFeedbacks" Id="{a28ac9cc-3e5a-4aec-ae25-5e2418416c2e}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD CheckOpenCloseFeedbacks
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_Valve('');
|
||||
|
||||
// valve config
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
_stValveConfig : ST_ValveConfig;
|
||||
|
||||
// valve feedback
|
||||
_xOpenFeedback : BOOL;
|
||||
_xCloseFeedback : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('CheckOpenCloseFeedbacks');
|
||||
|
||||
// set timeout to zero and open+close feedback present
|
||||
_stValveConfig.timTimeoutClose := T#0S;
|
||||
_stValveConfig.timTimeoutOpen := T#0S;
|
||||
_stValveConfig.xHasOpenFeedback := TRUE;
|
||||
_stValveConfig.xHasClosedFeedback := TRUE;
|
||||
|
||||
// Test feedbacks in manual mode
|
||||
_xOpenFeedback := FALSE;
|
||||
_xCloseFeedback := FALSE;
|
||||
_fbValve.xReleaseManualMode := TRUE;
|
||||
_fbValve.ReqManualMode();
|
||||
_fbValve(xOpenFeedback := _xOpenFeedback, xCloseFeedback := _xCloseFeedback, stHMIInterface := _stHMIValve, stValveConfig := _stValveConfig, xInUnitTestMode := TRUE);
|
||||
|
||||
// We should now be in manual mode
|
||||
AssertTrue(Condition := _fbValve.IsInManualMode, Message := 'Valve did not changed to manual mode');
|
||||
|
||||
|
||||
// Test not closed and not opened
|
||||
AssertFalse(Condition := _fbValve.IsClosed OR _fbValve.IsOpen, Message := 'Valve should not signal open or closed with no feedback signals');
|
||||
|
||||
// Test closed
|
||||
_xOpenFeedback := FALSE;
|
||||
_xCloseFeedback := TRUE;
|
||||
_fbValve(xOpenFeedback := _xOpenFeedback, xCloseFeedback := _xCloseFeedback,stHMIInterface := _stHMIValve, stValveConfig := _stValveConfig, xInUnitTestMode := TRUE);
|
||||
AssertTrue(Condition := _fbValve.IsClosed, Message := 'Valve should be closed');
|
||||
AssertFalse(Condition := _fbValve.IsOpen, Message := 'Valve should not be open');
|
||||
|
||||
// Test opened
|
||||
_xOpenFeedback := TRUE;
|
||||
_xCloseFeedback := FALSE;
|
||||
_stHMIValve.stOpenButton.xRequest := TRUE;
|
||||
_fbValve(stHMIInterface := _stHMIValve);
|
||||
_fbValve(xOpenFeedback := _xOpenFeedback, xCloseFeedback := _xCloseFeedback, stHMIInterface := _stHMIValve, stValveConfig := _stValveConfig, xInUnitTestMode := TRUE);
|
||||
AssertTrue(Condition := _fbValve.IsOpen, Message := 'Valve should be open');
|
||||
AssertFalse(Condition := _fbValve.IsClosed, Message := 'Valve should not be closed');
|
||||
|
||||
// Test open and close
|
||||
_xOpenFeedback := TRUE;
|
||||
_xCloseFeedback := TRUE;
|
||||
_fbValve(xOpenFeedback := _xOpenFeedback, xCloseFeedback := _xCloseFeedback, stHMIInterface := _stHMIValve, stValveConfig := _stValveConfig, xInUnitTestMode := TRUE);
|
||||
AssertFalse(Condition := _fbValve.IsClosed OR _fbValve.IsOpen, Message := 'Valve should not signal open or closed with both feedback signals high');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="OpenValveInAutomaticMode" Id="{0b9852fb-7e89-42e5-977d-75ac8ce8f431}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD OpenValveInAutomaticMode
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// valve state
|
||||
_xResult : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('OpenValveInAutomaticMode');
|
||||
|
||||
// Set in automatic mode
|
||||
_fbValve.ReqAutomaticMode();
|
||||
|
||||
// Open valve
|
||||
_fbValve(xAutomaticOpen := TRUE, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Needs one cycle to write outputs
|
||||
_fbValve(stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
|
||||
// evaluate valve state
|
||||
_xResult := _fbValve.IsOpen AND NOT _fbValve.IsClosed;
|
||||
AssertTrue(_xResult, 'Valve did not open in Automatic Mode');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="OpenValveInManualMode" Id="{ebd3a3ca-f259-4efb-b134-f4d858027ff8}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD OpenValveInManualMode
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// valve state
|
||||
_xResult : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('OpenValveInManualMode');
|
||||
|
||||
// Needs one cycle to write outputs
|
||||
_fbValve.xReleaseManualMode := TRUE;
|
||||
|
||||
// Set in manual mode
|
||||
_fbValve.ReqManualMode();
|
||||
|
||||
// Open valve
|
||||
_stHMIValve.stOpenButton.xRequest := TRUE;
|
||||
_fbValve(stHMIInterface := _stHMIValve);
|
||||
_fbValve(stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
|
||||
// evaluate valve state
|
||||
_xResult := _fbValve.IsOpen AND NOT _fbValve.IsClosed;
|
||||
AssertTrue(_xResult, 'Valve did not open in Manual Mode');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="SwitchToAutomaticMode" Id="{f0347789-26a5-4296-ac7a-3320d7d68b7f}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD SwitchToAutomaticMode
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// valve state
|
||||
_xResult : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('SwitchToAutomaticMode');
|
||||
|
||||
// request switch to automatic modes
|
||||
_fbValve.ReqAutomaticMode();
|
||||
|
||||
// call valve and read values
|
||||
_fbValve(stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
|
||||
// set result
|
||||
_xResult := _fbValve.IsInAutomaticMode;
|
||||
|
||||
// assert result
|
||||
AssertTrue(_xResult, 'Valve did not change into Automatic Mode');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="SwitchToManualMode" Id="{f3a6a0eb-d468-45b4-ae0e-31d573348f7d}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD SwitchToManualMode
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_Valve('');
|
||||
|
||||
// valve state
|
||||
_xResult : BOOL;
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('SwitchToManualMode');
|
||||
|
||||
// Test switch without xReleaseManualMode
|
||||
_fbValve.xReleaseManualMode := FALSE;
|
||||
_fbValve.ReqManualMode();
|
||||
_fbValve(stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
_xResult := NOT _fbValve.IsInManualMode;
|
||||
AssertTrue(_xResult, 'Valve changed to Manual Mode but this mode was not released');
|
||||
|
||||
// Test with xReleaseManualMode
|
||||
_fbValve.xReleaseManualMode := TRUE;
|
||||
_fbValve.ReqManualMode();
|
||||
_fbValve(stHMIInterface := _stHMIValve);
|
||||
_xResult := _fbValve.IsInManualMode;
|
||||
AssertTrue( _xResult, 'Valve did not changed to Manual Mode');
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestProcessInterlocks" Id="{a963e3c3-4c6c-44cd-913b-cd94b66ce40c}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
{attribute 'analysis' := '-81'}
|
||||
METHOD TestProcessInterlocks
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// valve state
|
||||
_xResult : BOOL;
|
||||
|
||||
// current interlock
|
||||
_usiCounter : USINT;
|
||||
|
||||
// Init all entries to TRUE
|
||||
_wInterlocks : T_INTERLOCK := 2#1111_1111_1111_1111;//[GVL_VALVE.MAX_INTERLOCKS(TRUE)];
|
||||
_wInterlocksUsed : T_INTERLOCK := 2#1111_1111_1111_1111;
|
||||
|
||||
// interlock test result
|
||||
_axInterlockTestResultFalse : ARRAY[0..GVL_CONFIGS.MAX_INTERLOCKS-1] OF BOOL;
|
||||
_axInterlockTestResultTrue : ARRAY[0..GVL_CONFIGS.MAX_INTERLOCKS-1] OF BOOL;
|
||||
|
||||
// interlock comulated result
|
||||
_xInterlocksFalseOK : BOOL;
|
||||
_xInterlocksTrueOK : BOOL;
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
// loop iterations for interlock test
|
||||
usiEndValue : USINT := GVL_CONFIGS.MAX_INTERLOCKS-1;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Test interlocks as reutrn value
|
||||
TEST('TestProcessInterlocks');
|
||||
|
||||
// call valve with interlocks and evaluate result
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
_xResult := _fbValve.ProcessInterlocksOK;
|
||||
|
||||
AssertTrue(_xResult, 'Interlocks not Ok but should be');
|
||||
|
||||
// Test each interlock individually
|
||||
// Save the result in the two following variables
|
||||
_xInterlocksFalseOK := TRUE;
|
||||
_xInterlocksTrueOK := TRUE;
|
||||
|
||||
FOR _usiCounter := 0 TO usiEndValue DO
|
||||
|
||||
// Test one interlock for false and then disable it
|
||||
_wInterlocks := SHL(_wInterlocks, 1);
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Save result in an array for later debugging if necessary
|
||||
_axInterlockTestResultFalse[_usiCounter] := _fbValve.ProcessInterlocksOK;
|
||||
|
||||
// Save global result
|
||||
IF _fbValve.ProcessInterlocksOK THEN
|
||||
_xInterlocksFalseOK := FALSE;
|
||||
END_IF
|
||||
// Disable this interlock after testing it
|
||||
_wInterlocksUsed := SHL(_wInterlocksUsed, 1);
|
||||
|
||||
// Test if, after disabling the interlock, the interlocks are ok again
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Save result in an array for later debugging if necessary
|
||||
_axInterlockTestResultTrue[_usiCounter] := _fbValve.ProcessInterlocksOK;
|
||||
|
||||
// Save global result
|
||||
IF NOT _fbValve.ProcessInterlocksOK THEN
|
||||
_xInterlocksTrueOK := FALSE;
|
||||
END_IF
|
||||
END_FOR
|
||||
|
||||
// Test False interlocks result
|
||||
AssertTrue(_xInterlocksFalseOK, 'Interlock should not be ok but are');
|
||||
|
||||
// Test False interlocks result
|
||||
AssertTrue(_xInterlocksTrueOK, 'Interlock should be ok but are not');
|
||||
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestProcessINTLKsInAutomaticMode" Id="{d6681863-baa6-4f1c-bb6d-7d6ecd0c4518}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestProcessINTLKsInAutomaticMode
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// valve interlocks
|
||||
_wInterlocks : T_INTERLOCK;
|
||||
_wInterlocksUsed : T_INTERLOCK;
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveConfig;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestProcessINTLKsInAutomaticMode');
|
||||
_wInterlocks.0 := 1;
|
||||
_wInterlocksUsed.0 := 1;
|
||||
|
||||
// Switch to automatic mode
|
||||
_fbValve.ReqAutomaticMode();
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
|
||||
// Open valve in automatic mode
|
||||
_fbValve(xAutomaticOpen := TRUE, stHMIInterface := _stHMIValve);
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Test if valve is open, when not we have an intermediate error
|
||||
// which should have been found by another test
|
||||
IF _fbValve.IsOpen THEN
|
||||
// Activate an interlock
|
||||
_wInterlocks.0 := 0;
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Valve should now be closed
|
||||
AssertFalse(Condition := _fbValve.xOpenValve, Message := 'Valve should not be open with active Interlock');
|
||||
AssertTrue(Condition := _fbValve.xCloseValve, Message := 'Close output not active with active Interlock');
|
||||
|
||||
// Test the same with open valve when interlock active
|
||||
_stValveConfig.xOpenWhenInterlocksActive := TRUE;
|
||||
_fbValve(stValveConfig := _stValveConfig, wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Valve should now be open
|
||||
AssertTrue(Condition := _fbValve.xOpenValve, Message := 'Valve should be open with active Interlock and inverted config');
|
||||
AssertFalse(Condition := _fbValve.xCloseValve, Message := 'Close output active with active Interlock and inverted config');
|
||||
ELSE
|
||||
AssertTrue(Condition := _fbValve.IsOpen, Message := 'Valve did not open before the test');
|
||||
END_IF
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="TestProcessINTLKsInManualMode" Id="{24ef6949-9116-427c-aa82-83ed6d197c5c}">
|
||||
<Declaration><![CDATA[{warning disable C0394}
|
||||
METHOD TestProcessINTLKsInManualMode
|
||||
VAR
|
||||
// valve instance
|
||||
_fbValve : FB_Valve('');
|
||||
|
||||
// valve hmi data
|
||||
_stHMIValve : ST_HMI_VALVE_DATA;
|
||||
|
||||
// valve interlocks
|
||||
_wInterlocks : T_INTERLOCK;
|
||||
_wInterlocksUsed : T_INTERLOCK;
|
||||
|
||||
// valve config
|
||||
_stValveConfig : ST_ValveConfig;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[TEST('TestProcessINTLKsInManualMode');
|
||||
_wInterlocks.0 := 1;
|
||||
_wInterlocksUsed.0 := 1;
|
||||
|
||||
// Switch to manual mode
|
||||
_fbValve.xReleaseManualMode := TRUE;
|
||||
_fbValve.ReqManualMode();
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve, xInUnitTestMode := TRUE);
|
||||
|
||||
// Open valve in manual mode
|
||||
_stHMIValve.stOpenButton.xRequest := TRUE;
|
||||
_fbValve(stHMIInterface := _stHMIValve);
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Test if valve is open, when not we have an intermediate error
|
||||
// which should have been found by another test
|
||||
IF _fbValve.IsOpen THEN
|
||||
// Activate an interlock
|
||||
_wInterlocks.0 := 0;
|
||||
_fbValve(wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Valve should now be closed
|
||||
AssertFalse(Condition := _fbValve.xOpenValve, Message := 'Valve should not be open with active Interlock');
|
||||
AssertTrue(Condition := _fbValve.xCloseValve, Message := 'Close output not active with active Interlock');
|
||||
|
||||
// Test the same with open valve when interlock active
|
||||
_stValveConfig.xOpenWhenInterlocksActive := TRUE;
|
||||
_fbValve(stValveConfig := _stValveConfig, wProcessINTLK := _wInterlocks, wProcessINTLKUsed := _wInterlocksUsed, stHMIInterface := _stHMIValve);
|
||||
|
||||
// Valve should now be open
|
||||
AssertTrue(Condition := _fbValve.xOpenValve, Message := 'Valve should be open with active Interlock and inverted config');
|
||||
AssertFalse(Condition := _fbValve.xCloseValve, Message := 'Close output active with active Interlock and inverted config');
|
||||
AssertTrue(Condition := _stHMIValve.stOpenButton.eFeedback = E_HMI_BUTTON_FEEDBACK.ACTIVE, Message := 'Open button should be set active with active Interlock and inverted config');
|
||||
ELSE
|
||||
AssertTrue(Condition := _fbValve.IsOpen, Message := 'Valve did not open before the test');
|
||||
END_IF
|
||||
|
||||
TEST_FINISHED();]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
Reference in New Issue
Block a user