First version Tray Feeder ready for test

- Tray feeder implementation ready for first tests
- Some refactoring of packml function names
- Added .xtv file to project again because of linking issues
- Added hmi button for packml complete command
- Started media cabinet
This commit is contained in:
2026-03-03 14:11:58 +01:00
parent dbfa6fc7cc
commit 0ea0887bb4
17 changed files with 4430 additions and 486 deletions

View File

@@ -174,7 +174,7 @@ END_VAR]]></Declaration>
IF stRobotInputs.stSafetyStatus.bEstop_Resettable THEN
_iSSM := 10;
ELSE
_eCmd := E_PackMLCmd.ABORT;
M_CmdAbort();
END_IF
ELSE
// Go to activate state
@@ -198,7 +198,7 @@ END_VAR]]></Declaration>
IF _tonTimer.Q THEN
_tonTimer(IN := FALSE);
// TODO trigger error message
_eCmd := E_PackMLCmd.ABORT;
M_CmdAbort();
END_IF
IF (NOT stRobotInputs.stSafetyStatus.bEstop) THEN
@@ -229,7 +229,7 @@ END_VAR]]></Declaration>
_tonTimer(IN := FALSE);
stRobotOutputs.stRobotControl.bActivate := FALSE;
// TODO trigger error message
_eCmd := E_PackMLCmd.ABORT;
M_CmdAbort();
END_IF
// Check homing
@@ -254,7 +254,7 @@ END_VAR]]></Declaration>
_tonTimer(IN := FALSE);
stRobotOutputs.stRobotControl.bHome := FALSE;
// TODO trigger error message
_eCmd := E_PackMLCmd.ABORT;
M_CmdAbort();
END_IF
// Set wrf
@@ -266,19 +266,19 @@ END_VAR]]></Declaration>
END_IF
IF xExecError THEN
_eCmd := E_PackMLCmd.ABORT;
M_CmdAbort();
END_IF
// Set trf
33:
M_ExecuteCmd(E_Meca_Cmds.SET_TRF, 0, 0, 92, 0, 180, 90, xDone => xExecDone, xError => xExecError);
M_ExecuteCmd(E_Meca_Cmds.SET_TRF, 0, 0, 91, 0, 180, 90, xDone => xExecDone, xError => xExecError);
IF xExecDone THEN
_iSSM := 34;
END_IF
IF xExecError THEN
_eCmd := E_PackMLCmd.ABORT;
M_CmdAbort();
END_IF
// Move to save position
@@ -290,7 +290,7 @@ END_VAR]]></Declaration>
END_IF
IF xExecError THEN
_eCmd := E_PackMLCmd.ABORT;
M_CmdAbort();
END_IF
// Robot ready

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="ST_HMI_Tank" Id="{65129234-1803-4176-b0ff-e2e1212dc4a3}">
<Declaration><![CDATA[TYPE ST_HMI_Tank :
STRUCT
stFillingValve : ST_HMI_VALVE_DATA;
stDrainValve : ST_HMI_VALVE_DATA;
stPumpValve : ST_HMI_VALVE_DATA;
xOverfull : BOOL;
xFull : BOOL;
xEmpty : BOOL;
END_STRUCT
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_MediaCabinet" Id="{9de34b64-23ba-4fef-b086-9297bbd06f24}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_MediaCabinet
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
// (1) Acetic acid 99%
_fbTankAceticAcidHigh : FB_Tank;
// (2) Sulfuric acid
_fbTankSulfuricAcid : FB_Tank;
// (3) Nitric acid 65% mixing
_fbTankNitricAcid : FB_Tank;
// (4) Acetic acid 10%
_fbTankAceticAcidLow : FB_Tank;
// (5) Hydrofluoric acid 40%
_fbTankHydrofluoricAcid : FB_Tank;
// (6) Sulfuric acid mixing
_fbTankSulfuricAcidMixing : FB_Tank;
// (7) Hydrofluoric acid 40% for mixing
_fbTankHydrofluoricAcidMixing : FB_Tank;
// (8) SEF
_fbTankSEF : FB_Tank;
// (9) Filmetch
_fbTankFilmetch : FB_Tank;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_Tank" Id="{d029e65c-5c27-470b-8bee-fea9f0455669}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_Tank
VAR_INPUT
xReleaseErrors : BOOL;
xReleaseManualMode : BOOL;
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
xOverfull : BOOL;
xFull : BOOL;
xEmpty : BOOL;
xError : BOOL;
END_VAR
VAR_IN_OUT
stHMIInterface : ST_HMI_Tank;
END_VAR
VAR
i_xOverfull AT %I* : BOOL;
i_xFull AT %I* : BOOL;
i_xEmpty AT %I* : BOOL;
fbFillingValve : FB_Valve;
fbDrainValve : FB_Valve;
fbPumpValve : FB_Valve;
_stValveConfig : ST_ValveConfig;
_wFillingValveSafetyIntlkUsed : T_INTERLOCK;
_wFillingValveSafetyIntlk : T_INTERLOCK;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Overfull is NC so true if ok
_wFillingValveSafetyIntlk.0 := i_xOverfull;
fbFillingValve(
xReleaseErrors:= xReleaseErrors,
stValveConfig:= _stValveConfig,
xReleaseManualMode:= xReleaseManualMode,
wSafetyINTLK:= _wFillingValveSafetyIntlk,
wSafetyINTLKUsed:= _wFillingValveSafetyIntlkUsed,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stFillingValve);
fbDrainValve(
xReleaseErrors:= xReleaseErrors,
stValveConfig:= _stValveConfig,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stDrainValve);
fbPumpValve(
xReleaseErrors:= xReleaseErrors,
stValveConfig:= _stValveConfig,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stPumpValve);]]></ST>
</Implementation>
<Method Name="FB_Init" Id="{9c6d1842-9c2e-4437-b40f-941f77668ffe}">
<Declaration><![CDATA[//FB_Init is always available implicitly and it is used primarily for initialization.
//The return value is not evaluated. For a specific influence, you can also declare the
//methods explicitly and provide additional code there with the standard initialization
//code. You can evaluate the return value.
METHOD FB_Init: BOOL
VAR_INPUT
bInitRetains: BOOL; // TRUE: the retain variables are initialized (reset warm / reset cold)
bInCopyCode: BOOL; // TRUE: the instance will be copied to the copy code afterward (online change)
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_stValveConfig.xHasOpenFeedback := FALSE;
_stValveConfig.xHasClosedFeedback := FALSE;
stHMIInterface.stFillingValve.stInterlock.asSafetyINTLKName[0] := 'Tank overfull';
_wFillingValveSafetyIntlkUsed.0 := 1;]]></ST>
</Implementation>
</Method>
<Method Name="M_HandleHMIOutput" Id="{8939e00b-3459-4b5e-a4b3-7b489eec260a}">
<Declaration><![CDATA[METHOD PRIVATE M_HandleHMIOutput : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Overfull sensor is NC
stHMIInterface.xOverfull := (NOT i_xOverfull);
stHMIInterface.xFull := i_xFull;
stHMIInterface.xEmpty := i_xEmpty;]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="E_TrayFeeder_JobType" Id="{d6a9a552-c90e-4d94-ad43-94290ba0d53d}">
<Declaration><![CDATA[{attribute 'qualified_only'}
{attribute 'strict'}
{attribute 'to_string'}
TYPE E_TrayFeeder_JobType :
(
ALL := 0,
ONE_TRAY,
NUMBER
);
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -95,6 +95,10 @@ _fbTcpConnection(
eState=> );
// Get connected state
IF (NOT xConnect) THEN
stStatus.xConnected := FALSE;
END_IF
_xConnected := (_fbTcpConnection.eState = E_SocketConnectionState.eSOCKET_CONNECTED);
// Receive timeout after sending a command

View File

@@ -7,6 +7,9 @@ VAR_INPUT
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
xBusy : BOOL;
xDone : BOOL;
xError : BOOL;
END_VAR
VAR_IN_OUT
stHMIInterface : ST_HMI_TrayFeeder;
@@ -19,6 +22,21 @@ VAR
_fbProtocolHandler : FB_TFProtocol;
_xConnect : BOOL := TRUE;
// Execute command flags
_xFeedNextTray : BOOL;
// Tray feed params
_iNextTray : INT := -1;
// Ouput buffer
_xBusy : BOOL;
_xDone : BOOL;
_xError : BOOL;
END_VAR
VAR CONSTANT
MIN_TRAY_INDEX : INT := 1;
MAX_TRAY_INDEX : INT := 18;
END_VAR
]]></Declaration>
<Implementation>
@@ -37,8 +55,15 @@ _fbProtocolHandler(
xError=> );
// Call isa88 base state machine
SUPER^(stPackMLHMIInterface := stHMIInterface.stStationCmds);]]></ST>
SUPER^(stPackMLHMIInterface := stHMIInterface.stStationCmds);
// Copy output buffer to output
xBusy := _xBusy;
xDone := _xDone;
xError := _xError;]]></ST>
</Implementation>
<Folder Name="Commands" Id="{d13eb874-134c-4022-b2e9-6079a2e962f7}" />
<Folder Name="States" Id="{e8ab6d03-ac10-44ac-b36d-f343f7404100}" />
<Method Name="FB_init" Id="{6c7048d9-3836-4289-b5f3-f8878267494f}">
<Declaration><![CDATA[//FB_Init ist immer implizit verfügbar und wird primär für die Initialisierung verwendet.
//Der Rückgabewert wird nicht ausgewertet. Für gezielte Einflussnahme können Sie
@@ -58,66 +83,21 @@ _sIpAddr := sIPAddr;
_udiPort := udiPort;
// Config state machine
_stSMConfig.xStartingDisabled := TRUE;
_stSMConfig.xStoppingDisabled := TRUE;
_stSMConfig.xAbortingDisabled := TRUE;
_stSMConfig.xCompletingDisabled := TRUE;
_stSMConfig.xCompletedDisabled := TRUE;
_stSMConfig.xHeldDisabled := TRUE;
_stSMConfig.xSuspendingDisabled := TRUE;
_stSMConfig.xUnsuspendingDisabled := TRUE;
_stSMConfig.xHoldingDisabled := TRUE;
_stSMConfig.xUnholdingDisabled := TRUE;
_stSMConfig.xSuspededDisabled := TRUE;
_stSMConfig.xAbortingDisabled := TRUE;]]></ST>
_stSMConfig.xCompletedDisabled := TRUE;
]]></ST>
</Implementation>
</Method>
<Method Name="M_Clearing" Id="{c748d77d-f0af-4f18-845f-a10049447b5b}">
<Declaration><![CDATA[METHOD PROTECTED M_Clearing]]></Declaration>
<Implementation>
<ST><![CDATA[CASE _iSSM OF
// Request feeder status
0:
_fbProtocolHandler.M_SendCmd('STAT-FEED:');
_iSSM := 10;
// Await response
10:
IF (NOT _fbProtocolHandler.xBusy) THEN
_iSSM := 40;
END_IF
40:
M_StateComplete();
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="M_Execute" Id="{615f393e-f45c-4e99-890d-36c504a262b8}">
<Declaration><![CDATA[METHOD PROTECTED M_Execute
]]></Declaration>
<Implementation>
<ST><![CDATA[CASE _iSSM OF
0:
IF _fbProtocolHandler.M_SendCmd('TRAY-FEED:') THEN
_iSSM := 10;
ELSE
_eCmd := E_PackMLCmd.STOP;
END_IF
10:
IF (NOT _fbProtocolHandler.xBusy) AND (NOT _fbProtocolHandler.xError) THEN
_iSSM := 20;
END_IF
IF _fbProtocolHandler.xError THEN
_eCmd := E_PackMLCmd.STOP;
END_IF
20:
IF _fbProtocolHandler.stStatus.xInPickPosition THEN
_eCmd := E_PackMLCmd.COMPLETE;
END_IF
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="M_Resetting" Id="{d821c17b-c2d1-4267-b49d-1f82be218ca5}">
<Declaration><![CDATA[METHOD PROTECTED M_Resetting
<Method Name="M_Clearing" Id="{c748d77d-f0af-4f18-845f-a10049447b5b}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED M_Clearing
VAR_INST
_tonReconnect : TON;
END_VAR]]></Declaration>
@@ -128,7 +108,8 @@ END_VAR]]></Declaration>
IF _fbProtocolHandler.xConnected THEN
_iSSM := 10;
ELSE
_eCmd := E_PackMLCmd.STOP;
// Goto error state
_iSSM := 90;
END_IF
// Send reset command
@@ -136,7 +117,8 @@ END_VAR]]></Declaration>
IF _fbProtocolHandler.M_SendCmd('SYST-RESE:') THEN
_iSSM := 20;
ELSE
_eCmd := E_PackMLCmd.STOP;
// Goto error state
_iSSM := 90;
END_IF
// Wait for reset command to be finished
@@ -147,7 +129,8 @@ END_VAR]]></Declaration>
END_IF
IF _fbProtocolHandler.xError THEN
_eCmd := E_PackMLCmd.STOP;
// Goto error state
_iSSM := 90;
END_IF
30:
@@ -167,7 +150,136 @@ END_VAR]]></Declaration>
// Check tray feeder status
40:
_xError := FALSE;
_xBusy := FALSE;
_xDone := TRUE;
M_StateComplete();
// Error state
90:
_xError := TRUE;
_xDone := FALSE;
_xBusy := FALSE;
M_CmdAbort();
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="M_CmdFeedNextTray" Id="{265f9335-abc0-4f81-922d-74061b2b7735}" FolderPath="Commands\">
<Declaration><![CDATA[METHOD M_CmdFeedNextTray : BOOL
VAR_INPUT
iTrayNr : INT := -1;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF (stStatus.eStateCurrent = E_PackMLState.EXECUTE) AND (NOT _xBusy) THEN
_xFeedNextTray := TRUE;
_xDone := FALSE;
_xBusy := TRUE;
M_CmdFeedNextTray := TRUE;
ELSE
M_CmdFeedNextTray := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Execute" Id="{615f393e-f45c-4e99-890d-36c504a262b8}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED M_Execute
VAR
_xResult : BOOL;
_sTemp : STRING(18);
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE _iSSM OF
// Feed new tray if we still need to produce parts
0:
IF _xFeedNextTray THEN
_xFeedNextTray := FALSE;
_iSSM := 10;
END_IF
// Goto held state if door is opened
IF _fbProtocolHandler.stStatus.xDoorOpen THEN
M_CmdHold();
END_IF
// Choose to feed next tray or specific tray number
10:
// Feed next tray
IF _iNextTray < MIN_TRAY_INDEX THEN
_xResult := _fbProtocolHandler.M_SendCmd('TRAY-FEED:');
ELSIF _iNextTray <= MAX_TRAY_INDEX THEN
// Cmd: 'TRAY-FEED:Tray=[1..18];'
_sTemp := 'TRAY-FEED:Tray=';
_sTemp := CONCAT(_sTemp, INT_TO_STRING(_iNextTray));
_sTemp := CONCAT(_sTemp, ';');
_xResult := _fbProtocolHandler.M_SendCmd(_sTemp);
ELSE
// Goto error state
_iSSM := 90;
END_IF
// Check command result
IF _xResult THEN
_iSSM := 20;
ELSE
// Goto error state
_iSSM := 90;
END_IF
// Wait for command to be handled
20:
IF (NOT _fbProtocolHandler.xBusy) AND (NOT _fbProtocolHandler.xError) THEN
_xBusy := FALSE;
_xDone := TRUE;
_iSSM := 0;
END_IF
IF _fbProtocolHandler.xError THEN
// Goto error state
_iSSM := 90;
END_IF
// Error occured
90:
_xDone := FALSE;
_xBusy := FALSE;
_xError := TRUE;
M_CmdAbort();
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="M_Held" Id="{5480e446-8eb4-4576-8bbd-9839c54f1c69}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED M_Held
]]></Declaration>
<Implementation>
<ST><![CDATA[// Unhold if door is closed
IF (NOT _fbProtocolHandler.stStatus.xDoorOpen) THEN
M_CmdUnhold();
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Resetting" Id="{d821c17b-c2d1-4267-b49d-1f82be218ca5}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED M_Resetting
VAR_INST
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE _iSSM OF
// Unload tray and move elevator to load position
0:
_fbProtocolHandler.M_SendCmd('ELEV-UNLO:');
_iSSM := 10;
// Await response
10:
// If cmd could be executed we are done here
IF (NOT _fbProtocolHandler.xBusy) THEN
M_StateComplete();
END_IF
// On error go to abort state
IF _fbProtocolHandler.xError THEN
M_CmdAbort();
END_IF
END_CASE]]></ST>
</Implementation>
</Method>

View File

@@ -8,6 +8,7 @@ STRUCT
uiActTray : UINT;
xDoorOpen : BOOL;
eStateInputStack : E_TFInputStackState;
xConnected : BOOL;
END_STRUCT
END_TYPE
]]></Declaration>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="ST_TrayFeeder_Recipe" Id="{7b125673-00fb-47ea-a840-6619678735ac}">
<Declaration><![CDATA[TYPE ST_TrayFeeder_Recipe :
STRUCT
// Tray type index
iTrayIdx : INT := -1;
// How many parts to make
eJobType : E_TrayFeeder_JobType := E_TrayFeeder_JobType.ALL;
// Tray number in tray feeder
iTrayNr : INT := -1;
END_STRUCT
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>