Added hot and cold plates

- Started spinner chuck io's
This commit is contained in:
2026-02-01 13:53:21 +01:00
parent 8c41ff9bad
commit 1ade81c1c5
30 changed files with 3626 additions and 5882 deletions

View File

@@ -7,6 +7,8 @@ VAR
_fbHVTester : FB_HVTester;
_fbEtcher1 : FB_Etcher;
_fbEtcher2 : FB_Etcher;
_fbTrayFeederInput : FB_TrayFeeder(sIPAddr := '192.168.1.10', udiPort := 5000);
_fbHeatCoolPlates : FB_HeatCoolPlates;
_xConfirmAlarms : BOOL;
@@ -16,11 +18,18 @@ VAR
_stRobotJobParams : ST_KukaRobot_JobParams;
_stCamResult AT %I* : ST_TrayFeederCamPosData;
_rtStopRobotFromSafety : R_TRIG;
// DEBUG commands
_xClear : BOOL;
_xReset : BOOL;
_xStart : BOOL;
_xHold : BOOL;
_xUnhold : BOOL;
_xStop : BOOL;
_xStartTrigger : BOOL;
_tofTriggerTime : TOF := (PT := T#1S);
@@ -30,19 +39,37 @@ END_VAR
<Implementation>
<ST><![CDATA[IF _xClear THEN
_xClear := FALSE;
_stRobotCmd.eCntrlCmd := E_PackMLCmd.CLEAR;
_stRobotCmd.xCmdChangeRequest := TRUE;
_fbRobot.M_Clear();
END_IF
IF _xReset THEN
_xReset := FALSE;
_stRobotCmd.eCntrlCmd := E_PackMLCmd.RESET;
_stRobotCmd.xCmdChangeRequest := TRUE;
_fbRobot.M_Reset();
END_IF
IF _xStart THEN
_xStart := FALSE;
_stRobotCmd.eCntrlCmd := E_PackMLCmd.START;
_fbRobot.M_Start();
END_IF
IF _xHold THEN
_xHold := FALSE;
_fbRobot.M_Hold();
END_IF
IF _xUnhold THEN
_xUnhold := FALSE;
_fbRobot.M_Unhold();
END_IF
IF _xStop THEN
_xStop := FALSE;
_fbRobot.M_Stop();
END_IF
_rtStopRobotFromSafety(CLK := PRG_Safety.xStopRobot);
IF _rtStopRobotFromSafety.Q THEN
_stRobotCmd.eCntrlCmd := E_PackMLCmd.STOP;
_stRobotCmd.xCmdChangeRequest := TRUE;
END_IF
@@ -62,12 +89,22 @@ END_IF
_fbHVTester(xOpenChambers:= GVL_SCADA.xOpenAllChambers);
_fbEtcher1(xOpenDoor:= GVL_SCADA.xOpenAllChambers);
_fbEtcher2(xOpenDoor:= GVL_SCADA.xOpenAllChambers);
_fbEtcher1(xOpenDoor:= GVL_SCADA.xOpenAllChambers, xConfirmAlarms := GVL_SCADA.xErrAck);
_fbEtcher2(xOpenDoor:= GVL_SCADA.xOpenAllChambers, xConfirmAlarms := GVL_SCADA.xErrAck);
// _fbTrayFeederInput(
// stCommand:= ,
// xConfirmAlarms := GVL_SCADA.xErrAck,
// stStatus=> GVL_SCADA.stTrayFeederInputState,
// stAdmin=> GVL_SCADA.stTRayFeederInputAdmin);
_fbHeatCoolPlates(xConfirmAlarms:= GVL_SCADA.xErrAck);
// Call safety program
PRG_Safety(xConfirmAlarms := GVL_SCADA.xErrAck);
PRG_Safety(
xConfirmAlarms := GVL_SCADA.xErrAck,
xRobotStopped := (_stRobotStatus.eStateCurrent <> E_PackMLState.EXECUTE));
// =====
// DEBUG

View File

@@ -4,9 +4,15 @@
<Declaration><![CDATA[PROGRAM PRG_Safety
VAR_INPUT
xConfirmAlarms : BOOL;
xRobotStopped : BOOL;
END_VAR
VAR_OUTPUT
xStopRobot : BOOL := FALSE;
END_VAR
VAR
_xRun AT %Q* : BOOL;
_xEStopOk AT %I* : BOOL;
_xRequestOpenDoor AT %I* : BOOL;
_rtrigDoorUnlock : R_TRIG;
@@ -22,8 +28,9 @@ END_VAR
<Implementation>
<ST><![CDATA[_xRun := NOT _xComStartup;
_rtrigDoorUnlock(CLK := _xRequestOpenDoor);
_rtrigDoorUnlock(CLK := _xRequestOpenDoor AND xRobotStopped);
IF _rtrigDoorUnlock.Q THEN
xStopRobot := (NOT xStopRobot);
_xLockDoor := (NOT _xLockDoor);
END_IF

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="ST_PosData" Id="{a239aa72-8733-4bd3-94a0-6f6589ef2443}">
<Declaration><![CDATA[{attribute 'pack_mode' := '1'}
TYPE ST_PosData :
STRUCT
wPosX : INT;
wPosY : INT;
END_STRUCT
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="ST_TrayFeederCamPosData" Id="{b23e235e-7a29-4216-a7f3-ec637f9c5927}">
<Declaration><![CDATA[{attribute 'pack_mode' := '1'}
TYPE ST_TrayFeederCamPosData :
STRUCT
byNumberOf : BYTE;
astPosData : ARRAY[0..7] OF ST_PosData;
END_STRUCT
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -1,25 +1,146 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_Etcher" Id="{e75b6d70-36db-4c78-b78d-a594609441d1}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_Etcher
<Declaration><![CDATA[FUNCTION_BLOCK FB_Etcher EXTENDS FB_PackMLGeneric
VAR_INPUT
xOpenDoor : BOOL;
xOpenChuckClamp : BOOL;
xEjectChuck : BOOL;
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
xChuckClampOpen : BOOL;
END_VAR
VAR
_xOpenDoor AT %Q* : BOOL;
_xCloseDoor AT %Q* : BOOL;
_fbValveDoor : FB_Valve('Door');
_stValveDoorCfg : ST_ValveConfig := (
xHasClosedFeedback := TRUE,
xHasOpenFeedback := TRUE,
timTimeoutOpen := T#5S,
timTimeoutClose := T#5S);
_stDoorHMIInterface : ST_HMI_VALVE_DATA;
_fbClampingLeft : FB_Valve('Clamping left');
_stValveClampingLeftCfg : ST_ValveConfig := (
xHasClosedFeedback := TRUE,
xHasOpenFeedback := TRUE,
timTimeoutOpen := T#5S,
timTimeoutClose := T#5S);
_stClampingLeftHMIInterface : ST_HMI_VALVE_DATA;
_fbClampingRight : FB_Valve('Clamping right');
_stValveClampingRightCfg : ST_ValveConfig := (
xHasClosedFeedback := TRUE,
xHasOpenFeedback := TRUE,
timTimeoutOpen := T#5S,
timTimeoutClose := T#5S);
_stClampingRightHMIInterface : ST_HMI_VALVE_DATA;
_fbClampingFront : FB_Valve('Clamping front');
_stValveClampingFrontCfg : ST_ValveConfig := (
xHasClosedFeedback := TRUE,
xHasOpenFeedback := TRUE,
timTimeoutOpen := T#5S,
timTimeoutClose := T#5S);
_stClampingFrontHMIInterface : ST_HMI_VALVE_DATA;
_fbClampingBack : FB_Valve('Clamping back');
_stValveClampingBackCfg : ST_ValveConfig := (
xHasClosedFeedback := TRUE,
xHasOpenFeedback := TRUE,
timTimeoutOpen := T#5S,
timTimeoutClose := T#5S);
_stClampingBackHMIInterface : ST_HMI_VALVE_DATA;
_rtEjectChuckCmd : R_TRIG;
_tpEjectChuck : TP;
// =======
// Sensors
// =======
// Spinner vibration sensor
_xVibrationSensor AT %I* : BOOL;
// =========
// Actuators
// =========
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF xOpenDoor THEN
_xOpenDoor := TRUE;
_xCloseDoor := FALSE;
<ST><![CDATA[// Main door
_fbValveDoor(
xAutomaticOpen:= xOpenDoor,
xReleaseErrors:= TRUE,
stValveConfig:= _stValveDoorCfg,
xReleaseManualMode:= FALSE,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= _stDoorHMIInterface);
// Chuck
_rtEjectChuckCmd(CLK := xEjectChuck);
IF _rtEjectChuckCmd.Q THEN
_tpEjectChuck(IN := TRUE, PT := T#500MS);
ELSE
_xOpenDoor := FALSE;
_xCloseDoor := TRUE;
END_IF]]></ST>
_tpEjectChuck(IN := FALSE);
END_IF
_fbClampingLeft(
xAutomaticOpen:= xOpenChuckClamp,
xReleaseErrors:= TRUE,
stValveConfig:= _stValveClampingLeftCfg,
xReleaseManualMode:= FALSE,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= _stClampingLeftHMIInterface);
_fbClampingRight(
xAutomaticOpen:= xOpenChuckClamp,
xReleaseErrors:= TRUE,
stValveConfig:= _stValveClampingRightCfg,
xReleaseManualMode:= FALSE,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= _stClampingRightHMIInterface);
_fbClampingFront(
xAutomaticOpen:= _tpEjectChuck.Q,
xReleaseErrors:= TRUE,
stValveConfig:= _stValveClampingFrontCfg,
xReleaseManualMode:= FALSE,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= _stClampingFrontHMIInterface);
_fbClampingBack(
xAutomaticOpen:= _tpEjectChuck.Q,
xReleaseErrors:= TRUE,
stValveConfig:= _stValveClampingBackCfg,
xReleaseManualMode:= FALSE,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= _stClampingBackHMIInterface);
// Call base sm
SUPER^();]]></ST>
</Implementation>
<Method Name="FB_Init" Id="{afcda70c-3e52-4a32-9ca9-670a6b854f24}">
<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[_stSMConfig.xStoppingDisabled := TRUE;
_stSMConfig.xCompletingDisabled := TRUE;
_stSMConfig.xCompletedDisabled := TRUE;
_stSMConfig.xAbortingDisabled := TRUE;]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_HVTester" Id="{63fd7fbb-2896-492c-ad94-827a20571a58}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_HVTester
<Declaration><![CDATA[FUNCTION_BLOCK FB_HVTester EXTENDS FB_PackMLGeneric
VAR_INPUT
xOpenChambers : BOOL;
END_VAR
@@ -35,7 +35,10 @@ ELSE
_xCloseDoor1 := TRUE;
_xCloseDoor2 := TRUE;
END_IF]]></ST>
END_IF
// Call base sm
SUPER^();]]></ST>
</Implementation>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_CoolPlate" Id="{629e3316-5d72-4e23-a03a-af14d37e58d6}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_CoolPlate
VAR_INPUT
rTempSetpoint : REAL := 25.0;
END_VAR
VAR_OUTPUT
END_VAR
VAR
// Card inputs
_stStatus AT %I* : ST_SerialStatus;
_byDataIn AT %I* : ARRAY[0..21] OF BYTE;
// Card outputs
_stCtrl AT %Q* : ST_SerialCrl;
_byDataOut AT %Q* : ARRAY[0..21] OF BYTE;
// Internal temp setpoint
_rTempSetpoint : REAL;
// Send trigger
_xSend : BOOL;
// Send temp test
_xTempTest : BOOL;
// Init trigger
_xInit : BOOL;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Clamp temperature settings
_rTempSetpoint := rTempSetpoint;
IF _rTempSetpoint > 60.0 THEN
_rTempSetpoint := 60.0;
END_IF
IF _rTempSetpoint < 10.0 THEN
_rTempSetpoint := 10.0;
END_IF
// Init card on first run
IF _xInit THEN
_xInit := FALSE;
_stCtrl.bInitRequest := 1;
END_IF
IF _stStatus.bInitAccepted THEN
_stCtrl.bInitRequest := 0;
END_IF
// Send
IF _xSend THEN
_xSend := FALSE;
_stCtrl.bTransmitRequest := 1;
END_IF
IF _stStatus.bTransmitAccepted THEN
_stCtrl.bTransmitRequest := 0;
END_IF
// Debug test
IF _xTempTest THEN
_xTempTest := FALSE;
M_SetTemp(rTemp := _rTempSetpoint);
_xSend := TRUE;
END_IF]]></ST>
</Implementation>
<Method Name="M_CalcChecksum" Id="{dc2c8dbc-8315-4281-befa-84b7f4e74dc9}">
<Declaration><![CDATA[METHOD M_CalcChecksum
VAR_INPUT
uiStartIndex : UINT;
uiEndIndex : UINT;
END_VAR
VAR_OUTPUT
byHigh : BYTE;
byLow : BYTE;
END_VAR
VAR
_dwChecksum : DWORD;
_uiCounter : UINT;
_byHigh : BYTE;
_byLow : BYTE;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Calculate sum
FOR _uiCounter := uiStartIndex TO uiEndIndex DO
_dwChecksum := _dwChecksum + _byDataOut[_uiCounter];
END_FOR
// Use lower bytes
_byHigh := SHR(_dwChecksum.%B0 AND 16#F0, 4);
_byLow := _dwChecksum.%B0 AND 16#0F;
// Add offset
_byHigh := _byHigh + 16#30;
_byLow := _byLow + 16#30;
byHigh := _byHigh;
byLow := _byLow;]]></ST>
</Implementation>
</Method>
<Method Name="M_SetTemp" Id="{e9f6069c-f4a0-47e4-9ef0-4fbbec8764d9}">
<Declaration><![CDATA[METHOD M_SetTemp
VAR_INPUT
rTemp : REAL;
END_VAR
VAR
_dwTemp : DWORD;
_sTemp : STRING(4);
_byHigh : BYTE;
_byLow : BYTE;
_sHexString : STRING(4);
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Convert temperature
_dwTemp := REAL_TO_DWORD(rTemp * 10)*10;
_sTemp := DWORD_TO_STRING(_dwTemp);
_byDataOut[0] := 16#02; // STX
_byDataOut[1] := 16#31; // Command code
_byDataOut[2] := _sTemp[0];
_byDataOut[3] := _sTemp[1];
_byDataOut[4] := _sTemp[2];
_byDataOut[5] := _sTemp[3];
_byDataOut[6] := 16#03; // ETX
M_CalcChecksum(
uiStartIndex:= 1,
uiEndIndex:= 5,
byHigh=> _byDataOut[7],
byLow=> _byDataOut[8]);
_byDataOut[9] := 16#0D; // <CR>
_stCtrl.byOutputLength := 10;]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_HeatCoolPlates" Id="{a2be063c-19d7-4ca2-8121-529d61cc7bc2}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_HeatCoolPlates
VAR_INPUT
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
END_VAR
VAR
_fbHeatingPlate : FB_HotPlate;
_xEnableHotplate : BOOL;
_rTargetTemp : REAL := 30.0;
// Cool plate
_fbCoolPlate : FB_CoolPlate;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_fbHeatingPlate(
xEnable:= _xEnableHotplate,
rTargetTemp:= _rTargetTemp,
xConfirmAlarms:= xConfirmAlarms,
uiNextFreeSlot=> ,
uiNextReadySlot=> );
_fbCoolPlate();]]></ST>
</Implementation>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_HotPlate" Id="{317a2373-f886-4e32-b683-81b726d00aac}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_HotPlate
VAR_INPUT
xEnable : BOOL;
rTargetTemp : REAL;
rDeadBand : REAL := 5.0;
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
uiNextFreeSlot : UINT;
uiNextReadySlot : UINT;
END_VAR
VAR
_xEnableHotplate AT %Q* : BOOL;
_axSlotFree : ARRAY [0..(GVL_HeatCoolConfig.HEAT_COOL_PLATES_NUM_SLOTS - 1)] OF BOOL;
_tonSlotTimer : ARRAY[0..(GVL_HeatCoolConfig.HEAT_COOL_PLATES_NUM_SLOTS - 1)] OF TON;
// Temp sensor
_fbTempSensor : FB_AnalogInput('Temp sensor');
_stTempSensorConfig : ST_ANALOG_IO_CONFIG := (sUnit := '°C', rPVMin := -200, rPVMax := 850, iAIMin := -2000, iAIMax := 8500);
_stTempSEnsorEWConfig : ST_ANALOG_EW_CONFIG := (
stLevels := (
rErrorMin := -2000,
rErrorMax := 8500,
rWarningMin := -1000,
rWarningMax := 7500),
stDelays := (
timErrorHighOn := T#1S,
timErrorLowOn := T#1S,
timWarningHighOn := T#1S,
timWarningLowOn := T#1S,
timHardwareSignalLevelOff := T#1S));
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Call sensor fbs
_fbTempSensor(
stAnalogIOConfig:= _stTempSensorConfig,
stAnalogEWConfig:= _stTempSEnsorEWConfig,
xReleaseErrors:= TRUE,
xReleaseLimitErrors:= FALSE,
xReleaseHardwareErrors:= TRUE,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface=> );
// Control temperature with two point controller
IF _fbTempSensor.rScaledValue < (rTargetTemp - rDeadBand) THEN
_xEnableHotplate := TRUE;
END_IF
IF _fbTempSensor.rScaledValue >= (rTargetTemp) THEN
_xEnableHotplate := FALSE;
END_IF
]]></ST>
</Implementation>
<Method Name="M_AddItem" Id="{9707459a-6558-487c-b730-c9dc92d598ed}">
<Declaration><![CDATA[METHOD M_AddItem
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<GVL Name="GVL_HeatCoolConfig" Id="{865917de-a2fa-49b0-b682-05395fd01971}">
<Declaration><![CDATA[{attribute 'qualified_only'}
VAR_GLOBAL CONSTANT
HEAT_COOL_PLATES_NUM_SLOTS : UINT := 9;
END_VAR]]></Declaration>
</GVL>
</TcPlcObject>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="ST_SerialCrl" Id="{02e99166-5c76-4fb3-84cc-719c63e20136}">
<Declaration><![CDATA[{attribute 'pack_mode' := '1'}
TYPE ST_SerialCrl :
STRUCT
bTransmitRequest : BIT;
bReceiveAccepted : BIT;
bInitRequest : BIT;
bSendContinues : BIT;
byOutputLength : BYTE;
END_STRUCT
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="ST_SerialStatus" Id="{e37399e0-7acb-4d91-826f-26258cabab1c}">
<Declaration><![CDATA[{attribute 'pack_mode' := '1'}
TYPE ST_SerialStatus :
STRUCT
bTransmitAccepted : BIT;
bReceiveRequested : BIT;
bInitAccepted : BIT;
bBufferFull : BIT;
bParityError : BIT;
bFramingError : BIT;
bOverrunError : BIT;
byInputLength : BYTE;
END_STRUCT
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -140,9 +140,9 @@ SUPER^();
_uCtrl.stCtrl.bNotDisableAxes := 1;
// Disable move if in T2 for safety reasons
IF _uState.stState.bT2 THEN
_uCtrl.stCtrl.bEnableMove := 0;
END_IF
// IF _uState.stState.bT2 THEN
// _uCtrl.stCtrl.bEnableMove := 0;
// END_IF
// ============================
@@ -179,7 +179,7 @@ _stSMConfig.xAbortingDisabled := TRUE;]]></ST>
</Implementation>
</Method>
<Method Name="M_Aborted" Id="{0c0c17ce-5c1c-4640-9d39-f25b22309d5d}">
<Declaration><![CDATA[METHOD M_Aborted
<Declaration><![CDATA[METHOD PROTECTED M_Aborted
]]></Declaration>
<Implementation>
<ST><![CDATA[// Reset all relevant robot control signals
@@ -196,7 +196,7 @@ _uJobs.stJobs.wFinishedJobNrFromPlc := E_KukaRobot_JobNumerPLC.NO_JOB;]]></ST>
</Implementation>
</Method>
<Method Name="M_Clearing" Id="{e6152288-8c7d-4b38-bfbc-4f861d76ccc5}">
<Declaration><![CDATA[METHOD M_Clearing
<Declaration><![CDATA[METHOD PROTECTED M_Clearing
VAR_INST
_tonWait : TON;
END_VAR]]></Declaration>
@@ -214,7 +214,7 @@ END_IF
</Implementation>
</Method>
<Method Name="M_Execute" Id="{bc86876c-a8db-4285-b95c-7c6858a2ca66}">
<Declaration><![CDATA[METHOD M_Execute
<Declaration><![CDATA[METHOD PROTECTED M_Execute
]]></Declaration>
<Implementation>
<ST><![CDATA[// Wait for robot to be done
@@ -224,28 +224,33 @@ END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Held" Id="{22ddbad0-0b66-427e-a2aa-f177f8adbc94}">
<Declaration><![CDATA[METHOD M_Held
<Declaration><![CDATA[METHOD PROTECTED M_Held
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Holding" Id="{ff8c2c8e-1fe0-4c63-ad7b-790d72bd9217}">
<Declaration><![CDATA[METHOD M_Holding
<Declaration><![CDATA[METHOD PROTECTED M_Holding
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
<ST><![CDATA[_uCtrl.stCtrl.bEnableMove := 0;
IF _uState.stState.bRobStopped THEN
M_StateComplete();
END_IF
]]></ST>
</Implementation>
</Method>
<Method Name="M_Idle" Id="{025437ab-beb0-4ad6-bdc3-468dec599ff4}">
<Declaration><![CDATA[METHOD M_Idle
<Declaration><![CDATA[METHOD PROTECTED M_Idle
]]></Declaration>
<Implementation>
<ST><![CDATA[_stJobParams := stJobParams;]]></ST>
</Implementation>
</Method>
<Method Name="M_Resetting" Id="{dfe4d36a-80aa-4364-bfd8-6ddd41636d59}">
<Declaration><![CDATA[METHOD M_Resetting
<Declaration><![CDATA[METHOD PROTECTED M_Resetting
VAR_INST
_tonTimeout : TON;
END_VAR]]></Declaration>
@@ -253,7 +258,26 @@ END_VAR]]></Declaration>
<ST><![CDATA[_tonTimeout(PT := T#10S);
CASE _iSSM OF
// Check if com interface is ok
0:
_uCtrl.stCtrl.bEnableMove := 1;
_uCtrl.stCtrl.bConfMess := 1;
_tonTimeout.IN := TRUE;
IF _uState.stState.bIOActConf THEN
_uCtrl.stCtrl.bConfMess := 0;
_iSSM := 10;
END_IF
// Timeout io_Act_conf ready
IF _tonTimeout.Q THEN
_uCtrl.stCtrl.bConfMess := 0;
_tonTimeout(IN := FALSE);
_eCmd := E_PackMLCmd.ABORT;
END_IF
// Enable axes
10:
_uCtrl.stCtrl.bEnableAxes := 1;
_tonTimeout.IN := TRUE;
@@ -261,7 +285,7 @@ CASE _iSSM OF
IF _uState.stState.bPeriRdy THEN
_uCtrl.stCtrl.bEnableAxes := 0;
_tonTimeout(IN := FALSE);
_iSSM := 10;
_iSSM := 20;
END_IF
// Timeout drives ready
@@ -272,16 +296,16 @@ CASE _iSSM OF
_eCmd := E_PackMLCmd.ABORT;
END_IF
10:
// Reset move stop
20:
_uCtrl.stCtrl.bConfMess := 1;
_tonTimeout.IN := TRUE;
// Wait for errors to be reset
IF (NOT _uState.stState.bStopMess) THEN
_uCtrl.stCtrl.bConfMess := 0;
_tonTimeout(IN := FALSE);
_iSSM := 20;
_iSSM := 30;
END_IF
// Timeout reset errors
@@ -291,10 +315,9 @@ CASE _iSSM OF
_eCmd := E_PackMLCmd.ABORT;
END_IF
20:
// Start main program
// Start program
30:
_uCtrl.stCtrl.bExtStart := 1;
_tonTimeout.IN := TRUE;
IF _tonTimeout.Q THEN
@@ -312,7 +335,7 @@ END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="M_Starting" Id="{011f85d8-1225-4288-876f-918df6e4f235}">
<Declaration><![CDATA[METHOD M_Starting
<Declaration><![CDATA[METHOD PROTECTED M_Starting
VAR_INST
_tonTimeout : TON;
END_VAR]]></Declaration>
@@ -413,10 +436,10 @@ END_CASE
</Implementation>
</Method>
<Method Name="M_Stopped" Id="{50813767-4bd7-4147-b5dc-1bbd18ae1555}">
<Declaration><![CDATA[METHOD M_Stopped
<Declaration><![CDATA[METHOD PROTECTED M_Stopped
]]></Declaration>
<Implementation>
<ST><![CDATA[_uCtrl.stCtrl.bConfMess := 0;
<ST><![CDATA[// _uCtrl.stCtrl.bConfMess := 0;
_uCtrl.stCtrl.bEnableAxes := 0;
_uCtrl.stCtrl.bNotDisableAxes := 1;
_uCtrl.stCtrl.bExtStart := 0;
@@ -426,28 +449,89 @@ _ePlcJob := E_KukaRobot_JobNumerPLC.NO_JOB;]]></ST>
</Implementation>
</Method>
<Method Name="M_Suspended" Id="{c2db015c-1cd0-491a-8ce6-6c0bffba7631}">
<Declaration><![CDATA[METHOD M_Suspended
<Declaration><![CDATA[METHOD PROTECTED M_Suspended
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Suspending" Id="{5b0e5227-d5bb-40c6-a1b8-8e81b852b9b9}">
<Declaration><![CDATA[METHOD M_Suspending
<Declaration><![CDATA[METHOD PROTECTED M_Suspending
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Unholding" Id="{786f4949-9630-4ace-9e30-65bea4e87cb2}">
<Declaration><![CDATA[METHOD M_Unholding
]]></Declaration>
<Declaration><![CDATA[METHOD PROTECTED M_Unholding
VAR_INST
_tonTimeout : TON;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
<ST><![CDATA[_tonTimeout(PT := T#10S);
CASE _iSSM OF
0:
_uCtrl.stCtrl.bEnableMove := 1;
_uCtrl.stCtrl.bEnableAxes := 1;
_tonTimeout.IN := TRUE;
// Wait for drives to be ready
IF _uState.stState.bPeriRdy THEN
_uCtrl.stCtrl.bEnableAxes := 0;
_tonTimeout(IN := FALSE);
_iSSM := 10;
END_IF
// Timeout drives ready
IF _tonTimeout.Q THEN
_uCtrl.stCtrl.bEnableAxes := 0;
_fbAlarmDrivesEnableTimeout.xRelease := TRUE;
_tonTimeout(IN := FALSE);
_eCmd := E_PackMLCmd.ABORT;
END_IF
10:
_uCtrl.stCtrl.bConfMess := 1;
_tonTimeout.IN := TRUE;
// Wait for errors to be reset
IF (NOT _uState.stState.bStopMess) THEN
_uCtrl.stCtrl.bConfMess := 0;
_tonTimeout(IN := FALSE);
_iSSM := 20;
END_IF
// Timeout reset errors
IF _tonTimeout.Q THEN
_fbAlarmRobotErrorResetTimeout.xRelease := TRUE;
_tonTimeout(IN := FALSE);
_eCmd := E_PackMLCmd.ABORT;
END_IF
20:
// Start main program
_uCtrl.stCtrl.bExtStart := 1;
_tonTimeout.IN := TRUE;
IF _tonTimeout.Q THEN
_tonTimeout(IN := FALSE);
_eCmd := E_PackMLCmd.ABORT;
END_IF
IF _uState.stState.bProAct THEN
_uCtrl.stCtrl.bExtStart := 0;
_tonTimeout(IN := FALSE);
M_StateComplete();
END_IF
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="M_Unsuspending" Id="{d7ce33fd-cd94-44f1-9289-25a3ab3829eb}">
<Declaration><![CDATA[METHOD M_Unsuspending
<Declaration><![CDATA[METHOD PROTECTED M_Unsuspending
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>

View File

@@ -0,0 +1,376 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_TFProtocol" Id="{f0c44f0b-70b8-45d0-8720-9bd7e08b6aa6}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_TFProtocol
VAR_INPUT
sIpAddr : STRING;
udiPort : UDINT;
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
xConnected : BOOL;
xNewResponseReady : BOOL;
xBusy : BOOL;
xError : BOOL;
END_VAR
VAR
// Connection settings
_fbTcpConnection : FB_ClientServerConnection;
_sIpAddr : STRING;
_udiPort : UDINT;
_hSocket : T_HSOCKET;
_xConnect : BOOL := TRUE;
_xConnected : BOOL;
// Socket send
_fbSocketSend : FB_SocketSend;
_timSendTimeout : TIME := T#5S;
// Socket receive
_fbSocketReceive : FB_SocketReceive;
_timReceiveTimeout : TIME := T#5S;
_abReceivedBuffer : ARRAY[0..100] OF BYTE;
_sReceivedResponse : STRING;
_udiCounterReceive : UDINT;
_udiReceivedBytes : UDINT;
_timPollingTime : TIME := T#50MS;
_tonPollTimer : TON;
_xEnableReceiveTimeout : BOOL;
_timReceiveTimeoutTime : TIME := T#500MS;
_tonReceiveTimeout : TON;
_uiLastReceivedResponseId : UINT := 0;
// Receive state machine
_iStateReceive : INT;
// Command data
_uiCmdId : UINT := 1;
_sCmd : STRING(255);
_sAck : STRING(255);
// Main state machine
_iState : INT := 0;
_diCounter : DINT;
_xSendCmd : BOOL;
_uiRetries : UINT;
_xCmdReceived : BOOL;
_iPlaceCmdSeperator : INT;
_sTmp : STRING;
_xReceivedResponseOk : BOOL;
_uiReceivedCommandId : UINT;
// Buffer before output
_xBusy : BOOL;
_xError : BOOL;
END_VAR
VAR CONSTANT
MAX_RETRIES : UINT := 3;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Call client server connection fb
_fbTcpConnection(
sSrvNetID:= '',
nMode:= ,
sRemoteHost:= sIpAddr,
nRemotePort:= udiPort,
bEnable:= _xConnect,
tReconnect:= T#2S,
bBusy=> ,
bError=> ,
nErrId=> ,
hSocket=> _hSocket,
eState=> );
// Get connected state
_xConnected := (_fbTcpConnection.eState = E_SocketConnectionState.eSOCKET_CONNECTED);
// Receive timeout after sending a command
_tonReceiveTimeout(IN := _xEnableReceiveTimeout, PT := _timReceiveTimeoutTime);
// Receive state machine
CASE _iStateReceive OF
// Main socket not connected
0:
IF _xConnected THEN
_iStateReceive := 10;
END_IF
// Call receive
10:
_fbSocketReceive(
sSrvNetId:= '',
hSocket:= _hSocket,
cbLen:= SIZEOF(_abReceivedBuffer) - _udiReceivedBytes,
pDest:= ADR(_abReceivedBuffer) + _udiReceivedBytes,
bExecute:= TRUE,
tTimeout:= _timReceiveTimeout,
bBusy=> ,
bError=> ,
nErrId=> ,
nRecBytes=> );
IF (NOT _fbSocketReceive.bBusy) AND (NOT _fbSocketReceive.bError) THEN
_fbSocketReceive(bExecute := FALSE);
IF _fbSocketReceive.nRecBytes > 0 THEN
_udiReceivedBytes := _udiReceivedBytes + _fbSocketReceive.nRecBytes;
_iStateReceive := 20;
ELSE
_iStateReceive := 15;
END_IF
END_IF
// If we have an error, check if we are connected
IF _fbSocketReceive.bError THEN
_fbSocketReceive(bExecute := FALSE);
_iStateReceive := 0;
END_IF
// Wait some time before rechecking
15:
_tonPollTimer(IN := TRUE, PT := _timPollingTime);
IF _tonPollTimer.Q THEN
_tonPollTimer(IN := FALSE);
_iStateReceive := 10;
END_IF
// Check if we are still connected
IF (NOT _xConnected) THEN
_tonPollTimer(IN := FALSE);
_sReceivedResponse := '';
_iStateReceive := 0;
END_IF
// Check received data
20:
// Check if received command is complete
MEMCPY(destAddr := ADR(_sReceivedResponse), srcAddr := ADR(_abReceivedBuffer), n := _udiReceivedBytes);
_udiReceivedBytes := 0;
//_xCmdReceived := TRUE;
// Go back to polling wait state
_iStateReceive := 15;
END_CASE
CASE _iState OF
// Wait for active connection to tray feeder
0:
IF _xConnected THEN
_iState := 10;
END_IF
// Connected and idle
10:
// Got to disconnected state if connection is lost
IF (NOT _xConnected) THEN
_iState := 0;
END_IF
IF _xSendCmd THEN
_xSendCmd := FALSE;
_xBusy := TRUE;
_iState := 20;
END_IF
// Check if we received a response without sending a command
// IF _xCmdReceived THEN
// _iState := 50;
// END_IF
// Send command
20:
_fbSocketSend(
sSrvNetId:= '',
hSocket:= _hSocket,
cbLen:= SIZEOF(_sCmd),
pSrc:= ADR(_sCmd),
bExecute:= TRUE,
tTimeout:= _timSendTimeout,
bBusy=> ,
bError=> ,
nErrId=> );
IF (NOT _fbSocketSend.bBusy) AND (NOT _fbSocketSend.bError) THEN
_fbSocketSend(bExecute := FALSE);
//_xEnableReceiveTimeout := TRUE;
//_iState := 30;
END_IF
IF _fbSocketSend.bError THEN
_fbSocketSend(bExecute := FALSE);
_iState := 90;
END_IF
// Wait for response
30:
// Received a response
IF _xCmdReceived THEN
_xCmdReceived := FALSE;
_xEnableReceiveTimeout := FALSE;
_uiRetries := 0;
_iState := 40;
END_IF
// Didnt receive command ack in time
// So resend the command if max retries are not reached
IF _tonReceiveTimeout.Q THEN
_xEnableReceiveTimeout := FALSE;
_uiRetries := _uiRetries + 1;
// Check if we reached the max number of retries
IF _uiRetries > MAX_RETRIES THEN
_iState := 90;
ELSE
// Retry by sendind command again
_iState := 20;
END_IF
END_IF
// Check response
40:
// Check for cmd id
IF (TO_STRING(_sReceivedResponse[0]) <> UINT_TO_STRING(_uiCmdId)) THEN
// Wrong command id received
_iState := 90;
END_IF
// For for response indicator
IF _sReceivedResponse[1] <> F_ToASC('<') THEN
// Wrong response indicator
_iState := 90;
END_IF
// Check for correct cmd
_xReceivedResponseOk := TRUE;
FOR _diCounter := 2 TO (LEN(_sReceivedResponse) - 1) DO
IF _sReceivedResponse[_diCounter] = F_ToASC(':') THEN
EXIT;
ELSIF _sReceivedResponse[_diCounter] <> _sCmd[_diCounter] THEN
_xReceivedResponseOk := FALSE;
EXIT;
END_IF
END_FOR
IF _xReceivedResponseOk THEN
_iState := 10;
ELSE
_iState := 90;
END_IF
50:
// Get command id
_uiReceivedCommandId := STRING_TO_UINT(TO_STRING(_sReceivedResponse[0]));
// Check if it is a new command
IF (_uiReceivedCommandId <> _uiLastReceivedResponseId) OR (_uiReceivedCommandId = 0) THEN
_uiLastReceivedResponseId := _uiReceivedCommandId;
xNewResponseReady := TRUE;
// Send acknowledgement
_iState := 60;
END_IF
// Prepare ack response
60:
_sAck := CONCAT(UINT_TO_STRING(_uiLastReceivedResponseId), '<');
FOR _diCounter := 2 TO (LEN(_sReceivedResponse) - 1) DO
IF _sReceivedResponse[_diCounter] <> F_ToASC(':') THEN
_sAck[_diCounter] := _sReceivedResponse[_diCounter];
ELSE
_sAck[_diCounter] := F_ToASC('\0');
EXIT;
END_IF
END_FOR
_iState := 70;
// Send ack response
70:
_fbSocketSend(
sSrvNetId:= '',
hSocket:= _hSocket,
cbLen:= SIZEOF(_sAck),
pSrc:= ADR(_sAck),
bExecute:= TRUE,
tTimeout:= _timSendTimeout,
bBusy=> ,
bError=> ,
nErrId=> );
IF (NOT _fbSocketSend.bBusy) AND (NOT _fbSocketSend.bError) THEN
_fbSocketSend(bExecute := FALSE);
_xEnableReceiveTimeout := TRUE;
_iState := 10;
END_IF
IF _fbSocketSend.bError THEN
_fbSocketSend(bExecute := FALSE);
_iState := 90;
END_IF
// Error
90:
_xError := TRUE;
_xBusy := FALSE;
IF xConfirmAlarms THEN
_xError := FALSE;
_iState := 0;
END_IF
END_CASE
// Copy output buffers to outputs
xConnected := _xConnected;
xBusy := _xBusy;
xError := _xError;]]></ST>
</Implementation>
<Method Name="M_GetResponse" Id="{48f8719d-7ed0-4fb1-824a-0bf475fcfc2c}">
<Declaration><![CDATA[METHOD M_GetResponse : STRING
VAR
_sTmp : STRING(255);
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[xNewResponseReady := FALSE;
MEMCPY(destAddr := ADR(_sTmp), ADR(_sReceivedResponse) + 2, n := INT_TO_UDINT(LEN(_sReceivedResponse) - 2));
M_GetResponse := _sTmp;]]></ST>
</Implementation>
</Method>
<Method Name="M_SendCmd" Id="{d00a8c1a-c183-4659-9c9e-be5b30566b7c}">
<Declaration><![CDATA[METHOD M_SendCmd : BOOL
VAR_INPUT
sCmd : STRING(80);
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Check if we are already sending a command
IF _xBusy OR _xError THEN
M_SendCmd := FALSE;
RETURN;
END_IF
// Increment command id
_uiCmdId := _uiCmdId + 1;
// Overflows at 9 and is reset to 1
IF _uiCmdId > 9 THEN
_uiCmdId := 1;
END_IF
// Create command with id
_sCmd := CONCAT(UINT_TO_STRING(_uiCmdId), '>');
_sCmd := CONCAT(_sCmd, sCmd);
// start sendind command state machine
_xSendCmd := TRUE;
M_SendCmd := TRUE;]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -1,38 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_TrayFeeder" Id="{e2e3e993-37de-42b1-80e1-7dba99a66e94}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FINAL FB_TrayFeeder EXTENDS FB_Isa88_SM
<Declaration><![CDATA[FUNCTION_BLOCK FINAL FB_TrayFeeder EXTENDS FB_PackMLGeneric
VAR_INPUT
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
END_VAR
VAR
_fbTcpConnection : FB_ClientServerConnection;
_sIpAddr : STRING;
_udiPort : UDINT;
_fbProtocolHandler : FB_TFProtocol;
_xTest : BOOL;
_xSendResult : BOOL;
_sCmd : STRING := 'STAT-FEED:';
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Call client server connection fb
_fbTcpConnection(
sSrvNetID:= '',
nMode:= ,
sRemoteHost:= _sIpAddr,
nRemotePort:= ,
bEnable:= ,
tReconnect:= ,
bBusy=> ,
bError=> ,
nErrId=> ,
hSocket=> ,
eState=> );
<ST><![CDATA[// IPs
// 192.168.1.10
// 192.168.1.11
_fbProtocolHandler(
sIpAddr:= _sIpAddr,
udiPort:= _udiPort,
xConfirmAlarms:= xConfirmAlarms,
xConnected=> ,
xNewResponseReady=> ,
xBusy=> ,
xError=> );
IF _xTest THEN
_xTest := FALSE;
_xSendResult := _fbProtocolHandler.M_SendCmd(sCmd := _sCmd);
END_IF
// Call isa88 base state machine
SUPER^();
// IPs
// 192.168.1.10
// 192.168.1.11]]></ST>
SUPER^();]]></ST>
</Implementation>
<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.
@@ -48,8 +54,17 @@ sIPAddr : STRING;
udiPort : UDINT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[_sIpAddr := sIPAddr;
_udiPort := udiPort;]]></ST>
<ST><![CDATA[// Save connection settings
_sIpAddr := sIPAddr;
_udiPort := udiPort;
// Config state machine
_stSMConfig.xStoppingDisabled := TRUE;
_stSMConfig.xCompletingDisabled := TRUE;
_stSMConfig.xCompletedDisabled := TRUE;
_stSMConfig.xAbortingDisabled := TRUE;]]></ST>
</Implementation>
</Method>
</POU>

View File

@@ -6,6 +6,10 @@ VAR_GLOBAL
xErrAck : BOOL;
xOpenAllChambers : BOOL;
// Unit states
stTrayFeederInputState : ST_PMLs;
stTRayFeederInputAdmin : ST_PMLa;
END_VAR]]></Declaration>
</GVL>
</TcPlcObject>

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_PI" Id="{d504557e-7fd7-4784-a00a-5d7d1bed0c95}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_PI
VAR_INPUT
rSP : REAL;
rPV : REAL;
rKp : REAL;
rTn : REAL;
xEnable : BOOL;
xSaturatedUpper : BOOL := FALSE;
xSaturatedLower : BOOL := FALSE;
END_VAR
VAR_OUTPUT
rMV : REAL;
END_VAR
VAR
_rError : REAL := 0.0;
_rIntegral : REAL := 0.0;
_rProportinal : REAL := 0.0;
_rDeltaIntegral : REAL := 0.0;
_fbGetCurTaskIdx : GETCURTASKINDEX;
_rT : REAL;
_xFirstCylce : BOOL := TRUE;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF _xFirstCylce THEN
_xFirstCylce := FALSE;
// Get current task time
_fbGetCurTaskIdx();
_rT := LREAL_TO_REAL(UDINT_TO_LREAL(TwinCAT_SystemInfoVarList._TASKInfo[_fbGetCurTaskIdx.index].CycleTime) * 10E-5);
END_IF
IF xEnable THEN
_rError := rSP - rPV;
ELSE
_rError := 0.0;
_rIntegral := 0.0;
rMV := 0.0;
RETURN;
END_IF
// Calculate proportinal part
_rProportinal := rKp * _rError;
// Calculate controller output
rMV := _rProportinal + _rIntegral;
// Calculate integral for this step
IF rTn <> 0 THEN
_rDeltaIntegral := (rKp * _rT / rTn) * _rError;
ELSE
_rDeltaIntegral := 0;
END_IF
// Only add new integral part if we are going away from the upper or lower bound
IF (xSaturatedUpper AND (_rDeltaIntegral > 0.0)) THEN
_rDeltaIntegral := 0.0;
END_IF
IF (xSaturatedLower AND (_rDeltaIntegral < 0.0)) THEN
_rDeltaIntegral := 0.0;
END_IF
// Calculate integral part
_rIntegral := _rIntegral + _rDeltaIntegral;
// Reset integral with deactivated integral time
IF (rTn = 0.0) AND (_rIntegral <> 0) THEN
_rIntegral := 0.0;
END_IF]]></ST>
</Implementation>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="ST_PackMLGenericHMIInterface" Id="{54cdd4b1-e09e-436e-9737-cc31548609eb}">
<Declaration><![CDATA[TYPE ST_PackMLGenericHMIInterface :
STRUCT
stBtnAbort : ST_HMI_CONTROL_BUTTON;
stBtnClear : ST_HMI_CONTROL_BUTTON;
stBtnHold : ST_HMI_CONTROL_BUTTON;
stBtnReset : ST_HMI_CONTROL_BUTTON;
stBtnStart : ST_HMI_CONTROL_BUTTON;
stBtnStop : ST_HMI_CONTROL_BUTTON;
stBtnSuspend : ST_HMI_CONTROL_BUTTON;
stBtnUnhold : ST_HMI_CONTROL_BUTTON;
stBtnUnsuspend : ST_HMI_CONTROL_BUTTON;
eCurrentMode : E_PackMLUnitMode;
eCurrentState : E_PackMLState;
END_STRUCT
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -1,7 +1,7 @@
<?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
<Declaration><![CDATA[FUNCTION_BLOCK FB_PackMLGeneric
VAR_INPUT
stCommand : ST_PMLc;
END_VAR
@@ -12,6 +12,9 @@ VAR_OUTPUT
// Admin data
stAdmin : ST_PMLa;
END_VAR
VAR_IN_OUT
//stHMIInterface : ST_PackMLGenericHMIInterface;
END_VAR
VAR
// State machine handler
_fbStateMachine : FB_PackMLStateMachine;
@@ -143,85 +146,161 @@ CASE stStatus.eStateCurrent OF
;
END_CASE]]></ST>
</Implementation>
<Method Name="M_Aborted" Id="{db1a684f-e4e1-4d89-a3aa-9b9dfde0508c}">
<Declaration><![CDATA[METHOD M_Aborted
<Folder Name="Commands" Id="{11740802-7551-418d-83f3-5b2d5c93c299}" />
<Folder Name="States" Id="{2cf25144-1e5c-4db8-ba57-9d98461c53ce}" />
<Action Name="A_HandleHMIOutput" Id="{73c47dbe-0382-4e83-8c9e-e4744dd66394}">
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Action>
<Method Name="M_Abort" Id="{a8ac7d94-0639-4bcc-b083-994135ce6951}" FolderPath="Commands\">
<Declaration><![CDATA[METHOD M_Abort : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF (stStatus.eStateCurrent <> E_PackMLState.ABORTED) AND (stStatus.eStateCurrent <> E_PackMLState.ABORTING) THEN
_eCmd := E_PackMLCmd.ABORT;
M_Abort := TRUE;
ELSE
M_Abort := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Aborted" Id="{db1a684f-e4e1-4d89-a3aa-9b9dfde0508c}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED M_Aborted
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Aborting" Id="{928ad614-a3a7-4c6c-b1bc-55ae54e4c95f}">
<Declaration><![CDATA[METHOD M_Aborting
<Method Name="M_Aborting" Id="{928ad614-a3a7-4c6c-b1bc-55ae54e4c95f}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED 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
<Method Name="M_Clear" Id="{1ae1174f-acb8-4f8a-bc73-ec233f6637b2}" FolderPath="Commands\">
<Declaration><![CDATA[METHOD M_Clear : BOOL
]]></Declaration>
<Implementation>
<ST><![CDATA[IF stStatus.eStateCurrent = E_PackMLState.ABORTED THEN
_eCmd := E_PackMLCmd.CLEAR;
M_Clear := TRUE;
ELSE
M_Clear := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Clearing" Id="{1716cf1b-94c6-4995-8b3f-c7ebcf5727d3}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED 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
<Method Name="M_Complete" Id="{33df5dea-d83b-48e1-8898-d7c8e1f031bd}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED M_Complete
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Completing" Id="{341608cb-1218-481f-929c-cb79602c11ab}">
<Declaration><![CDATA[METHOD M_Completing
<Method Name="M_Completing" Id="{341608cb-1218-481f-929c-cb79602c11ab}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED 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
<Method Name="M_Execute" Id="{2a469169-0eb2-43c9-be21-48909285ee44}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED 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
<Method Name="M_Held" Id="{05b040b0-b1b9-4afd-81d0-88fc1f1a7f9b}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED M_Held
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Holding" Id="{519b03b3-2409-4b45-818f-535b3e16b22e}">
<Declaration><![CDATA[METHOD M_Holding
<Method Name="M_Hold" Id="{63908543-c84a-46a6-803b-0cd0a69ee040}" FolderPath="Commands\">
<Declaration><![CDATA[METHOD M_Hold : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF (stStatus.eStateCurrent = E_PackMLState.EXECUTE) OR (stStatus.eStateCurrent = E_PackMLState.SUSPENDED) THEN
_eCmd := E_PackMLCmd.HOLD;
M_Hold := TRUE;
ELSE
M_Hold := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Holding" Id="{519b03b3-2409-4b45-818f-535b3e16b22e}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED 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
<Method Name="M_Idle" Id="{aa784f5c-7adf-4c9f-a414-65b10afd2772}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED M_Idle
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Resetting" Id="{4050ed6f-edbe-4c3e-ac42-919a37a47ea9}">
<Declaration><![CDATA[METHOD M_Resetting
<Method Name="M_Reset" Id="{9acdfbad-6477-4a07-aac5-b9a102467964}" FolderPath="Commands\">
<Declaration><![CDATA[METHOD M_Reset : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF stStatus.eStateCurrent = E_PackMLState.STOPPED THEN
_eCmd := E_PackMLCmd.RESET;
M_Reset := TRUE;
ELSE
M_Reset := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Resetting" Id="{4050ed6f-edbe-4c3e-ac42-919a37a47ea9}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED 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
<Method Name="M_Start" Id="{86eb6432-588a-4480-b09e-72e5733dc716}" FolderPath="Commands\">
<Declaration><![CDATA[METHOD M_Start : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF stStatus.eStateCurrent = E_PackMLState.IDLE THEN
_eCmd := E_PackMLCmd.RESET;
M_Start := TRUE;
ELSE
M_Start := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Starting" Id="{0059e7f6-5f2a-40e4-9d9b-652f221495a9}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED 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
<Method Name="M_StateComplete" Id="{0cf3625e-8009-4108-a9f4-d98c991f9930}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED M_StateComplete
]]></Declaration>
<Implementation>
<ST><![CDATA[// Reset state state machine
@@ -231,43 +310,104 @@ _iSSM := 0;
_fbStateMachine.M_StateComplete();]]></ST>
</Implementation>
</Method>
<Method Name="M_Stopped" Id="{9f8a09cf-f3be-4d60-b5e4-cd9572fae88c}">
<Declaration><![CDATA[METHOD M_Stopped
<Method Name="M_Stop" Id="{8beef0bf-5aa2-4644-ae54-6acbcdaacef4}" FolderPath="Commands\">
<Declaration><![CDATA[METHOD M_Stop : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF (stStatus.eStateCurrent <> E_PackMLState.ABORTED)
AND (stStatus.eStateCurrent <> E_PackMLState.ABORTING)
AND (stStatus.eStateCurrent <> E_PackMLState.CLEARING)
AND (stStatus.eStateCurrent <> E_PackMLState.STOPPING)
AND (stStatus.eStateCurrent <> E_PackMLState.STOPPED)
THEN
_eCmd := E_PackMLCmd.STOP;
M_Stop := TRUE;
ELSE
M_Stop := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Stopped" Id="{9f8a09cf-f3be-4d60-b5e4-cd9572fae88c}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED M_Stopped
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Stopping" Id="{193565ef-cf20-428c-b726-e7c1b61375c5}">
<Declaration><![CDATA[METHOD M_Stopping
<Method Name="M_Stopping" Id="{193565ef-cf20-428c-b726-e7c1b61375c5}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED 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
<Method Name="M_Suspend" Id="{a69941cd-31ee-44b4-9c8b-a7c774e40447}" FolderPath="Commands\">
<Declaration><![CDATA[METHOD M_Suspend : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF stStatus.eStateCurrent = E_PackMLState.EXECUTE THEN
_eCmd := E_PackMLCmd.SUSPEND;
M_Suspend := TRUE;
ELSE
M_Suspend := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Suspended" Id="{222c3ad7-f7d5-4773-8e98-863345472053}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED M_Suspended
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_Suspending" Id="{0f5d52e2-2a54-4ea9-a0c4-7f08229c4f21}">
<Declaration><![CDATA[METHOD M_Suspending
<Method Name="M_Suspending" Id="{0f5d52e2-2a54-4ea9-a0c4-7f08229c4f21}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED 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
<Method Name="M_Unhold" Id="{6af8dbfd-0422-459a-b99f-09e9246d2621}" FolderPath="Commands\">
<Declaration><![CDATA[METHOD M_Unhold : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF (stStatus.eStateCurrent = E_PackMLState.HELD) THEN
_eCmd := E_PackMLCmd.UNSUSPEND;
M_Unhold := TRUE;
ELSE
M_Unhold := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Unholding" Id="{662dd054-329b-4e57-ba77-486f92af795a}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED 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
<Method Name="M_Unsuspend" Id="{ff6f4f4b-4bc6-47f7-a257-a2bcea2d6ae3}" FolderPath="Commands\">
<Declaration><![CDATA[METHOD M_Unsuspend : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF (stStatus.eStateCurrent = E_PackMLState.SUSPENDED) THEN
_eCmd := E_PackMLCmd.UNSUSPEND;
M_Unsuspend := TRUE;
ELSE
M_Unsuspend := FALSE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_Unsuspending" Id="{80fb11c4-916a-4f8f-9cf9-b9a2d51524a1}" FolderPath="States\">
<Declaration><![CDATA[METHOD PROTECTED M_Unsuspending
]]></Declaration>
<Implementation>
<ST><![CDATA[M_StateComplete();]]></ST>

View File

@@ -27,9 +27,34 @@
<SubType>Code</SubType>
<ExcludeFromBuild>false</ExcludeFromBuild>
</Compile>
<Compile Include="00_Main\ST_PosData.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="00_Main\ST_TrayFeederCamPosData.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\Etcher\FB_Etcher.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\HeatCoolPlates\FB_CoolPlate.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\HeatCoolPlates\FB_HeatCoolPlates.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\HeatCoolPlates\FB_HotPlate.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\HeatCoolPlates\GVL_HeatCoolConfig.TcGVL">
<SubType>Code</SubType>
<LinkAlways>true</LinkAlways>
</Compile>
<Compile Include="01_Stationen\HeatCoolPlates\ST_SerialCrl.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\HeatCoolPlates\ST_SerialStatus.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\HVTester\FB_HVTester.TcPOU">
<SubType>Code</SubType>
</Compile>
@@ -66,6 +91,9 @@
<Compile Include="01_Stationen\Kuka_Robot\ST_KukaRobot_UnitFeedbacks.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\TrayFeeder\FB_TFProtocol.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\TrayFeeder\FB_TrayFeeder.TcPOU">
<SubType>Code</SubType>
</Compile>
@@ -73,6 +101,9 @@
<SubType>Code</SubType>
<LinkAlways>true</LinkAlways>
</Compile>
<Compile Include="LibraryCandidates\FB_PI.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="LibraryCandidates\PackML\DUTs\E_PackMLCmd.TcDUT">
<SubType>Code</SubType>
</Compile>
@@ -112,6 +143,9 @@
<Compile Include="LibraryCandidates\PackML\DUTs\PackTags\ST_PMLs.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="LibraryCandidates\PackML\DUTs\ST_PackMLGenericHMIInterface.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="LibraryCandidates\PackML\DUTs\ST_PackMLStateMachineConfig.TcDUT">
<SubType>Code</SubType>
</Compile>
@@ -150,6 +184,7 @@
<Folder Include="01_Stationen\Kuka_Robot\InterfaceUnions" />
<Folder Include="01_Stationen\HVTester" />
<Folder Include="01_Stationen\Etcher" />
<Folder Include="01_Stationen\HeatCoolPlates" />
<Folder Include="01_Stationen\TrayFeeder" />
<Folder Include="01_Stationen" />
<Folder Include="00_Main" />
@@ -221,6 +256,10 @@
<DefaultResolution>Tc2_TcpIp, * (Beckhoff Automation GmbH)</DefaultResolution>
<Namespace>Tc2_TcpIp</Namespace>
</PlaceholderReference>
<PlaceholderReference Include="Tc2_Utilities">
<DefaultResolution>Tc2_Utilities, * (Beckhoff Automation GmbH)</DefaultResolution>
<Namespace>Tc2_Utilities</Namespace>
</PlaceholderReference>
<PlaceholderReference Include="Tc3_Module">
<DefaultResolution>Tc3_Module, * (Beckhoff Automation GmbH)</DefaultResolution>
<Namespace>Tc3_Module</Namespace>

File diff suppressed because one or more lines are too long