0.001mm FUNCTION_BLOCK FINAL FB_KukaRobot EXTENDS FB_PackMLGeneric VAR_INPUT stJobParams : ST_KukaRobot_JobParams; // 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 VAR // 0 - Nicht aus // 1 - Enable // 2 - Enable move // 3 - Conf_Mess (Reset) stCtrl AT %Q* : ST_KukaRobot_Ctrl; // 0 -> Robot job to do // 1 -> PLC job which is finished stJobs AT %Q* : ST_KukaRobot_Jobs; // 0 - Greifer nummer // 1 - Drehteller Nummer // 2 - Position Heizplatte // 3 - Position Kuehlplatte abyToolsAndPositions AT %Q* : ARRAY[0..3] OF BYTE; // Positions in um diOffsetPosX AT %Q* : DINT; diOffsetPosY AT %Q* : DINT; diThickness AT %Q* : DINT; // Inputs stState AT %I* : ST_KukaRobot_State; dwErrorBits AT %I* : DWORD; awJobStatesFromRobot AT %I* : ARRAY[0..1] OF WORD; eJobForPLC AT %I* : E_KukaRobot_JobNumerPLC; {attribute 'analysis' := '-33'} abyMirrorToolsAndPositions AT %I* : ARRAY[0..3] OF BYTE; // Position mirrors diMirrorOffsetPosX AT %I* : DINT; diMirrorOffsetPosY AT %I* : DINT; diMirrorThickness AT %I* : DINT; {attribute 'analysis' := '+33'} // Motortemperaturen asiMotorTemps1To4 AT %I* : ARRAY[0..3] OF SINT; asiMotorTemps5To8 AT %I* : ARRAY[0..3] OF SINT; _ePlcJob :E_KukaRobot_JobNumerPLC; _xRobotReady : BOOL; _xError : BOOL; // Internal job params will be copied from input // only from IDLE -> STARTING _stJobParams : ST_KukaRobot_JobParams; // ====== // Alarms // ====== _fbAlarmNotInExtMode : FB_AlarmMessage(stEventEntry := TC_EVENTS.KukaRobot.NotInExtMode, xWithConfirmation := FALSE); _fbAlarmEStopActive : FB_AlarmMessage(stEventEntry := TC_EVENTS.KukaRobot.EStopActive, xWithConfirmation := FALSE); _fbAlarmOperatorSafetyNotOk : FB_AlarmMessage(stEventEntry := TC_EVENTS.KukaRobot.OperatorSafetyNotOk, xWithConfirmation := FALSE); _fbAlarmRobotErrorResetTimeout : FB_AlarmMessage(stEventEntry := TC_EVENTS.KukaRobot.ErrorResetTimeout, xWithConfirmation := TRUE); _fbAlarmDrivesEnableTimeout : FB_AlarmMessage(stEventEntry := TC_EVENTS.KukaRobot.DrivesEnableTimeout, xWithConfirmation := TRUE); END_VAR ]]> E_KukaRobot_JobNumerPLC.NO_JOB)); IF _rtNewJob.Q THEN eCmdFromRobot := eJobForPLC; xNewCmdRequested := TRUE; END_IF IF xAckPLCCmd THEN xNewCmdRequested := FALSE; IF (NOT xPLCJobFailed) THEN stJobs.wFinishedJobNrFromPlc := eJobForPLC; ELSE stJobs.wFinishedJobNrFromPlc := E_KukaRobot_JobNumerPLC.JOB_FAILED; END_IF eCmdFromRobot := E_KukaRobot_JobNumerPLC.NO_JOB; END_IF // Reset plc job done IF (eJobForPLC = E_KukaRobot_JobNumerPLC.NO_JOB) AND (stJobs.wFinishedJobNrFromPlc <> E_KukaRobot_JobNumberRobot.NO_JOB) AND (NOT xPLCJobFailed) THEN stJobs.wFinishedJobNrFromPlc := E_KukaRobot_JobNumerPLC.NO_JOB; END_IF]]> 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 diOffsetPosX := REAL_TO_DINT(_stJobParams.rPosX * 1000); // Pos y in um diOffsetPosY := REAL_TO_DINT(_stJobParams.rPosY * 1000); // Thickness diThickness := REAL_TO_DINT(_stJobParams.rThickness * 1000); // Gripper side stCtrl.byGripperSide := _stJobParams.byGripperSide; // Scan QR code IF stJobParams.xScanQRCode THEN stCtrl.bScanQRCode := 1; ELSE stCtrl.bScanQRCode := 0; END_IF // Position on hotplate abyToolsAndPositions[2] := stJobParams.byPlaceOnHotplate; // Position on coolplate abyToolsAndPositions[3] := stJobParams.byPlaceOnCoolPlate; // Gripper number abyToolsAndPositions[0] := stJobParams.byGripperNumber; // Chuck for etcher to load abyToolsAndPositions[1] := stJobParams.byChuckNumber; // Write robot job number stJobs.wJobNrForRobot := DINT_TO_WORD(_stJobParams.eJob); // Safety reset timout fb _tonTimeout(IN := FALSE); _iSSM := 20; // Wait for robot program start 20: _tonTimeout(IN := TRUE, PT := T#5S); // If job number is read back correct, go to next state IF awJobStatesFromRobot[0] = stJobs.wJobNrForRobot THEN stJobs.wJobNrForRobot := E_KukaRobot_JobNumberRobot.NO_JOB; _tonTimeout(IN := FALSE); M_StateComplete(); END_IF // Timeout occured IF _tonTimeout.Q THEN _tonTimeout(IN := FALSE); _eCmd := E_PackMLCmd.ABORT; END_IF // Robot has error IF dwErrorBits <> 0 THEN _tonTimeout(IN := FALSE); _eCmd := E_PackMLCmd.ABORT; END_IF ELSE ; END_CASE // Wrong job read back from robot -> Abort // IF _awJobStatesFromRobot[0] <> 0 AND _awJobStatesFromRobot[0] <> E_KukaRobot_JobNumberRobot.WARMUP THEN // _eCmd := E_PackMLCmd.ABORT; // END_IF // ]]>