First bigger step to automation

- Aligned X and Y NC Axis with aligner camera coordination system
- Added robot plc jobs and feedback
- Began Meca500 robot interface
- Changed hotplate control to slow PWM
- PackML statemachine now starts in aborted state
- Fixed StateML start method
This commit is contained in:
2026-02-04 19:31:13 +01:00
parent 677c03d51d
commit c1850f780b
29 changed files with 1249 additions and 374 deletions

View File

@@ -15,15 +15,17 @@ TYPE E_KukaRobot_JobNumerPLC :
// Etcher 1 station
ENABLE_VACUUM_ETCHER1 := 20,
DISABLE_VACUUM_ETHER1 := 22,
DISABLE_VACUUM_ETCHER1 := 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
UNLOCK_CHUCK_ETCHER2 := 61,
LOCK_CHUCK_ETCHER2 := 63,
JOB_FAILED := 99
) WORD := NO_JOB;
END_TYPE
]]></Declaration>

View File

@@ -9,11 +9,17 @@ VAR_INPUT
// Feedbacks from other units
// like if a door is open and such things
stUnitFeedbacks : ST_KukaRobot_UnitFeedbacks;
xAckPLCCmd : BOOL;
xPLCJobFailed : BOOL;
xReleaseAlarms : BOOL;
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
eCmdFromRobot : E_KukaRobot_JobNumerPLC;
xNewCmdRequested : BOOL;
xReady : BOOL;
xError : BOOL;
END_VAR
@@ -43,7 +49,7 @@ VAR
_uState AT %I* : U_KukaRobot_State;
_dwErrorBits AT %I* : DWORD;
_awJobStatesFromRobot AT %I* : ARRAY[0..1] OF WORD;
_dwJobForPLC AT %I* : DWORD;
_eJobForPLC AT %I* : E_KukaRobot_JobNumerPLC;
_abMirrorToolsAndPositions AT %I* : ARRAY[0..3] OF BYTE;
@@ -58,6 +64,8 @@ VAR
_ePlcJob :E_KukaRobot_JobNumerPLC;
_iState : INT;
_xRobotReady : BOOL;
_xError : BOOL;
@@ -97,7 +105,7 @@ _fbAlarmEStopActive(
timOffDelay:= T#0S);
_fbAlarmOperatorSafetyNotOk(
xActive:= (NOT _uState.stState.bUserSAF),
xActive:= (NOT _uState.stState.bUserSAF) AND (_uState.stState.bExt),
xRelease:= TRUE,
xAcknowledge:= xConfirmAlarms,
timOnDelay:= T#0S,
@@ -149,7 +157,12 @@ _uCtrl.stCtrl.bNotDisableAxes := 1;
// Write unit feedbacks outputs
// ============================
_uCtrl.stCtrl.bDoorEtcher1Open := stUnitFeedbacks.xDoorEtcher1Open;
_uCtrl.stCtrl.bDoorEtcher2Open := stUnitFeedbacks.xDoorEtcher2Open;
_uCtrl.stCtrl.bDoorHVTestHotOpen := stUnitFeedbacks.xDoorHVTestHotOpen;
_uCtrl.stCtrl.bDoorHVTestColdOpen := stUnitFeedbacks.xDoorHVTestColdOpen;
M_HandlePLCJobs();
// =================
@@ -217,9 +230,69 @@ END_IF
<Declaration><![CDATA[METHOD PROTECTED M_Execute
]]></Declaration>
<Implementation>
<ST><![CDATA[// Wait for robot to be done
IF _awJobStatesFromRobot[0] = 0 THEN
_eCmd := E_PackMLCmd.COMPLETE;
<ST><![CDATA[CASE stJobParams.eJob OF
E_KukaRobot_JobNumberRobot.WARMUP:
CASE _iSSM OF
0: // Wait for program to end
IF _awJobStatesFromRobot[0] = 0 THEN
IF _asiMotorTemps1To4[3] < 40 THEN
_iSSM := 10;
ELSE
_eCmd := E_PackMLCmd.COMPLETE;
END_IF
END_IF
10: // Write robot number 0
_uJobs.stJobs.wJobNrForRobot := stJobParams.eJob;
IF _awJobStatesFromRobot[0] = _uJobs.stJobs.wJobNrForRobot THEN
_uJobs.stJobs.wJobNrForRobot := E_KukaRobot_JobNumberRobot.NO_JOB;
_iSSM := 0;
END_IF
END_CASE
ELSE
// Wait for robot to be done
IF _awJobStatesFromRobot[0] = 0 THEN
_uJobs.stJobs.wJobNrForRobot := E_KukaRobot_JobNumberRobot.NO_JOB;
_eCmd := E_PackMLCmd.COMPLETE;
END_IF
END_CASE
]]></ST>
</Implementation>
</Method>
<Method Name="M_HandlePLCJobs" Id="{4e3710b4-697b-42e8-86b1-31b19b3023db}">
<Declaration><![CDATA[METHOD M_HandlePLCJobs
VAR_INST
_rtrigNewJob : R_TRIG;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_rtrigNewJob(CLK := (_eJobForPLC <> E_KukaRobot_JobNumberRobot.NO_JOB));
IF _rtrigNewJob.Q THEN
eCmdFromRobot := _eJobForPLC;
xNewCmdRequested := TRUE;
END_IF
IF xNewCmdRequested AND xAckPLCCmd THEN
xNewCmdRequested := FALSE;
IF (NOT xPLCJobFailed) THEN
_uJobs.stJobs.wFinishedJobNrFromPlc := _eJobForPLC;
ELSE
_uJobs.stJobs.wFinishedJobNrFromPlc := E_KukaRobot_JobNumerPLC.JOB_FAILED;
END_IF
eCmdFromRobot := E_KukaRobot_JobNumberRobot.NO_JOB;
END_IF
// Reset plc job done
IF (_eJobForPLC = E_KukaRobot_JobNumberRobot.NO_JOB)
AND (_uJobs.stJobs.wFinishedJobNrFromPlc <> E_KukaRobot_JobNumberRobot.NO_JOB)
AND (NOT xPLCJobFailed)
THEN
_uJobs.stJobs.wFinishedJobNrFromPlc := E_KukaRobot_JobNumberRobot.NO_JOB;
END_IF]]></ST>
</Implementation>
</Method>
@@ -343,15 +416,20 @@ END_VAR]]></Declaration>
<ST><![CDATA[CASE _iSSM OF
// Check job parameters
0:
IF (_stJobParams.byGripperNumber < 0) OR (_stJobParams.byGripperNumber > 3) // Wrong gripper number
OR (_stJobParams.byChuckNumber < 1) OR (_stJobParams.byChuckNumber > 6) // Wrong chuck number
OR (_stJobParams.byGripperSide < 1) OR (_stJobParams.byGripperSide > 2) // Wrong gripper side
IF (_stJobParams.byGripperNumber < 0) OR (_stJobParams.byGripperNumber > 4) // Wrong gripper number
//OR (_stJobParams.byChuckNumber < 1) OR (_stJobParams.byChuckNumber > 6) // Wrong chuck number
OR (_stJobParams.byGripperSide < 1) OR (_stJobParams.byGripperSide > 6) // Wrong gripper side
THEN
_eCmd := E_PackMLCmd.ABORT;
ELSE
_iSSM := 10;
END_IF
// BLOCKIERE GREIFER TAUSCH, DA AKTUELL KABEL DEFEKT !!!!!
IF _stJobParams.eJob = E_KukaRobot_JobNumberRobot.CHANGE_GRIPPER THEN
_eCmd := E_PackMLCmd.ABORT;;
END_IF
// Transfer job data to robot
10:
// Pos x in um
@@ -364,16 +442,7 @@ END_VAR]]></Declaration>
_diThickness := REAL_TO_DINT(_stJobParams.rThickness * 1000);
// Gripper side
IF _stJobParams.byGripperSide = 1 THEN
_uCtrl.stCtrl.bGripperSide1 := 1;
_uCtrl.stCtrl.bGripperSide2 := 0;
ELSIF _stJobParams.byGripperSide = 2 THEN
_uCtrl.stCtrl.bGripperSide1 := 0;
_uCtrl.stCtrl.bGripperSide2 := 1;
ELSE
_uCtrl.stCtrl.bGripperSide1 := 0;
_uCtrl.stCtrl.bGripperSide2 := 0;
END_IF
_uCtrl.stCtrl.byGripperSide := _stJobParams.byGripperSide;
// Scan QR code
IF stJobParams.xScanQRCode THEN

View File

@@ -38,15 +38,18 @@ STRUCT
bDummy8 : BIT;
bDummy9 : BIT;
bGripperSide1 : BIT;
bGripperSide2 : BIT;
bDummy10 : BIT;
bDummy11 : BIT;
bDummy12 : BIT;
bDoorEtcher1Open : BIT;
bDoorEtcher2Open : BIT;
bDoorHVTestHotOpen : BIT;
bDoorHVTestColdOpen : BIT;
bDummy13: BIT;
byGripperSide : BYTE;
END_STRUCT
END_TYPE
]]></Declaration>

View File

@@ -7,31 +7,31 @@ STRUCT
eJob : E_KukaRobot_JobNumberRobot;
// Position in x in mm
rPosX : REAL;
rPosX : REAL := 78;
// Position in y in mm
rPosY : REAL;
rPosY : REAL := 88;
// Substrate thickness in mm
rThickness : REAL;
rThickness : REAL := 2.7;
// Gripper side (1 or 2)
byGripperSide : BYTE;
byGripperSide : BYTE := 3;
// Scan QR Code during pickup from loading station
xScanQRCode : BOOL;
// Position on hotplate (1-9)
byPlaceOnHotplate : BYTE;
byPlaceOnHotplate : BYTE := 1;
// Position on coolplate (1-9)
byPlaceOnCoolPlate : BYTE;
byPlaceOnCoolPlate : BYTE := 1;
// Gripper tool number (0-3)
byGripperNumber : BYTE;
byGripperNumber : BYTE := 2;
// Chuck for etcher to load (1-6)
byChuckNumber : BYTE;
byChuckNumber : BYTE := 1;
END_STRUCT
END_TYPE
]]></Declaration>

View File

@@ -3,8 +3,8 @@
<DUT Name="ST_KukaRobot_UnitFeedbacks" Id="{d247890a-fdb7-498e-85a5-2423833e65fc}">
<Declaration><![CDATA[TYPE ST_KukaRobot_UnitFeedbacks :
STRUCT
xDoorEthcher1Open : BOOL;
xDoorEther2Open : BOOL;
xDoorEtcher1Open : BOOL;
xDoorEtcher2Open : BOOL;
xDoorHVTestHotOpen : BOOL;
xDoorHVTestColdOpen : BOOL;
END_STRUCT