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; xReleaseAlarms : BOOL; xConfirmAlarms : BOOL; END_VAR VAR_OUTPUT xReady : BOOL; xError : BOOL; END_VAR VAR // 0 - Nicht aus // 1 - Enable // 2 - Enable move // 3 - Conf_Mess (Reset) _uCtrl AT %Q* : U_KukaRobot_Ctrl; // 0 -> Robot job to do // 1 -> PLC job which is finished _uJobs AT %Q* : U_KukaRobot_Jobs; // 0 - Greifer nummer // 1 - Drehteller Nummer // 2 - Position Heizplatte // 3 - Position Kuehlplatte _abToolsAndPositions AT %Q* : ARRAY[0..3] OF BYTE; // Positions in um _diOffsetPosX AT %Q* : DINT; _diOffsetPosY AT %Q* : DINT; _diThickness AT %Q* : DINT; // Inputs _uState AT %I* : U_KukaRobot_State; _dwErrorBits AT %I* : DWORD; _awJobStatesFromRobot AT %I* : ARRAY[0..1] OF WORD; _dwJobForPLC AT %I* : DWORD; _abMirrorToolsAndPositions AT %I* : ARRAY[0..3] OF BYTE; // Position mirrors _diMirrorOffsetPosX AT %I* : DINT; _diMirrorOffsetPosY AT %I* : DINT; _diMirrorThickness AT %I* : DINT; // 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 ]]> 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 THEN _eCmd := E_PackMLCmd.ABORT; ELSE _iSSM := 10; 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 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 // Scan QR code IF stJobParams.xScanQRCode THEN _uCtrl.stCtrl.bScanQRCode := 1; ELSE _uCtrl.stCtrl.bScanQRCode := 0; END_IF // Position on hotplate _abToolsAndPositions[2] := stJobParams.byPlaceOnHotplate; // Position on coolplate _abToolsAndPositions[3] := stJobParams.byPlaceOnCoolPlate; // Gripper number _abToolsAndPositions[0] := stJobParams.byGripperNumber; // Chuck for etcher to load _abToolsAndPositions[1] := stJobParams.byChuckNumber; // Write robot job number _uJobs.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] = _uJobs.stJobs.wJobNrForRobot THEN _uJobs.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 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 // ]]>