Changed from ISA88 to PackML

- Added PackML Base FB's
- Added Unit Tests for PackML Base State Machine
- Added Robot job numbers according to new interface
- Added PLC job number for robot to call according to new interface
- Change Robot to PackML interface
This commit is contained in:
2026-01-23 22:55:49 +01:00
parent 2d11c43579
commit 3946e45c65
26 changed files with 1615 additions and 421 deletions

View File

@@ -27,8 +27,8 @@ Global
Release|TwinCAT RT (x86) = Release|TwinCAT RT (x86)
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Debug|TwinCAT HMI.ActiveCfg = Debug|TwinCAT RT (x86)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Debug|TwinCAT HMI.Build.0 = Debug|TwinCAT RT (x86)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Debug|TwinCAT HMI.ActiveCfg = Debug|TwinCAT OS (x64)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Debug|TwinCAT HMI.Build.0 = Debug|TwinCAT OS (x64)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Debug|TwinCAT OS (ARMV7-A).ActiveCfg = Debug|TwinCAT OS (ARMV7-A)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Debug|TwinCAT OS (ARMV7-A).Build.0 = Debug|TwinCAT OS (ARMV7-A)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Debug|TwinCAT OS (ARMV7-M).ActiveCfg = Debug|TwinCAT OS (ARMV7-M)
@@ -43,8 +43,8 @@ Global
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Debug|TwinCAT RT (x86).Build.0 = Debug|TwinCAT RT (x86)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Release|TwinCAT HMI.ActiveCfg = Release|TwinCAT RT (x86)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Release|TwinCAT HMI.Build.0 = Release|TwinCAT RT (x86)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Release|TwinCAT HMI.ActiveCfg = Release|TwinCAT OS (x64)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Release|TwinCAT HMI.Build.0 = Release|TwinCAT OS (x64)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Release|TwinCAT OS (ARMV7-A).ActiveCfg = Release|TwinCAT OS (ARMV7-A)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Release|TwinCAT OS (ARMV7-A).Build.0 = Release|TwinCAT OS (ARMV7-A)
{CB97A0B0-7E22-470D-8550-AA318EA46E50}.Release|TwinCAT OS (ARMV7-M).ActiveCfg = Release|TwinCAT OS (ARMV7-M)
@@ -91,8 +91,8 @@ Global
{B4B0E423-9884-4277-82A6-6D7062793303}.Release|TwinCAT RT (x64).Build.0 = Release|TwinCAT HMI
{B4B0E423-9884-4277-82A6-6D7062793303}.Release|TwinCAT RT (x86).ActiveCfg = Release|TwinCAT HMI
{B4B0E423-9884-4277-82A6-6D7062793303}.Release|TwinCAT RT (x86).Build.0 = Release|TwinCAT HMI
{384A40E7-3107-4D80-8361-04B00829260A}.Debug|TwinCAT HMI.ActiveCfg = Debug|TwinCAT RT (x86)
{384A40E7-3107-4D80-8361-04B00829260A}.Debug|TwinCAT HMI.Build.0 = Debug|TwinCAT RT (x86)
{384A40E7-3107-4D80-8361-04B00829260A}.Debug|TwinCAT HMI.ActiveCfg = Debug|TwinCAT OS (x64)
{384A40E7-3107-4D80-8361-04B00829260A}.Debug|TwinCAT HMI.Build.0 = Debug|TwinCAT OS (x64)
{384A40E7-3107-4D80-8361-04B00829260A}.Debug|TwinCAT OS (ARMV7-A).ActiveCfg = Debug|TwinCAT OS (ARMV7-A)
{384A40E7-3107-4D80-8361-04B00829260A}.Debug|TwinCAT OS (ARMV7-A).Build.0 = Debug|TwinCAT OS (ARMV7-A)
{384A40E7-3107-4D80-8361-04B00829260A}.Debug|TwinCAT OS (ARMV7-M).ActiveCfg = Debug|TwinCAT OS (ARMV7-M)
@@ -107,8 +107,8 @@ Global
{384A40E7-3107-4D80-8361-04B00829260A}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64)
{384A40E7-3107-4D80-8361-04B00829260A}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86)
{384A40E7-3107-4D80-8361-04B00829260A}.Debug|TwinCAT RT (x86).Build.0 = Debug|TwinCAT RT (x86)
{384A40E7-3107-4D80-8361-04B00829260A}.Release|TwinCAT HMI.ActiveCfg = Release|TwinCAT RT (x86)
{384A40E7-3107-4D80-8361-04B00829260A}.Release|TwinCAT HMI.Build.0 = Release|TwinCAT RT (x86)
{384A40E7-3107-4D80-8361-04B00829260A}.Release|TwinCAT HMI.ActiveCfg = Release|TwinCAT OS (x64)
{384A40E7-3107-4D80-8361-04B00829260A}.Release|TwinCAT HMI.Build.0 = Release|TwinCAT OS (x64)
{384A40E7-3107-4D80-8361-04B00829260A}.Release|TwinCAT OS (ARMV7-A).ActiveCfg = Release|TwinCAT OS (ARMV7-A)
{384A40E7-3107-4D80-8361-04B00829260A}.Release|TwinCAT OS (ARMV7-A).Build.0 = Release|TwinCAT OS (ARMV7-A)
{384A40E7-3107-4D80-8361-04B00829260A}.Release|TwinCAT OS (ARMV7-M).ActiveCfg = Release|TwinCAT OS (ARMV7-M)
@@ -123,8 +123,8 @@ Global
{384A40E7-3107-4D80-8361-04B00829260A}.Release|TwinCAT RT (x64).Build.0 = Release|TwinCAT RT (x64)
{384A40E7-3107-4D80-8361-04B00829260A}.Release|TwinCAT RT (x86).ActiveCfg = Release|TwinCAT RT (x86)
{384A40E7-3107-4D80-8361-04B00829260A}.Release|TwinCAT RT (x86).Build.0 = Release|TwinCAT RT (x86)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Debug|TwinCAT HMI.ActiveCfg = Debug|TwinCAT RT (x86)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Debug|TwinCAT HMI.Build.0 = Debug|TwinCAT RT (x86)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Debug|TwinCAT HMI.ActiveCfg = Debug|TwinCAT OS (x64)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Debug|TwinCAT HMI.Build.0 = Debug|TwinCAT OS (x64)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Debug|TwinCAT OS (ARMV7-A).ActiveCfg = Debug|TwinCAT OS (ARMV7-A)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Debug|TwinCAT OS (ARMV7-A).Build.0 = Debug|TwinCAT OS (ARMV7-A)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Debug|TwinCAT OS (ARMV7-M).ActiveCfg = Debug|TwinCAT OS (ARMV7-M)
@@ -139,8 +139,8 @@ Global
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Debug|TwinCAT RT (x86).Build.0 = Debug|TwinCAT RT (x86)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Release|TwinCAT HMI.ActiveCfg = Release|TwinCAT RT (x86)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Release|TwinCAT HMI.Build.0 = Release|TwinCAT RT (x86)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Release|TwinCAT HMI.ActiveCfg = Release|TwinCAT OS (x64)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Release|TwinCAT HMI.Build.0 = Release|TwinCAT OS (x64)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Release|TwinCAT OS (ARMV7-A).ActiveCfg = Release|TwinCAT OS (ARMV7-A)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Release|TwinCAT OS (ARMV7-A).Build.0 = Release|TwinCAT OS (ARMV7-A)
{16E7B360-DCD5-431E-9380-EF0E96A38071}.Release|TwinCAT OS (ARMV7-M).ActiveCfg = Release|TwinCAT OS (ARMV7-M)

View File

@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<TcSmProject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.beckhoff.com/schemas/2012/07/TcSmProject" TcSmVersion="1.0" TcVersion="3.1.4026.19">
<Project ProjectGUID="{CB97A0B0-7E22-470D-8550-AA318EA46E50}" TargetNetId="5.127.104.206.1.1" Target64Bit="true" ShowHideConfigurations="#x6">
<Project ProjectGUID="{CB97A0B0-7E22-470D-8550-AA318EA46E50}" TargetNetId="5.167.199.178.1.1" Target64Bit="true" ShowHideConfigurations="#x6">
<System>
<Licenses>
<Target>
@@ -13,6 +13,9 @@
<Name>PlcTask</Name>
</Task>
</Tasks>
<TypeSystem>
<AdditionalTmcFile Name="Infineon" File="Infineon.tmc"/>
</TypeSystem>
</System>
<Motion>
<NC File="NC.xti"/>
@@ -36,10 +39,4 @@
<Device File="Device 5 (EtherCAT).xti" Id="5"/>
</Io>
</Project>
<Mappings>
<MappingInfo Identifier="{00000000-2001-0850-0020-500851000403}" Id="#x02030030"/>
<MappingInfo Identifier="{00000000-0010-0304-3000-040310000403}" Id="#x02030010"/>
<MappingInfo Identifier="{00000000-0020-0304-3000-040322000403}" Id="#x02030040"/>
<MappingInfo Identifier="{03040050-0050-0304-5000-040350000403}" Id="#x02030020" Watchdog="04000000040000000400000004000000"/>
</Mappings>
</TcSmProject>

View File

@@ -9,6 +9,7 @@ VAR
_fbEtcher2 : FB_Etcher;
_xFirstCycle : BOOL := TRUE;
END_VAR
]]></Declaration>
<Implementation>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="E_KukaRobot_JobNumberRobot" Id="{088c6121-55a8-439f-a5d4-6dc132a46dc5}">
<Declaration><![CDATA[{attribute 'qualified_only'}
{attribute 'strict'}
{attribute 'to_string'}
TYPE E_KukaRobot_JobNumberRobot :
(
// No job
NO_JOB := 0,
// Tray feeder input station
GET_FROM_INPUT := 10,
// Tray feeder output station
PUT_TO_OUTPUT := 11,
// Aligner station
PUT_INTO_ALIGNER := 15,
GET_FROM_ALIGNER := 16,
// Etcher 1 station
PUT_INTO_ETCHER1 := 20,
GET_FROM_ETCHER1 := 22,
GET_AND_PUT_ETCHER1 := 24,
// Etcher 2 station
PUT_INTO_ETCHER2 := 21,
GET_GROM_ETCHER2 := 23,
GET_AND_PUT_ETCHER2 := 25,
// HV test station (1 - Hot, 2 - Cold)
PUT_HV1 := 30,
GET_HV1 := 32,
GET_AND_PUT_HV1 := 34,
PUT_HV2 := 31,
GET_HV2 := 33,
GET_AND_PUT_HV2 := 35,
// Heating station
PUT_HOT_PLATE := 40,
GET_HOT_PLATE := 41,
// Cooling station
PUT_COOL_PLATE := 42,
GET_COOL_PLATE := 43,
// NIO station
PUT_INTO_NIO := 70,
GET_FROM_NIO := 71,
// Tool change robot gripper
CHANGE_GRIPPER := 50,
// Tool change etchers
GET_CHUCK_ETCHER1 := 60,
GET_CHUCK_ETCHER2 := 61,
PUT_CHUCK_ETCHER1 := 62,
PUT_CHUCK_ETCHER2 := 63,
PUT_CHUCK_INTO_MAGAZINE := 64,
GET_CHUCK_FROM_MAGAZINE := 65
) WORD := NO_JOB;
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="E_KukaRobot_JobNumerPLC" Id="{42772339-3817-41dd-ac6e-f6eea439266e}">
<Declaration><![CDATA[{attribute 'qualified_only'}
{attribute 'strict'}
{attribute 'to_string'}
TYPE E_KukaRobot_JobNumerPLC :
(
// No job
NO_JOB := 0,
// Aligner station
ENABLE_VACUUM_ALIGNER := 15,
DISABLE_VACUUM_ALIGNER := 16,
// Etcher 1 station
ENABLE_VACUUM_ETCHER1 := 20,
DISABLE_VACUUM_ETHER1 := 22,
UNLOCK_CHUCK_ETCHER1 := 60,
LOCK_CHUCK_ETCHER1 := 62,
// Ether 2 station
ENABLE_VACUUM_ETCHER2 := 21,
DISABLE_VACUUM_ETCHER2 := 23,
UNLOCK_CHUCK_ETHCER2 := 61,
LOCK_CHUCK_ETCHER2 := 63
) WORD := NO_JOB;
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -1,10 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_KukaRobot" Id="{6ca3e82a-4047-4132-872d-1f49057f08d6}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FINAL FB_KukaRobot EXTENDS FB_Isa88_SM
<Declaration><![CDATA[// Positionen in um <=> 0.001mm
FUNCTION_BLOCK FINAL FB_KukaRobot EXTENDS FB_PackMLGeneric
VAR_INPUT
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
xReady : BOOL;
xError : BOOL;
END_VAR
VAR
// 0 - Nicht aus
@@ -45,46 +49,106 @@ VAR
_asiMotorTemps1To4 AT %I* : ARRAY[0..3] OF SINT;
_asiMotorTemps5To8 AT %I* : ARRAY[0..3] OF SINT;
END_VAR
VAR CONSTANT
// Bit indices for robot interface
NOT_DISABLE_AXES : USINT := 0;
ENABLE_AXES : USINT := 1;
ENABLE_MOVE : USINT := 2;
CONF_MESS : USINT := 3;
_eRobotJob : E_KukaRobot_JobNumberRobot;
_ePlcJob :E_KukaRobot_JobNumerPLC;
// Array indices for Job interface
ROBOT_JOB : USINT := 0;
PLC_JOB_FINISHED : USINT := 1;
_xRobotReady : BOOL;
// Array indices for tools and plate positions
GRIPPER_NR : USINT := 0;
TURN_TABLE_NR : USINT := 1;
HEATING_PLATE_POS : USINT := 2;
COOLING_PLATE_POS : USINT := 3;
_xError : BOOL;
// ======
// Alarms
// ======
_fbAlarmNotInExtMode : FB_AlarmMessage(stEventEntry := TC_EVENTS.RobotEvents.RobotNotInExtMode, xWithConfirmation := FALSE);
_fbAlarmEStopActive : FB_AlarmMessage(stEventEntry := TC_EVENTS.RobotEvents.RobotEStopActive, xWithConfirmation := FALSE);
_fbAlarmOperatorSafetyNotOk : FB_AlarmMessage(stEventEntry := TC_EVENTS.RobotEvents.OperatorSafetyNotOk, xWithConfirmation := FALSE);
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Positionen in um <=> 0.001mm
<ST><![CDATA[// =============
// Handle alarms
// =============
// Zur Sicherheit im T2 Zustand die Fahrfreigabe wegnehmen (da standardpasswort bleibt)
_fbAlarmNotInExtMode(
xActive:= (NOT _uState.stState.bExt),
xRelease:= TRUE,
xAcknowledge:= xConfirmAlarms,
timOnDelay:= T#0S,
timOffDelay:= T#0S);
_fbAlarmEStopActive(
xActive:= (NOT _uState.stState.bAlarmStop),
xRelease:= TRUE,
xAcknowledge:= xConfirmAlarms,
timOnDelay:= T#0S,
timOffDelay:= T#0S);
_fbAlarmOperatorSafetyNotOk(
xActive:= (NOT _uState.stState.bUserSAF),
xRelease:= TRUE,
xAcknowledge:= xConfirmAlarms,
timOnDelay:= T#0S,
timOffDelay:= T#0S);
// =======================
// Check if robot is ready
// =======================
_xRobotReady := _uState.stState.bExt
AND _uState.stState.bAlarmStop
AND _uState.stState.bUserSAF
AND _uState.stState.bPeriRdy
AND _uState.stState.bIOActConf
AND (NOT _uState.stState.bStopMess);
// =============================
// Call isa88 base state machine
SUPER^();]]></ST>
// =============================
SUPER^();
// ==============================
// Handle general control outputs
// ==============================
// Allow robot to be moved with programming pendant
_uCtrl.stCtrl.bNotDisableAxes := 1;
// Disable move if in T2 for safety reasons
IF (NOT _uState.stState.bT2) THEN
_uCtrl.stCtrl.bEnableMove := 1;
ELSE
_uCtrl.stCtrl.bEnableMove := 0;
END_IF
// ==================
// Write job outputs
// ==================
_uJobs.stJobs.wJobNrForRobot := _eRobotJob;
_uJobs.stJobs.wFinishedJobNrFromPlc := _ePlcJob;
// =================
// Write fb outputs
// =================
xReady := _xRobotReady;
xError := _xError;]]></ST>
</Implementation>
<Method Name="M_StateIdle" Id="{025437ab-beb0-4ad6-bdc3-468dec599ff4}">
<Declaration><![CDATA[METHOD M_StateIdle
<Method Name="M_Idle" Id="{025437ab-beb0-4ad6-bdc3-468dec599ff4}">
<Declaration><![CDATA[METHOD M_Idle
]]></Declaration>
<Implementation>
<ST><![CDATA[// Allow robot to be moved with programming pendant
_uCtrl.stCtrl.bNotDisableAxes := 1;
_uCtrl.stCtrl.bEnableAxes := 1;
_uCtrl.stCtrl.bEnableMove := 1;
_uCtrl.stCtrl.bConfMess := 0;
<ST><![CDATA[_uCtrl.stCtrl.bConfMess := 0;
// Deselect all jobs and set plc finished job to none
//_awJobs[ROBOT_JOB] := 0;
//_awJobs[PLC_JOB_FINISHED] := 0;]]></ST>
_eRobotJob := E_KukaRobot_JobNumberRobot.NO_JOB;
_ePlcJob := E_KukaRobot_JobNumerPLC.NO_JOB;
]]></ST>
</Implementation>
</Method>
</POU>

View File

@@ -4,9 +4,16 @@
<Declaration><![CDATA[{attribute 'pack_mode' := '0'}
TYPE ST_KukaRobot_Ctrl :
STRUCT
// DRIVES_OFF
bNotDisableAxes : BIT;
// DRIVES_ON
bEnableAxes : BIT;
// MOVE_ENABLE
bEnableMove : BIT;
// CONF_MESS
bConfMess : BIT;
END_STRUCT
END_TYPE

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="E_Isa88_Cmd" Id="{697f242d-4f68-49dd-b08e-e24e192406b6}">
<Declaration><![CDATA[{attribute 'qualified_only'}
{attribute 'strict'}
{attribute 'to_string'}
TYPE E_Isa88_Cmd :
(
RESET := 0,
START,
PAUSE,
RESUME,
STOP,
HOLD,
RESTART,
ABORT
);
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="E_Isa88_State" Id="{67b9298d-6884-4e53-b893-d852614b96d4}">
<Declaration><![CDATA[{attribute 'qualified_only'}
{attribute 'strict'}
{attribute 'to_string'}
TYPE E_Isa88_State :
(
IDLE := 0,
RUNNING,
COMPLETE,
PAUSING,
PAUSED,
HOLDING,
HELD,
RESTARTING,
STOPPING,
STOPPED,
ABORTING,
ABORTED
);
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -1,177 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_Isa88_SM" Id="{29def7dc-7eb7-4788-94bf-20badd909417}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_Isa88_SM IMPLEMENTS I_Isa88_SM
VAR_INPUT
xExecute : BOOL;
eCMD : E_Isa88_Cmd;
END_VAR
VAR_OUTPUT
eCurrentState : E_Isa88_State;
eCurrentCMD : E_Isa88_Cmd;
END_VAR
VAR
_eState : E_Isa88_State;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[CASE _eState OF
E_Isa88_State.IDLE:
M_StateIdle();
E_Isa88_State.RUNNING:
M_StateRunning();
E_Isa88_State.COMPLETE:
M_StateComplete();
E_Isa88_State.PAUSING:
IF M_StatePausing() THEN
_eState := E_Isa88_State.PAUSED;
END_IF
E_Isa88_State.PAUSED:
M_StatePaused();
E_Isa88_State.HOLDING:
IF M_StateHolding() THEN
_eState := E_Isa88_State.HELD;
END_IF
E_Isa88_State.HELD:
M_StateHeld();
E_Isa88_State.RESTARTING:
IF M_StateRestarting() THEN
_eState := E_Isa88_State.RUNNING;
END_IF
E_Isa88_State.STOPPING:
IF M_StateStopping() THEN
_eState := E_Isa88_State.STOPPED;
END_IF
E_Isa88_State.STOPPED:
M_StateStopped();
E_Isa88_State.ABORTING:
IF M_StateAborting() THEN
_eState := E_Isa88_State.ABORTED;
END_IF
E_Isa88_State.ABORTED:
M_StateAborted();
ELSE
;
END_CASE]]></ST>
</Implementation>
<Method Name="M_StateAborted" Id="{7d3ae447-cd1c-41c4-ac16-4adbba3ca9d2}">
<Declaration><![CDATA[METHOD M_StateAborted
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_StateAborting" Id="{65c188ca-e49a-469e-8acf-15108e45afc4}">
<Declaration><![CDATA[METHOD M_StateAborting : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_StateComplete" Id="{c6f588b5-faa7-4cdb-8ef7-15b60b1b3437}">
<Declaration><![CDATA[METHOD M_StateComplete
VAR_INPUT
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_StateHeld" Id="{d3017117-19ee-4be8-a004-3bf1cb3e986c}">
<Declaration><![CDATA[METHOD M_StateHeld
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_StateHolding" Id="{aa747568-2f98-4853-8a09-082a8e71cb49}">
<Declaration><![CDATA[METHOD M_StateHolding : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_StateIdle" Id="{a1e6fb67-08b4-4452-a103-1e87b93b70df}">
<Declaration><![CDATA[METHOD M_StateIdle
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_StatePaused" Id="{e2e36464-c119-471f-8bba-3290f653d282}">
<Declaration><![CDATA[METHOD M_StatePaused
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_StatePausing" Id="{02b59ba7-54b7-4ccd-88ad-9fc49284626e}">
<Declaration><![CDATA[METHOD M_StatePausing : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_StateRestarting" Id="{b6ffa7ab-5439-47ef-8993-798aa3ec7e01}">
<Declaration><![CDATA[METHOD M_StateRestarting : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_StateRunning" Id="{e61c2773-08f6-421e-88fd-c87d0d7d7581}">
<Declaration><![CDATA[METHOD M_StateRunning
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_StateStopped" Id="{0455a3a5-4745-4cf5-8c40-69d001c1d9aa}">
<Declaration><![CDATA[METHOD M_StateStopped
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_StateStopping" Id="{e88bc558-0424-4a5f-99cd-f9d787839b47}">
<Declaration><![CDATA[METHOD M_StateStopping : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -1,78 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<Itf Name="I_Isa88_SM" Id="{40882424-4ec1-4664-8b86-b7a6af5bbb74}">
<Declaration><![CDATA[INTERFACE I_Isa88_SM
]]></Declaration>
<Method Name="M_StateAborted" Id="{e67083c3-128e-45d9-b1cc-0a35d94ac3bc}">
<Declaration><![CDATA[METHOD M_StateAborted
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_StateAborting" Id="{d3e0a947-0574-444f-878b-6e216d4fca0c}">
<Declaration><![CDATA[METHOD M_StateAborting : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_StateComplete" Id="{bef858dc-1667-4bca-9f0f-99332f97e6e2}">
<Declaration><![CDATA[METHOD M_StateComplete
VAR_INPUT
END_VAR]]></Declaration>
</Method>
<Method Name="M_StateHeld" Id="{44494e88-dd2e-4465-9ead-95d76f1444b6}">
<Declaration><![CDATA[METHOD M_StateHeld
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_StateHolding" Id="{2b2a3d8f-01ad-4938-b464-ceb50de62ddf}">
<Declaration><![CDATA[METHOD M_StateHolding : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_StateIdle" Id="{4ceced48-4f87-482f-a69a-e97b69ac8963}">
<Declaration><![CDATA[METHOD M_StateIdle
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_StatePaused" Id="{fc81aaa6-18b7-4113-914d-8d5cd632e976}">
<Declaration><![CDATA[METHOD M_StatePaused
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_StatePausing" Id="{48a7510c-d8b6-42c2-a5e4-f4ebcb66eb3b}">
<Declaration><![CDATA[METHOD M_StatePausing : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_StateRestarting" Id="{12cefe9f-48b4-4752-b95c-8ffb5612b7c4}">
<Declaration><![CDATA[METHOD M_StateRestarting : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_StateRunning" Id="{90fa6b25-1c31-4d7c-a91d-56a908196ed4}">
<Declaration><![CDATA[METHOD M_StateRunning
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_StateStopped" Id="{62d558ef-79a2-484a-a156-d8057fe6d97a}">
<Declaration><![CDATA[METHOD M_StateStopped
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_StateStopping" Id="{7ecd335a-ebd9-4170-b5b7-2f9add02b49d}">
<Declaration><![CDATA[METHOD M_StateStopping : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
</Itf>
</TcPlcObject>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="E_PackMLCmd" Id="{3ba7a228-f199-4355-be17-fd46fc967487}">
<Declaration><![CDATA[{attribute 'qualified_only'}
{attribute 'strict'}
{attribute 'to_string'}
TYPE E_PackMLCmd :
(
UNDEFINED := 0,
RESET := 1,
START := 2,
STOP := 3,
HOLD := 4,
UNHOLD := 5,
SUSPEND := 6,
UNSUSPEND := 7,
ABORT := 8,
CLEAR := 9,
COMPLETE := 10
) DINT;
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="E_PackMLState" Id="{563a2f85-ab5d-400a-a6dd-3d1839155f82}">
<Declaration><![CDATA[{attribute 'qualified_only'}
{attribute 'strict'}
{attribute 'to_string'}
TYPE E_PackMLState :
(
UNDEFINED := 0,
CLEARING := 1,
STOPPED := 2,
STARTING := 3,
IDLE := 4,
SUSPENDED := 5,
EXECUTE := 6,
STOPPING := 7,
ABORTING := 8,
ABORTED := 9,
HOLDING := 10,
HELD := 11,
UNHOLDING := 12,
SUSPENDING := 13,
UNSUSPENDING := 14,
RESETTING := 15,
COMPLETING := 16,
COMPLETE := 17
) DINT := STOPPED;
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="E_PackMLUnitMode" Id="{56f8b8e3-48e3-4607-ac73-c965d4d0058d}">
<Declaration><![CDATA[{attribute 'qualified_only'}
{attribute 'strict'}
{attribute 'to_string'}
TYPE E_PackMLUnitMode :
(
INVALID := 0,
PRODUCTION := 1,
MAINTENANCE := 2,
MANUAL := 3,
CHANGE_OVER := 4,
CLEAN := 5,
SET_UP := 6,
EMPTY_OUT := 7
) DINT := PRODUCTION;
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -0,0 +1,225 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_PackMLGeneric" Id="{f562a10e-01bc-407d-9fc0-2837d13c10b1}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_PackMLGeneric IMPLEMENTS I_UnitState
VAR_INPUT
// Mode from superior unit
eModeCmd : E_PackMLUnitMode;
// Command for new state from superior unit
eCmd : E_PackMLCmd;
END_VAR
VAR_OUTPUT
// Current mode of unit
eMode : E_PackMLUnitMode;
// Current state of unit
eState : E_PackMLState;
// xInvalidModeCmd : BOOL;
END_VAR
VAR
// State machine handler
_fbStateMachine : FB_PackMLStateMachine;
// Internal unit state
_eState : E_PackMLState;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_fbStateMachine(
eMode:= eMode,
eCmd:= eCmd,
eState=> _eState,
xError=> );
// Call state method according to current state
CASE _eState OF
E_PackMLState.CLEARING:
M_Clearing();
E_PackMLState.STOPPED:
M_Stopped();
E_PackMLState.STARTING:
M_Starting();
E_PackMLState.IDLE:
M_Idle();
E_PackMLState.SUSPENDED:
M_Suspended();
E_PackMLState.EXECUTE:
M_Execute();
E_PackMLState.STOPPING:
M_Stopping();
E_PackMLState.ABORTING:
M_Aborting();
E_PackMLState.ABORTED:
M_Aborted();
E_PackMLState.HOLDING:
M_Holding();
E_PackMLState.HELD:
M_Held();
E_PackMLState.UNHOLDING:
M_Unholding();
E_PackMLState.SUSPENDING:
M_Suspending();
E_PackMLState.UNSUSPENDING:
M_Unsuspending();
E_PackMLState.RESETTING:
M_Resetting();
E_PackMLState.COMPLETING:
M_Completing();
E_PackMLState.COMPLETE:
M_Complete();
ELSE
;
END_CASE
// Copy internal flags to output
eState := _eState;]]></ST>
</Implementation>
<Method Name="M_Aborted" Id="{db1a684f-e4e1-4d89-a3aa-9b9dfde0508c}">
<Declaration><![CDATA[METHOD M_Aborted
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Aborting" Id="{928ad614-a3a7-4c6c-b1bc-55ae54e4c95f}">
<Declaration><![CDATA[METHOD M_Aborting
]]></Declaration>
<Implementation>
<ST><![CDATA[M_StateComplete();]]></ST>
</Implementation>
</Method>
<Method Name="M_Clearing" Id="{1716cf1b-94c6-4995-8b3f-c7ebcf5727d3}">
<Declaration><![CDATA[METHOD M_Clearing
]]></Declaration>
<Implementation>
<ST><![CDATA[M_StateComplete();]]></ST>
</Implementation>
</Method>
<Method Name="M_Complete" Id="{33df5dea-d83b-48e1-8898-d7c8e1f031bd}">
<Declaration><![CDATA[METHOD M_Complete
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Completing" Id="{341608cb-1218-481f-929c-cb79602c11ab}">
<Declaration><![CDATA[METHOD M_Completing
]]></Declaration>
<Implementation>
<ST><![CDATA[M_StateComplete();]]></ST>
</Implementation>
</Method>
<Method Name="M_Execute" Id="{2a469169-0eb2-43c9-be21-48909285ee44}">
<Declaration><![CDATA[METHOD M_Execute
]]></Declaration>
<Implementation>
<ST><![CDATA[M_StateComplete();]]></ST>
</Implementation>
</Method>
<Method Name="M_Held" Id="{05b040b0-b1b9-4afd-81d0-88fc1f1a7f9b}">
<Declaration><![CDATA[METHOD M_Held
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Holding" Id="{519b03b3-2409-4b45-818f-535b3e16b22e}">
<Declaration><![CDATA[METHOD M_Holding
]]></Declaration>
<Implementation>
<ST><![CDATA[M_StateComplete();]]></ST>
</Implementation>
</Method>
<Method Name="M_Idle" Id="{aa784f5c-7adf-4c9f-a414-65b10afd2772}">
<Declaration><![CDATA[METHOD M_Idle
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Resetting" Id="{4050ed6f-edbe-4c3e-ac42-919a37a47ea9}">
<Declaration><![CDATA[METHOD M_Resetting
]]></Declaration>
<Implementation>
<ST><![CDATA[M_StateComplete();]]></ST>
</Implementation>
</Method>
<Method Name="M_Starting" Id="{0059e7f6-5f2a-40e4-9d9b-652f221495a9}">
<Declaration><![CDATA[METHOD M_Starting
]]></Declaration>
<Implementation>
<ST><![CDATA[M_StateComplete();]]></ST>
</Implementation>
</Method>
<Method Name="M_StateComplete" Id="{0cf3625e-8009-4108-a9f4-d98c991f9930}">
<Declaration><![CDATA[METHOD M_StateComplete
]]></Declaration>
<Implementation>
<ST><![CDATA[_fbStateMachine.M_StateComplete();]]></ST>
</Implementation>
</Method>
<Method Name="M_Stopped" Id="{9f8a09cf-f3be-4d60-b5e4-cd9572fae88c}">
<Declaration><![CDATA[METHOD M_Stopped
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Stopping" Id="{193565ef-cf20-428c-b726-e7c1b61375c5}">
<Declaration><![CDATA[METHOD M_Stopping
]]></Declaration>
<Implementation>
<ST><![CDATA[M_StateComplete();]]></ST>
</Implementation>
</Method>
<Method Name="M_Suspended" Id="{222c3ad7-f7d5-4773-8e98-863345472053}">
<Declaration><![CDATA[METHOD M_Suspended
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Suspending" Id="{0f5d52e2-2a54-4ea9-a0c4-7f08229c4f21}">
<Declaration><![CDATA[METHOD M_Suspending
]]></Declaration>
<Implementation>
<ST><![CDATA[M_StateComplete();]]></ST>
</Implementation>
</Method>
<Method Name="M_Unholding" Id="{662dd054-329b-4e57-ba77-486f92af795a}">
<Declaration><![CDATA[METHOD M_Unholding
]]></Declaration>
<Implementation>
<ST><![CDATA[M_StateComplete();]]></ST>
</Implementation>
</Method>
<Method Name="M_Unsuspending" Id="{80fb11c4-916a-4f8f-9cf9-b9a2d51524a1}">
<Declaration><![CDATA[METHOD M_Unsuspending
]]></Declaration>
<Implementation>
<ST><![CDATA[M_StateComplete();]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,244 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_PackMLStateMachine" Id="{784ceb84-1721-424f-89d1-422a24198e57}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_PackMLStateMachine
VAR_INPUT
eMode : E_PackMLUnitMode;
eCmd : E_PackMLCmd;
END_VAR
VAR_OUTPUT
eState : E_PackMLState;
eCurrentMode : E_PackMLUnitMode;
xError : BOOL;
END_VAR
VAR
// Internal mode
_eMode : E_PackMLUnitMode;
// Internal state
_eState : E_PackMLState;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Check for mode switch
IF eMode <> _eMode THEN
// Only allow mode switch in stopped state
// or in aborted state when target mode ist manual mode
IF (_eState = E_PackMLState.STOPPED) OR (_eState = E_PackMLState.ABORTED AND eMode = E_PackMLUnitMode.MANUAL) THEN
_eMode := eMode;
END_IF
END_IF
// Base state machine
CASE _eState OF
E_PackMLState.STOPPING:
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.STOPPED:
IF eCmd = E_PackMLCmd.RESET THEN
_eState := E_PackMLState.RESETTING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.RESETTING:
IF eCmd = E_PackMLCmd.STOP THEN
_eState := E_PackMLState.STOPPING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.IDLE:
IF eCmd = E_PackMLCmd.START THEN
_eState := E_PackMLState.STARTING;
END_IF
IF eCmd = E_PackMLCmd.STOP THEN
_eState := E_PackMLState.STOPPING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.STARTING:
IF eCmd = E_PackMLCmd.STOP THEN
_eState := E_PackMLState.STOPPING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.EXECUTE:
IF eCmd = E_PackMLCmd.SUSPEND THEN
_eState := E_PackMLState.SUSPENDING;
END_IF
IF eCmd = E_PackMLCmd.HOLD THEN
_eState := E_PackMLState.HOLDING;
END_IF
IF eCmd = E_PackMLCmd.STOP THEN
_eState := E_PackMLState.STOPPING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.SUSPENDING:
IF eCmd = E_PackMLCmd.STOP THEN
_eState := E_PackMLState.STOPPING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.SUSPENDED:
IF eCmd = E_PackMLCmd.UNSUSPEND THEN
_eState := E_PackMLState.UNSUSPENDING;
END_IF
IF eCmd = E_PackMLCmd.STOP THEN
_eState := E_PackMLState.STOPPING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.UNSUSPENDING:
IF eCmd = E_PackMLCmd.STOP THEN
_eState := E_PackMLState.STOPPING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.HOLDING:
IF eCmd = E_PackMLCmd.STOP THEN
_eState := E_PackMLState.STOPPING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.HELD:
IF eCmd = E_PackMLCmd.UNHOLD THEN
_eState := E_PackMLState.UNHOLDING;
END_IF
IF eCmd = E_PackMLCmd.STOP THEN
_eState := E_PackMLState.STOPPING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.UNHOLDING:
IF eCmd = E_PackMLCmd.STOP THEN
_eState := E_PackMLState.STOPPING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.COMPLETING:
IF eCmd = E_PackMLCmd.STOP THEN
_eState := E_PackMLState.STOPPING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.COMPLETE:
IF eCmd = E_PackMLCmd.RESET THEN
_eState := E_PackMLState.RESETTING;
END_IF
IF eCmd = E_PackMLCmd.STOP THEN
_eState := E_PackMLState.STOPPING;
END_IF
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
E_PackMLState.ABORTED:
IF eCmd = E_PackMLCmd.CLEAR THEN
_eState := E_PackMLState.CLEARING;
END_IF
E_PackMLState.CLEARING:
IF eCmd = E_PackMLCmd.ABORT THEN
_eState := E_PackMLState.ABORTING;
END_IF
ELSE
;
END_CASE
// Copy internal state value to fb output
eState := _eState;
eCurrentMode := _eMode;]]></ST>
</Implementation>
<Method Name="M_StateComplete" Id="{e2f1bae5-5059-4baa-8ba2-8dfa58d439e5}">
<Declaration><![CDATA[METHOD M_StateComplete
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[CASE _eState OF
E_PackMLState.STOPPING:
_eState := E_PackMLState.STOPPED;
E_PackMLState.RESETTING:
_eState := E_PackMLState.IDLE;
E_PackMLState.STARTING:
_eState := E_PackMLState.EXECUTE;
E_PackMLState.EXECUTE:
_eState := E_PackMLState.COMPLETING;
E_PackMLState.SUSPENDING:
_eState := E_PackMLState.SUSPENDED;
E_PackMLState.UNSUSPENDING:
_eState := E_PackMLState.EXECUTE;
E_PackMLState.HOLDING:
_eState := E_PackMLState.HELD;
E_PackMLState.UNHOLDING:
_eState := E_PackMLState.EXECUTE;
E_PackMLState.COMPLETING:
_eState := E_PackMLState.COMPLETE;
E_PackMLState.ABORTING:
_eState := E_PackMLState.ABORTED;
E_PackMLState.CLEARING:
_eState := E_PackMLState.STOPPED;
END_CASE
eState := _eState;]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<Itf Name="I_UnitState" Id="{cdb705eb-8c7b-4a1b-b75d-2d038b2142ed}">
<Declaration><![CDATA[INTERFACE I_UnitState
]]></Declaration>
<Method Name="M_Aborted" Id="{60879075-982d-46e3-879f-28a027152492}">
<Declaration><![CDATA[METHOD M_Aborted
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Aborting" Id="{a7f0b039-d3ad-461a-85a2-ba36dbff9c79}">
<Declaration><![CDATA[METHOD M_Aborting
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Clearing" Id="{6299cd97-9cf1-4270-94b0-c0bcc4e1099d}">
<Declaration><![CDATA[METHOD M_Clearing
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Complete" Id="{b3cf5b7a-9a5a-43fd-b325-d4fd150ef337}">
<Declaration><![CDATA[METHOD M_Complete
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Completing" Id="{7c1cb77d-7ca4-41f6-bf62-9389baa6ee7f}">
<Declaration><![CDATA[METHOD M_Completing
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Execute" Id="{03ab6d64-3e16-414d-9136-f9b18ea617be}">
<Declaration><![CDATA[METHOD M_Execute
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Held" Id="{68deb94e-e48b-464f-9c76-8d9ed1bf2546}">
<Declaration><![CDATA[METHOD M_Held
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Holding" Id="{559633b5-914c-40d3-8d33-7376565527fb}">
<Declaration><![CDATA[METHOD M_Holding
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Idle" Id="{67e5973f-2505-422d-bb50-93ce0b57a267}">
<Declaration><![CDATA[METHOD M_Idle
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Resetting" Id="{d1009681-05ba-46d8-97a6-e3edaa95ef55}">
<Declaration><![CDATA[METHOD M_Resetting
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Starting" Id="{a747e482-f90e-45e5-98dc-79e29c5eb846}">
<Declaration><![CDATA[METHOD M_Starting
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Stopped" Id="{4639d90c-8eac-499e-a39a-e21317512d84}">
<Declaration><![CDATA[METHOD M_Stopped
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Stopping" Id="{81d1ced0-30b6-4a0e-b4f0-f2f5159fb0a2}">
<Declaration><![CDATA[METHOD M_Stopping
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Suspended" Id="{d84aeac6-2d41-4eb9-bcab-6c5cf55f051b}">
<Declaration><![CDATA[METHOD M_Suspended
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Suspending" Id="{74fa6a0f-a468-4665-8e53-35af4d69eb0e}">
<Declaration><![CDATA[METHOD M_Suspending
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Unholding" Id="{2cbdd1fc-df75-4e65-b402-0f80d7393bf2}">
<Declaration><![CDATA[METHOD M_Unholding
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Unsuspending" Id="{b50ba50d-d8d9-4340-8bf8-95a965e5f0da}">
<Declaration><![CDATA[METHOD M_Unsuspending
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
</Itf>
</TcPlcObject>

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<Itf Name="I_UnitStateActing" Id="{c702df5f-1a22-4aea-b488-0fb9e9d6d715}">
<Declaration><![CDATA[INTERFACE I_UnitStateActing
]]></Declaration>
<Method Name="M_Aborting" Id="{7c2f68db-46da-431c-ae3a-645172f1883b}">
<Declaration><![CDATA[METHOD M_Aborting
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Clearing" Id="{9d54d966-edc5-4f21-bd4e-93594fa24900}">
<Declaration><![CDATA[METHOD M_Clearing
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Completing" Id="{58605d4f-0a0c-4fdd-9d50-28facf47e281}">
<Declaration><![CDATA[METHOD M_Completing
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Execute" Id="{ab83a18f-a5bc-4b8f-b1f3-7186449d2761}">
<Declaration><![CDATA[METHOD M_Execute
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Holding" Id="{75e803d4-1308-483e-b7e2-17e7d4b226d0}">
<Declaration><![CDATA[METHOD M_Holding
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Resetting" Id="{0e18ccba-b77b-4b73-8769-7ee43b60219b}">
<Declaration><![CDATA[METHOD M_Resetting
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Starting" Id="{58fc3d45-f33e-4dd2-bcd8-33e9912df38b}">
<Declaration><![CDATA[METHOD M_Starting
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Stopping" Id="{2552a9a7-c44e-4a0f-b543-d0ead71abcad}">
<Declaration><![CDATA[METHOD M_Stopping
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Suspending" Id="{4a4db317-bf30-420e-8759-cbe6735e3cbf}">
<Declaration><![CDATA[METHOD M_Suspending
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Unholding" Id="{0552e45c-941b-4643-88d7-3142a7e014c8}">
<Declaration><![CDATA[METHOD M_Unholding
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Unsuspending" Id="{9b9d5dbc-614c-4f59-9357-18a6be86205d}">
<Declaration><![CDATA[METHOD M_Unsuspending
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
</Itf>
</TcPlcObject>

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<Itf Name="I_UnitStateWaiting" Id="{39625219-05f8-4347-91c2-8778ac2bbe52}">
<Declaration><![CDATA[INTERFACE I_UnitStateWaiting
]]></Declaration>
<Method Name="M_Aborted" Id="{e9883017-eee3-45b6-a539-97564bed85bd}">
<Declaration><![CDATA[METHOD M_Aborted
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Complete" Id="{e5ea1a66-0ad7-44f0-8155-f8f6e9fb0869}">
<Declaration><![CDATA[METHOD M_Complete
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Held" Id="{22f78e55-8e74-4d03-b949-ddbec289c616}">
<Declaration><![CDATA[METHOD M_Held
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Idle" Id="{a4192dfa-4513-4296-9d67-360bb2fdd051}">
<Declaration><![CDATA[METHOD M_Idle
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Stopped" Id="{8609190c-90f0-46f9-b5b0-5dddabdfa3b1}">
<Declaration><![CDATA[METHOD M_Stopped
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
<Method Name="M_Suspended" Id="{eeb60c98-c52b-43d3-9d93-2abce6744a61}">
<Declaration><![CDATA[METHOD M_Suspended
VAR_INPUT
END_VAR
]]></Declaration>
</Method>
</Itf>
</TcPlcObject>

View File

@@ -0,0 +1,569 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_PackMLStateMachine_Test" Id="{6fbfd066-a6ec-4393-8e2f-9c56726e94be}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_PackMLStateMachine_Test EXTENDS FB_TestSuite
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Normal commands
M_InitialState();
M_StoppedToIdle();
M_IdleToExecute();
M_HoldUnholdCycle();
M_SuspendUnsuspendCycle();
M_ExecuteToComplete();
M_ResetFromComplete();
// Full cycle
M_FullProductionCycle();
// Stop tests
M_StopFromIdle();
M_StopFromExecute();
M_StopFromComplete();
// Abort tests
M_AbortFromExecute();
M_AbortDuringStarting();
M_AbortDuringHolding();
M_AbortDuringClearing();
// Clearing
M_ClearFromAborted();
// Mode switching
M_ModeSwitchInStopped();
M_ModeSwitchNotAllowedInIdle();
M_ModeSwitchAbortedToManual();
M_ModeSwitchAbortedToNonManualNotAllowed();
]]></ST>
</Implementation>
<Method Name="M_AbortDuringClearing" Id="{35f8c603-4e33-4f68-9e15-218d78d5c03b}">
<Declaration><![CDATA[METHOD M_AbortDuringClearing
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('AbortDuringClearing');
// Setup: Get to CLEARING
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.ABORT);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.CLEAR);
AssertEquals_DINT(E_PackMLState.CLEARING, fbPackML.eState, 'Setup: Should be CLEARING');
// Test ABORT during CLEARING
fbPackML(eCmd := E_PackMLCmd.ABORT);
AssertEquals_DINT(E_PackMLState.ABORTING, fbPackML.eState, 'Should abort from CLEARING');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_AbortDuringHolding" Id="{aaa6bed5-41ed-40eb-8168-11c14ad58832}">
<Declaration><![CDATA[METHOD M_AbortDuringHolding
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('AbortDuringHolding');
// Setup: Get to HOLDING
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.HOLD);
AssertEquals_DINT(E_PackMLState.HOLDING, fbPackML.eState, 'Setup: Should be HOLDING');
// Test ABORT during HOLDING
fbPackML(eCmd := E_PackMLCmd.ABORT);
AssertEquals_DINT(E_PackMLState.ABORTING, fbPackML.eState, 'Should abort from HOLDING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.ABORTED, fbPackML.eState, 'Should reach ABORTED');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_AbortDuringStarting" Id="{fbb52ff0-3ecb-4984-be10-32efaf2d1f2b}">
<Declaration><![CDATA[METHOD M_AbortDuringStarting
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('AbortDuringStarting');
// Setup: Get to STARTING
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
AssertEquals_DINT(E_PackMLState.STARTING, fbPackML.eState, 'Setup: Should be STARTING');
// Test ABORT during STARTING
fbPackML(eCmd := E_PackMLCmd.ABORT);
AssertEquals_DINT(E_PackMLState.ABORTING, fbPackML.eState, 'Should abort from STARTING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.ABORTED, fbPackML.eState, 'Should reach ABORTED');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_AbortFromExecute" Id="{6eaecb2f-7c92-492a-8635-8d91354de462}">
<Declaration><![CDATA[METHOD M_AbortFromExecute
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('AbortFromExecute');
// Setup: Get to EXECUTE
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
// Test ABORT
fbPackML(eCmd := E_PackMLCmd.ABORT);
AssertEquals_DINT(E_PackMLState.ABORTING, fbPackML.eState, 'Should transition to ABORTING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.ABORTED, fbPackML.eState, 'Should transition to ABORTED');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_ClearFromAborted" Id="{672532be-23ab-4162-bb1f-60f23d043e3f}">
<Declaration><![CDATA[METHOD M_ClearFromAborted
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('ClearFromAborted');
// Setup: Get to ABORTED
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.ABORT);
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.ABORTED, fbPackML.eState, 'Setup: Should be ABORTED');
// Test CLEAR
fbPackML(eCmd := E_PackMLCmd.CLEAR);
AssertEquals_DINT(E_PackMLState.CLEARING, fbPackML.eState, 'Should transition to CLEARING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.STOPPED, fbPackML.eState, 'Should transition to STOPPED');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_ExecuteToComplete" Id="{d180915d-5230-4918-a72f-7d7b60cb333e}">
<Declaration><![CDATA[METHOD M_ExecuteToComplete
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('ExecuteToComplete');
// Setup: Get to EXECUTE
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.EXECUTE, fbPackML.eState, 'Setup: Should be in EXECUTE');
// Test completion
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.COMPLETING, fbPackML.eState, 'Should transition to COMPLETING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.COMPLETE, fbPackML.eState, 'Should transition to COMPLETE');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_FullProductionCycle" Id="{e11b3300-6857-4b29-8000-595d07539eed}">
<Declaration><![CDATA[METHOD M_FullProductionCycle
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('FullProductionCycle');
// STOPPED -> RESETTING -> IDLE
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.IDLE, fbPackML.eState, 'Should reach IDLE');
// IDLE -> STARTING -> EXECUTE
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.EXECUTE, fbPackML.eState, 'Should reach EXECUTE');
// EXECUTE -> COMPLETING -> COMPLETE
fbPackML.M_StateComplete();
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.COMPLETE, fbPackML.eState, 'Should reach COMPLETE');
// COMPLETE -> RESETTING -> IDLE
fbPackML(eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.IDLE, fbPackML.eState, 'Should return to IDLE');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_HoldUnholdCycle" Id="{01b950b4-a901-4c0f-8993-5e8c46b75e11}">
<Declaration><![CDATA[METHOD M_HoldUnholdCycle
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('HoldUnholdCycle');
// Setup: Get to EXECUTE
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
// Test HOLD
fbPackML(eCmd := E_PackMLCmd.HOLD);
AssertEquals_DINT(E_PackMLState.HOLDING, fbPackML.eState, 'Should transition to HOLDING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.HELD, fbPackML.eState, 'Should transition to HELD');
// Test UNHOLD
fbPackML(eCmd := E_PackMLCmd.UNHOLD);
AssertEquals_DINT(E_PackMLState.UNHOLDING, fbPackML.eState, 'Should transition to UNHOLDING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.EXECUTE, fbPackML.eState, 'Should return to EXECUTE');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_IdleToExecute" Id="{e39d1646-a140-445b-a77a-a4b3ecb6a68b}">
<Declaration><![CDATA[METHOD M_IdleToExecute
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('IdleToExecute');
// Setup: Get to IDLE
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.IDLE, fbPackML.eState, 'Setup: Should be IDLE');
// Test START command
fbPackML(eCmd := E_PackMLCmd.START);
AssertEquals_DINT(E_PackMLState.STARTING, fbPackML.eState, 'Should transition to STARTING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.EXECUTE, fbPackML.eState, 'Should transition to EXECUTE');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_InitialState" Id="{abbdf72f-ef98-4943-bd47-30822864724d}">
<Declaration><![CDATA[METHOD M_InitialState
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('InitialState');
AssertEquals_DINT(
Expected := E_PackMLState.STOPPED,
Actual := fbPackML.eState,
Message := 'Initial state should be STOPPED'
);
AssertEquals_DINT(
Expected := E_PackMLUnitMode.PRODUCTION,
Actual := fbPackML.eCurrentMode,
Message := 'Initial mode should be PRODUCTION'
);
AssertFalse(
Condition := fbPackML.xError,
Message := 'No error should be present initially'
);
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_ModeSwitchAbortedToManual" Id="{16d80727-dea0-4822-8ac2-bb785dfb8fd9}">
<Declaration><![CDATA[METHOD M_ModeSwitchAbortedToManual
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('ModeSwitchAbortedToManual');
// Setup: Get to ABORTED in PRODUCTION mode
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.ABORT);
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.ABORTED, fbPackML.eState, 'Setup: Should be ABORTED');
AssertEquals_DINT(E_PackMLUnitMode.PRODUCTION, fbPackML.eCurrentMode, 'Mode should be PRODUCTION');
// Switch to MANUAL mode - should be allowed
fbPackML(eMode := E_PackMLUnitMode.MANUAL);
AssertEquals_DINT(E_PackMLUnitMode.MANUAL, fbPackML.eCurrentMode, 'Mode should switch to MANUAL');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_ModeSwitchAbortedToNonManualNotAllowed" Id="{814f1869-6786-43ba-944f-eec48a900610}">
<Declaration><![CDATA[METHOD M_ModeSwitchAbortedToNonManualNotAllowed : REFERENCE TO FB_Test
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('ModeSwitchAbortedToNonManualNotAllowed');
// Setup: Get to ABORTED in PRODUCTION mode
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.ABORT);
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.ABORTED, fbPackML.eState, 'Setup: Should be ABORTED');
// Try to switch to MAINTENANCE - should be rejected
fbPackML(eMode := E_PackMLUnitMode.MAINTENANCE);
AssertEquals_DINT(E_PackMLUnitMode.PRODUCTION, fbPackML.eCurrentMode, 'Mode should remain PRODUCTION');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_ModeSwitchInStopped" Id="{438c169a-3232-4ff5-8d39-6d4748bb8e0c}">
<Declaration><![CDATA[METHOD M_ModeSwitchInStopped
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('ModeSwitchInStopped');
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION);
AssertEquals_DINT(E_PackMLState.STOPPED, fbPackML.eState, 'Should be in STOPPED');
AssertEquals_DINT(E_PackMLUnitMode.PRODUCTION, fbPackML.eCurrentMode, 'Mode should be PRODUCTION');
// Mode switch should be accepted
fbPackML(eMode := E_PackMLUnitMode.MAINTENANCE);
AssertEquals_DINT(E_PackMLUnitMode.MAINTENANCE, fbPackML.eCurrentMode, 'Mode should switch to MAINTENANCE');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_ModeSwitchNotAllowedInIdle" Id="{a1275023-bc44-4cde-b6cb-9ba394083234}">
<Declaration><![CDATA[METHOD M_ModeSwitchNotAllowedInIdle
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('ModeSwitchNotAllowedInIdle');
// Setup: Get to IDLE in PRODUCTION mode
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.IDLE, fbPackML.eState, 'Setup: Should be in IDLE');
AssertEquals_DINT(E_PackMLUnitMode.PRODUCTION, fbPackML.eCurrentMode, 'Mode should be PRODUCTION');
// Try to switch mode - should be rejected
fbPackML(eMode := E_PackMLUnitMode.MANUAL);
AssertEquals_DINT(E_PackMLUnitMode.PRODUCTION, fbPackML.eCurrentMode, 'Mode should remain PRODUCTION');
AssertEquals_DINT(E_PackMLState.IDLE, fbPackML.eState, 'Should remain in IDLE');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_ResetFromComplete" Id="{cbdb2a33-12a7-489c-a968-e416c0488e4f}">
<Declaration><![CDATA[METHOD M_ResetFromComplete
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('ResetFromComplete');
// Setup: Get to COMPLETE
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
fbPackML.M_StateComplete();
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.COMPLETE, fbPackML.eState, 'Setup: Should be COMPLETE');
// Test RESET from COMPLETE
fbPackML(eCmd := E_PackMLCmd.RESET);
AssertEquals_DINT(E_PackMLState.RESETTING, fbPackML.eState, 'Should transition to RESETTING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.IDLE, fbPackML.eState, 'Should transition to IDLE');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_StopFromComplete" Id="{6f2c0387-41ef-426f-869c-ddae93a70046}">
<Declaration><![CDATA[METHOD M_StopFromComplete
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('StopFromComplete');
// Setup: Get to COMPLETE
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
fbPackML.M_StateComplete();
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.COMPLETE, fbPackML.eState, 'Setup: Should be COMPLETE');
// Test STOP from COMPLETE
fbPackML(eCmd := E_PackMLCmd.STOP);
AssertEquals_DINT(E_PackMLState.STOPPING, fbPackML.eState, 'Should transition to STOPPING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.STOPPED, fbPackML.eState, 'Should transition to STOPPED');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_StopFromExecute" Id="{2399ead6-3273-4524-990f-02be84126c6a}">
<Declaration><![CDATA[METHOD M_StopFromExecute
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('StopFromExecute');
// Setup: Get to EXECUTE
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
// Test STOP from EXECUTE
fbPackML(eCmd := E_PackMLCmd.STOP);
AssertEquals_DINT(E_PackMLState.STOPPING, fbPackML.eState, 'Should transition to STOPPING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.STOPPED, fbPackML.eState, 'Should transition to STOPPED');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_StopFromIdle" Id="{15984370-8f4c-4823-af08-97c9f70546cd}">
<Declaration><![CDATA[METHOD M_StopFromIdle
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('StopFromIdle');
// Setup: Get to IDLE
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
// Test STOP from IDLE
fbPackML(eCmd := E_PackMLCmd.STOP);
AssertEquals_DINT(E_PackMLState.STOPPING, fbPackML.eState, 'Should transition to STOPPING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.STOPPED, fbPackML.eState, 'Should transition to STOPPED');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_StoppedToIdle" Id="{4e29286e-7cd6-4d2e-89db-08104750a1c6}">
<Declaration><![CDATA[METHOD M_StoppedToIdle
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('StoppedToIdle');
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION);
AssertEquals_DINT(E_PackMLState.STOPPED, fbPackML.eState, 'Should be in STOPPED');
fbPackML(eCmd := E_PackMLCmd.RESET);
AssertEquals_DINT(E_PackMLState.RESETTING, fbPackML.eState, 'Should transition to RESETTING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.IDLE, fbPackML.eState, 'Should transition to IDLE');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
<Method Name="M_SuspendUnsuspendCycle" Id="{78311aa6-53b9-4c6e-8c1c-a43729a514d1}">
<Declaration><![CDATA[METHOD M_SuspendUnsuspendCycle
VAR
fbPackML : FB_PackMLStateMachine;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TEST('SuspendUnsuspendCycle');
// Setup: Get to EXECUTE
fbPackML(eMode := E_PackMLUnitMode.PRODUCTION, eCmd := E_PackMLCmd.RESET);
fbPackML.M_StateComplete();
fbPackML(eCmd := E_PackMLCmd.START);
fbPackML.M_StateComplete();
// Test SUSPEND
fbPackML(eCmd := E_PackMLCmd.SUSPEND);
AssertEquals_DINT(E_PackMLState.SUSPENDING, fbPackML.eState, 'Should transition to SUSPENDING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.SUSPENDED, fbPackML.eState, 'Should transition to SUSPENDED');
// Test UNSUSPEND
fbPackML(eCmd := E_PackMLCmd.UNSUSPEND);
AssertEquals_DINT(E_PackMLState.UNSUSPENDING, fbPackML.eState, 'Should transition to UNSUSPENDING');
fbPackML.M_StateComplete();
AssertEquals_DINT(E_PackMLState.EXECUTE, fbPackML.eState, 'Should return to EXECUTE');
TEST_FINISHED();]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="PRG_Test" Id="{f876543c-d362-446e-a091-152833fd4557}" SpecialFunc="None">
<Declaration><![CDATA[PROGRAM PRG_Test
VAR
_fbPackMLStateMachine_Test : FB_PackMLStateMachine_Test;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TcUnit.RUN();]]></ST>
</Implementation>
</POU>
</TcPlcObject>

View File

@@ -33,6 +33,12 @@
<Compile Include="01_Stationen\HVTester\FB_HVTester.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\Kuka_Robot\E_KukaRobot_JobNumberRobot.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\Kuka_Robot\E_KukaRobot_JobNumerPLC.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\Kuka_Robot\FB_KukaRobot.TcPOU">
<SubType>Code</SubType>
</Compile>
@@ -64,16 +70,34 @@
<SubType>Code</SubType>
<LinkAlways>true</LinkAlways>
</Compile>
<Compile Include="LibraryCandidates\ISA88\E_Isa88_Cmd.TcDUT">
<Compile Include="LibraryCandidates\PackML\E_PackMLCmd.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="LibraryCandidates\ISA88\E_Isa88_State.TcDUT">
<Compile Include="LibraryCandidates\PackML\E_PackMLState.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="LibraryCandidates\ISA88\FB_Isa88_SM.TcPOU">
<Compile Include="LibraryCandidates\PackML\E_PackMLUnitMode.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="LibraryCandidates\ISA88\I_Isa88_SM.TcIO">
<Compile Include="LibraryCandidates\PackML\FB_PackMLGeneric.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="LibraryCandidates\PackML\FB_PackMLStateMachine.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="LibraryCandidates\PackML\ITFs\I_UnitState.TcIO">
<SubType>Code</SubType>
</Compile>
<Compile Include="LibraryCandidates\PackML\ITFs\I_UnitStateActing.TcIO">
<SubType>Code</SubType>
</Compile>
<Compile Include="LibraryCandidates\PackML\ITFs\I_UnitStateWaiting.TcIO">
<SubType>Code</SubType>
</Compile>
<Compile Include="LibraryCandidates\Unittests\FB_PackMLStateMachine_Test.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="LibraryCandidates\Unittests\PRG_Test.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="PlcTask.TcTTO">
@@ -97,11 +121,17 @@
<Folder Include="01_Stationen" />
<Folder Include="00_Main" />
<Folder Include="LibraryCandidates" />
<Folder Include="LibraryCandidates\ISA88" />
<Folder Include="GVLs" />
<Folder Include="LibraryCandidates\Unittests" />
<Folder Include="LibraryCandidates\PackML" />
<Folder Include="LibraryCandidates\PackML\ITFs" />
<Folder Include="Visu" />
</ItemGroup>
<ItemGroup>
<PlaceholderReference Include="BaseComponents">
<DefaultResolution>BaseComponents, * (Heisig GmbH)</DefaultResolution>
<Namespace>BC</Namespace>
</PlaceholderReference>
<PlaceholderReference Include="System_VisuElemMeter">
<DefaultResolution>VisuElemMeter, 4.7.0.0 (System)</DefaultResolution>
<Namespace>VisuElemMeter</Namespace>
@@ -161,6 +191,10 @@
<Namespace>Tc3_Module</Namespace>
<SystemLibrary>true</SystemLibrary>
</PlaceholderReference>
<PlaceholderReference Include="TcUnit">
<DefaultResolution>TcUnit, * (www.tcunit.org)</DefaultResolution>
<Namespace>TcUnit</Namespace>
</PlaceholderReference>
</ItemGroup>
<ItemGroup>
<None Include="PLC.tmc">

View File

@@ -5,7 +5,7 @@
<CycleTime>10000</CycleTime>
<Priority>20</Priority>
<PouCall>
<Name>PRG_Main</Name>
<Name>PRG_Test</Name>
</PouCall>
<TaskFBGuid>{40eb18ee-d47c-458f-bba5-88b899fc1567}</TaskFBGuid>
<Fb_init>{6e3535be-c313-4e44-9f98-4268a560c4bf}</Fb_init>

View File

@@ -544,7 +544,7 @@
<ImageData Id="1020">424de6000000000000007600000028000000100000000e000000010004000000000070000000000000000000000010000000000000001c120800244aa500203262002462ee001c273f00245ad500243a7c001c222b001c1a1e002472fc00244fb7001c2a4d00243a7100246afc0024428d001c1a1300d5bbbbbbedddddddddb8777fcdd9dd9dd580ffffcddddddd9e7780f47b5dd9ddd3d35cb700e9ddd9ddd9d9de88a9ddddd9dddd9abb3dddddddddd99e04d9dd9dddddddd20adddddd9dd9d958b9ddd9ddddddd18cddddddd9dd5554e99d999d1dd9b07b2ee111e1add5bb777774bb6add</ImageData>
<ImageData Id="1021">424de6000000000000007600000028000000100000000e000000010004000000000070000000000000000000000000000000000000000000000000008000008000000080800080000000800080008080000080808000c0c0c0000000ff0000ff000000ffff00ff000000ff00ff00ffff0000ffffff00bb1111113bbbbbbbbb1000001bbbbbbbbb0000001bbbbbbbb300000001bbbbbbbbbbb110003bbbbbbbbbbbb3003bbbbbbbbbbbb311bbbbbbbbbbbbb300bbbbbbbbbbbbb103bbbbbbbbbbbbb01bbbbbbbbbbbb301bbbbbbbbbbbbb03bbbbbbb3bbb1001133333333bb3110000001113bb</ImageData>
</ImageDatas>
<Device Id="1" DevType="111" DevFlags="#x0003" AmsPort="28673" AmsNetId="0.0.0.0.2.1" RemoteName="Device 1 (EtherCAT)" InfoImageId="2">
<Device Id="1" Disabled="true" DevType="111" DevFlags="#x0003" AmsPort="28673" AmsNetId="0.0.0.0.2.1" RemoteName="Device 1 (EtherCAT)" InfoImageId="2">
<Name>__FILENAME__</Name>
<AddressInfo>
<Pnp>
@@ -556,9 +556,6 @@
<Image Id="1" AddrType="9" ImageType="3">
<Name>Image</Name>
</Image>
<Image Id="5" AddrType="10" ImageType="3">
<Name>Prozessabbild-2</Name>
</Image>
<Box Id="24" BoxType="9099">
<Name>Etcher1ChuckPresent (EP1018-0001)</Name>
<ImageId>1000</ImageId>
@@ -35040,19 +35037,19 @@ Bit 8 - 15 : reserved]]></Comment>
<Var>
<Name>HEAD</Name>
<Type GUID="{D46F6451-58CF-4853-A5DB-DA36D1D59A28}" Namespace="IO">ECAT_HEAD</Type>
<BitOffs>1184</BitOffs>
<BitOffs>12416</BitOffs>
</Var>
<Var>
<Name>DATA</Name>
<Type GUID="{18071995-0000-0000-0000-001300000200}">ARRAY [0..511] OF BYTE</Type>
<BitOffs>1264</BitOffs>
<BitOffs>12496</BitOffs>
</Var>
<Var>
<Name>CNT</Name>
<Comment><![CDATA[Working counter
After receiving]]></Comment>
<Type>UINT</Type>
<BitOffs>5360</BitOffs>
<BitOffs>16592</BitOffs>
</Var>
</Vars>
<Vars VarGrpType="2">
@@ -35060,19 +35057,19 @@ After receiving]]></Comment>
<Var>
<Name>HEAD</Name>
<Type GUID="{D46F6451-58CF-4853-A5DB-DA36D1D59A28}" Namespace="IO">ECAT_HEAD</Type>
<BitOffs>1184</BitOffs>
<BitOffs>12416</BitOffs>
</Var>
<Var>
<Name>DATA</Name>
<Type GUID="{18071995-0000-0000-0000-001300000200}">ARRAY [0..511] OF BYTE</Type>
<BitOffs>1264</BitOffs>
<BitOffs>12496</BitOffs>
</Var>
<Var>
<Name>CNT</Name>
<Comment><![CDATA[Working counter
Before sending]]></Comment>
<Type>UINT</Type>
<BitOffs>5360</BitOffs>
<BitOffs>16592</BitOffs>
</Var>
</Vars>
</EtherCATCmd>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<TcSmItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.beckhoff.com/schemas/2012/07/TcSmProject" TcSmVersion="1.0" TcVersion="3.1.4026.19" ClassName="CDevDpRamDef" SubType="121">
<Device Id="11" DevType="121">
<Device Id="11" Disabled="true" DevType="121">
<Name>__FILENAME__</Name>
<AddressInfo>
<Pci>

View File

@@ -18,55 +18,4 @@
<TaskPouOid Prio="20" OTCID="#x08502001"/>
</TaskPouOids>
</Instance>
<Mappings>
<OwnerA>
<OwnerB Name="TIID^Device 1 (EtherCAT)^Box 44 (EX260-SEC1)">
<Link VarA="PlcTask Outputs^PRG_Main._fbHVTester._xCloseDoor1" VarB="Byte 0^Output[3]" Size="1"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbHVTester._xCloseDoor2" VarB="Byte 0^Output[1]" Size="1"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbHVTester._xOpenDoor1" VarB="Byte 0^Output[2]" Size="1"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbHVTester._xOpenDoor2" VarB="Byte 0^Output[0]" Size="1"/>
</OwnerB>
<OwnerB Name="TIID^Device 1 (EtherCAT)^HV_K01_KL01^HV_K01_KL07 (EL2008)">
<Link VarA="PlcTask Outputs^PRG_Main._fbHVTester._xCloseChamber1" VarB="Channel 6^HV Hot_CloseChamber" Size="1"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbHVTester._xCloseChamber2" VarB="Channel 3^HV Cold_CloseChamber" Size="1"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbHVTester._xOpenChamber1" VarB="Channel 5^HV Hot_OpenChamber" Size="1"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbHVTester._xOpenChamber2" VarB="Channel 2^HV Cold_OpenChamber" Size="1"/>
</OwnerB>
<OwnerB Name="TIID^Device 1 (EtherCAT)^K01_KL01 (EK1100)^K01_KL02 (EL1018)">
<Link VarA="PlcTask Inputs^PRG_Safety._xRequestOpenDoor" VarB="Channel 4^MainDoorUnlock" Size="1"/>
</OwnerB>
<OwnerB Name="TIID^Device 1 (EtherCAT)^K20_QM01 (EX260-SEC1)">
<Link VarA="PlcTask Outputs^PRG_Main._fbEtcher2._xCloseDoor" VarB="Byte 0^Output[1]" Size="1"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbEtcher2._xOpenDoor" VarB="Byte 0^Output[0]" Size="1"/>
</OwnerB>
<OwnerB Name="TIID^Device 1 (EtherCAT)^K21_QM01 (EX260-SEC1)">
<Link VarA="PlcTask Outputs^PRG_Main._fbEtcher1._xCloseDoor" VarB="Byte 0^Output[1]" Size="1"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbEtcher1._xOpenDoor" VarB="Byte 0^Output[0]" Size="1"/>
</OwnerB>
<OwnerB Name="TIID^Device 1 (EtherCAT)^PC_K01_KL01 (EK1100)^PC_K01_KL02 (EL1918)">
<Link VarA="PlcTask Inputs^PRG_Safety._xComStartup" VarB="StandardInputs^Standard Out Var 12" Size="1"/>
<Link VarA="PlcTask Outputs^PRG_Safety._xErrorAck" VarB="StandardOutputs^Standard In Var 212" Size="1"/>
<Link VarA="PlcTask Outputs^PRG_Safety._xLockDoor" VarB="StandardOutputs^Standard In Var 192" Size="1"/>
<Link VarA="PlcTask Outputs^PRG_Safety._xRun" VarB="StandardOutputs^Standard In Var 9" Size="1"/>
</OwnerB>
<OwnerB Name="TIID^Device 1 (EtherCAT)^RobotMain">
<Link VarA="PlcTask Inputs^PRG_Main._fbRobot._abMirrorToolsAndPositions" VarB="Module 3 (Default IO)^Std. In (64 Bytes)^Input DWORD 4 (Greifer/Drehteller/Positionen)"/>
<Link VarA="PlcTask Inputs^PRG_Main._fbRobot._asiMotorTemps1To4" VarB="Module 3 (Default IO)^Std. In (64 Bytes)^Input DWORD 8 (Motor Temp)"/>
<Link VarA="PlcTask Inputs^PRG_Main._fbRobot._asiMotorTemps5To8" VarB="Module 3 (Default IO)^Std. In (64 Bytes)^Input DWORD 9 (Motor Temp)"/>
<Link VarA="PlcTask Inputs^PRG_Main._fbRobot._awJobStatesFromRobot" VarB="Module 3 (Default IO)^Std. In (64 Bytes)^Input DWORD 2 (JobAktiv/JobEnde)"/>
<Link VarA="PlcTask Inputs^PRG_Main._fbRobot._diMirrorOffsetPosX" VarB="Module 3 (Default IO)^Std. In (64 Bytes)^Input DWORD 5 (Offset X)"/>
<Link VarA="PlcTask Inputs^PRG_Main._fbRobot._diMirrorOffsetPosY" VarB="Module 3 (Default IO)^Std. In (64 Bytes)^Input DWORD 6 (Offset Y)"/>
<Link VarA="PlcTask Inputs^PRG_Main._fbRobot._diMirrorThickness" VarB="Module 3 (Default IO)^Std. In (64 Bytes)^Input DWORD 7 (Thickness)"/>
<Link VarA="PlcTask Inputs^PRG_Main._fbRobot._dwErrorBits" VarB="Module 3 (Default IO)^Std. In (64 Bytes)^Input DWORD 1 (Errorbits)"/>
<Link VarA="PlcTask Inputs^PRG_Main._fbRobot._dwJobForPLC" VarB="Module 3 (Default IO)^Std. In (64 Bytes)^Input DWORD 3 (JobForPLC)"/>
<Link VarA="PlcTask Inputs^PRG_Main._fbRobot._uState^dwState" VarB="Module 3 (Default IO)^Std. In (64 Bytes)^Input DWORD 0 (Status)"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbRobot._abToolsAndPositions" VarB="Module 3 (Default IO)^Std. Out (64 Bytes)^Output DWORD 2 (Greifer/Drehteller/Positionen)"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbRobot._diOffsetPosX" VarB="Module 3 (Default IO)^Std. Out (64 Bytes)^Output DWORD 3 (Offset X)"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbRobot._diOffsetPosY" VarB="Module 3 (Default IO)^Std. Out (64 Bytes)^Output DWORD 4 (Offset Y)"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbRobot._diThickness" VarB="Module 3 (Default IO)^Std. Out (64 Bytes)^ Output DWORD 5 (Thickness)"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbRobot._uCtrl^dwCtrl" VarB="Module 3 (Default IO)^Std. Out (64 Bytes)^Output DWORD 0 (CMDs)"/>
<Link VarA="PlcTask Outputs^PRG_Main._fbRobot._uJobs^dwJobs" VarB="Module 3 (Default IO)^Std. Out (64 Bytes)^Output DWORD 1 (JobNr/PLCJobNr)"/>
</OwnerB>
</OwnerA>
</Mappings>
</TcSmItem>