Files
infineon_legacy_plc/PLC/9 Robot/POUs/ROBOT_MAIN_FB.TcPOU
2026-01-08 11:08:17 +01:00

1365 lines
39 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.13">
<POU Name="ROBOT_MAIN_FB" Id="{004bae5a-363f-4d11-a0e0-b072cd50bd90}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK ROBOT_MAIN_FB EXTENDS Station_GENERAL_MAIN_FB IMPLEMENTS I_STATION_CMD_CALL
VAR
Config : sRobotConfig;
ConfigOld : sRobotConfig;
i : INT;
bStartWarmUp : BOOL;
END_VAR
VAR_INPUT
IO : ROBOT_IO_FB;
RobotControl : KUKA_ROBOT_FB;
TargetStation : INT;
TargetSlot : INT;
TargetPuddle : INT;
// Size : USINT;
// RecipeName : STRING;
bInForcePut : BOOL;
PassCounter : UDINT;
FailCounter : UDINT;
PassFailText : STRING;
END_VAR
VAR CONSTANT
DualArm : BOOL := TRUE;
END_VAR
VAR RETAIN
CumulativePassCounter : UDINT;
CumulativeFailCounter : UDINT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
<Method Name="Change" Id="{70daaf13-41c8-4b0e-a5e2-4e2d768746b8}">
<Declaration><![CDATA[METHOD Change : BOOL;
VAR
i : INT;
END_VAR
VAR_INST
iSize : USINT;
FinalOffset : sPoint;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE _Step OF
0:
IF iStationStatus.WaferInfo[0].Number > 0 THEN
iSize := iStationStatus.WaferInfo[0].Size;
IF RobotControl.MTR(TargetStation, iSize, 1) THEN
_Step := 5;
END_IF
ELSIF iStationStatus.WaferInfo[1].Number > 0 THEN
iSize := iStationStatus.WaferInfo[1].Size;
IF RobotControl.MTR(TargetStation, iSize, 0) THEN
_Step := 5;
END_IF
END_IF
5:
PrepareNext(TargetStation);
IF StationsStatus[TargetStation].Ist.PrepOut THEN
_Step := 10;
ELSIF NOT StationsStatus[TargetStation].Ist.InitDone THEN
TargetStation := FirstCassette;
IF iStationStatus.WaferInfo[0].Number > 0 THEN
TargetPuddle := 0;
iStationStatus.WaferInfo[0].Defect := TRUE;
ELSIF iStationStatus.WaferInfo[1].Number > 0 THEN
TargetPuddle := 1;
iStationStatus.WaferInfo[1].Defect := TRUE;
END_IF
iCMD := PutCMD;
_Step := 0;
END_IF
10:
IF RobotControl.MSS(TargetStation, iSize) THEN
_Step := 20;
END_IF
20:
IF iStationStatus.WaferInfo[0].Number > 0 THEN
iStationStatus.WaferInfo[1] := StationsStatus[TargetStation].WaferInfo[0];
StationsStatus[TargetStation].WaferInfo[0] := iStationStatus.WaferInfo[0];
iStationStatus.WaferInfo[0].Number := 0;
ELSIF iStationStatus.WaferInfo[1].Number > 0 THEN
iStationStatus.WaferInfo[0] := StationsStatus[TargetStation].WaferInfo[0];
StationsStatus[TargetStation].WaferInfo[0] := iStationStatus.WaferInfo[1];
iStationStatus.WaferInfo[1].Number := 0;
ELSE
RETURN;
END_IF
_Step := 50;
50:
StationsStatus[TargetStation].WaferInfo[0].FlowStepNumber := StationsStatus[TargetStation].WaferInfo[0].FlowStepNumber +1;
CASE CMD[GeneralStation] OF
StartCMD:
_Step := _Step +1;
ELSE
_Step := 100;
END_CASE
51:
FOR i := 0 TO iScheduler.NumberOfjob - 1 DO
IF iScheduler.Job[i].WaferNumber = StationsStatus[TargetStation].WaferInfo[0].Number AND
iScheduler.Job[i].CassetteNumber = StationsStatus[TargetStation].WaferInfo[0].CassetteNumber THEN
//iScheduler.Job[i].Delete := TRUE;
JobDelete(i);
_Step := _Step +1;
EXIT;
END_IF
END_FOR
52:
// StationsStatus[TargetStation].WaferInfo[0].RecipeName := RecipeName;
StationsStatus[TargetStation].Soll.AutoStart := TRUE;
CMD[TargetStation] := CloseInCMD;
_Step := 100;
100:
Change := TRUE;
_Step := 0;
END_CASE
]]></ST>
</Implementation>
</Method>
<Method Name="CheckDiameter" Id="{ec7f144d-144a-48b5-919c-29afd1d2c1cd}">
<Declaration><![CDATA[METHOD CheckDiameter : BOOL
VAR_INPUT
Diameter : LREAL;
Size : INT;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF ABS(Diameter - Config.SubstrateInformation[Size].Diameter) <= Config.SubstrateInformation[Size].DiameterTolerance THEN
CheckDiameter := TRUE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="CleanOut" Id="{da118cb8-8913-4767-8b8a-589aba1897b4}">
<Declaration><![CDATA[METHOD CleanOut : BOOL
VAR_INPUT
END_VAR
VAR_INST
Step : INT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[IF iStationStatus.Soll.Stop THEN
Step := 0;
bInStartRobotCleanOut := FALSE;
RETURN;
END_IF
CASE Step OF
0:
IF iStationStatus.WaferInfo[0].Number = 100 THEN
iStationStatus.WaferInfo[0].Defect := TRUE;
TargetPuddle := 0;
Step := 10;
ELSIF iStationStatus.WaferInfo[1].Number = 100 THEN
iStationStatus.WaferInfo[1].Defect := TRUE;
TargetPuddle := 1;
Step := 10;
ELSE
Step := 50;
END_IF
10:
IF NOT iStationStatus.Ist.Busy THEN
TargetStation := FirstCassette;
iCMD := PutCMD;
Step := Step +1;
END_IF
11:
IF NOT iStationStatus.Ist.Busy THEN
Step := 0;
END_IF
50:
FOR i := FirstStation TO LastStation DO
IF StationsStatus[i].WaferInfo[0].Number = 100 THEN
StationsStatus[i].WaferInfo[0].Defect := TRUE;
TargetStation := i;
Step := 60;
RETURN;
END_IF
END_FOR
Step := 100;
60:
IF StationsStatus[TargetStation].EmergencyRecipeAvailable THEN
Step := Step +1;
ELSE
Step := 70;
END_IF
61:
IF StationsStatus[TargetStation].StationCMDCall.StartEmergency() THEN
Step := 70;
END_IF
70:
CASE PaddleMode OF
ePaddleMode.LowerPaddle:
TargetPuddle := 1;
ELSE
TargetPuddle := 0;
END_CASE
Step := Step +1;
71:
IF NOT iStationStatus.Ist.Busy THEN
iCMD := GetCMD;
Step := Step +1;
END_IF
72:
IF NOT iStationStatus.Ist.Busy THEN
Step := 80;
END_IF
80:
IF NOT iStationStatus.Ist.Busy THEN
TargetStation := FirstCassette;
iCMD := PutCMD;
Step := Step +1;
END_IF
81:
IF NOT iStationStatus.Ist.Busy THEN
Step := 50;
END_IF
100:
CleanOut := TRUE;
Step := 0;
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="FB_Init" Id="{698b4873-6196-4c56-9214-878e3d26aefe}">
<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[_VisuName := 'ROBOT';]]></ST>
</Implementation>
</Method>
<Method Name="Get" Id="{459f936d-9d08-45e7-bece-f2e5629d100f}">
<Declaration><![CDATA[METHOD Get : BOOL
VAR_INST
SLOTID : STRING;
fbFormat : FB_FormatString;
format : STRING := '%0004.0f%02.0f%02.0f%02.0f%02.0f%02.0f';
faTime : ARRAY[0..5] OF REAL;
CreateDir : FB_CreateDir;
Path : T_MaxString;
iSize : USINT;
DeleteCassette : INT;
DeleteSlot : INT;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF RobotControl.bIn_T1 THEN
iCMD := noStationCMD;
_Step := 0;
RETURN;
END_IF
CASE _Step OF
0://If Cassette PrepOut not needed
CASE StationsStatus[TargetStation].StationType OF
TypeCassette:
//IF NOT CASSETTE_IO[TargetStation].Door THEN
// iStationStatus.Error := TRUE;
// iStationStatus.StepRetry := 0;
// iStationStatus.ErrorIndex := AlarmSend(iStation:=iStationStatus.iStation,MsgId := ROBOT_ErrorNr.eCassetteDoor,TRUE, eReportType.Error, sAvailableResponse.RetryCancel, FALSE);
// RETURN;
//END_IF
IF (StationsStatus[TargetStation].Ist.CloseIn OR CMD[TargetStation] = StartCMD) AND TargetSlot > 0 AND
(CASSETTE_MAIN[TargetStation].Signal.Wafer[TargetSlot].WaferStatus = WaferForProccess OR iStationStatus.Ist.Service) THEN
IF CMD[TargetStation] = StartCMD THEN
RobotControl.bInAutoIgnore := TRUE;
END_IF
_Step := 5;
END_IF
ELSE
IF StationsStatus[TargetStation].WaferInfo[0].Number <> 0 THEN
IF StationsStatus[TargetStation].Ist.PrepIn OR StationsStatus[TargetStation].Ist.PrepOut THEN
_Step := 30;
ELSE
IF NOT StationsStatus[TargetStation].Ist.Busy THEN
CMD[TargetStation] := PrepOutCMD;
END_IF
_Step := 10;
END_IF
END_IF
END_CASE
5:
iSize := CASSETTE_MAIN[TargetStation].Signal.Wafer[TargetSlot].Size;
IF RobotControl.MTR(TargetStation, iSize, TargetPuddle, 1) THEN
_Step := 30;
END_IF
10:
iSize := StationsStatus[TargetStation].WaferInfo[0].Size;
IF RobotControl.MTR(TargetStation, iSize, TargetPuddle, 1) THEN
_Step := 20;
END_IF
20:
IF StationsStatus[TargetStation].Ist.PrepOut THEN
_Step := 30;
RETURN;
END_IF
IF NOT StationsStatus[TargetStation].Ist.Busy THEN
CMD[TargetStation] := PrepOutCMD;
END_IF
30:
CASE StationsStatus[TargetStation].StationType OF
TypeCassette:
iSize := CASSETTE_MAIN[TargetStation].Signal.Wafer[TargetSlot].Size;
IF RobotControl.GET(TargetStation, iSize, TargetSlot, TargetPuddle) THEN
IF RobotControl.bDeleteWafer THEN
DeleteCassette := TargetStation;
DeleteSlot := TargetSlot;
_Step := 35;
ELSIF RobotControl.bIgnore THEN
CASSETTE_MAIN[TargetStation].Signal.Wafer[TargetSlot].WaferStatus := noWafer;
RobotControl.bIgnore := FALSE;
_Step := 100;
ELSE
_Step := 40;
END_IF
END_IF
ELSE
iSize := StationsStatus[TargetStation].WaferInfo[0].Size;
IF RobotControl.GET(TargetStation, iSize, 1, TargetPuddle) THEN
IF RobotControl.bDeleteWafer THEN
RobotControl.bDeleteWafer := FALSE;
StationsStatus[TargetStation].Soll.Stop := TRUE;
IF StationsStatus[TargetStation].WaferInfo[0].Number = 100 THEN
_Step := 100;
ELSE
DeleteCassette := StationsStatus[TargetStation].WaferInfo[0].CassetteNumber;
DeleteSlot := StationsStatus[TargetStation].WaferInfo[0].Number;
_Step := 35;
END_IF
ELSIF RobotControl.bIgnore THEN
RobotControl.bIgnore := FALSE;
StationsStatus[TargetStation].WaferInfo[0].Number := 0;
_Step := 100;
ELSE
_Step := 40;
END_IF
END_IF
END_CASE
35:
IF DeleteWaferFromScheduler(DeleteCassette, DeleteSlot) THEN
CASSETTE_MAIN[DeleteCassette].Signal.Wafer[DeleteSlot].WaferStatus := noWafer;
RobotControl.bDeleteWafer := FALSE;
_Step := 100;
END_IF
40:
CASE StationsStatus[TargetStation].StationType OF
TypeCassette:
iStationStatus.WaferInfo[TargetPuddle].Number := TargetSlot;
iStationStatus.WaferInfo[TargetPuddle].CassetteNumber := TargetStation;
iStationStatus.WaferInfo[TargetPuddle].FlowStepNumber := 0;
iStationStatus.WaferInfo[TargetPuddle].Defect := FALSE;
iStationStatus.WaferInfo[TargetPuddle].Size := CASSETTE_MAIN[FirstCassette].Signal.Wafer[TargetSlot].Size;
IF iStationStatus.Ist.Service THEN
CASSETTE_MAIN[TargetStation].Signal.Wafer[TargetSlot].WaferStatus := noWafer;
iStationStatus.WaferInfo[TargetPuddle].Number := 100;
_Step := 100;
ELSE
CASSETTE_MAIN[TargetStation].Signal.Wafer[TargetSlot].WaferStatus := WaferInProccess;
_Step := 50;
END_IF
ELSE
iStationStatus.WaferInfo[TargetPuddle] := StationsStatus[TargetStation].WaferInfo[0];
StationsStatus[TargetStation].WaferInfo[0].Number := 0;
CMD[TargetStation] := eStationCMD.CloseOutCMD;
_Step := 100;
END_CASE
50:
(*faTime[0] := LocalTime.wYear;
faTime[1] := LocalTime.wMonth;
faTime[2] := LocalTime.wDay;
faTime[3] := LocalTime.wHour;
faTime[4] := LocalTime.wMinute;
faTime[5] := LocalTime.wSecond;
fbFormat(
sFormat:=format,
arg1:= F_REAL (faTime[0]),
arg2:= F_REAL (faTime[1]),
arg3:= F_REAL (faTime[2]),
arg4:= F_REAL (faTime[3]),
arg5:= F_REAL (faTime[4]),
arg6:= F_REAL (faTime[5]),
sOut=> SLOTID
);*)
SLOTID := INT_TO_STRING(TargetSlot);
//CASSETTE_MAIN[TargetStation].Signal.Wafer[TargetSlot].SLOT_ID := SLOTID;
iStationStatus.WaferInfo[0].LotStartTime := CASSETTE_MAIN[TargetStation].Signal.START_TIME;
iStationStatus.WaferInfo[0].LotID := CASSETTE_MAIN[TargetStation].Signal.LotID;
iStationStatus.WaferInfo[0].SlotID := SLOTID;
_Step := _Step +1;
51:
Path := CONCAT(LOG_MAIN_PATH, iStationStatus.WaferInfo[0].LotStartTime);
Path := CONCAT(Path, '\');
Path := CONCAT(Path, iStationStatus.WaferInfo[0].LotID);
Path := CONCAT(Path, '\');
Path := CONCAT(Path, iStationStatus.WaferInfo[0].SlotID);
CreateDir(sPathName := Path, bExecute := TRUE);
_Step := _Step +1;
52:
IF CreateDir.bError THEN
_Step := 200;
ELSIF NOT CreateDir.bBusy THEN
_Step := 100;
END_IF
CreateDir(bExecute := FALSE);
100:
Get := TRUE;
_Step := 0;
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="GetGripperSize" Id="{667a6724-3166-406e-8b98-94c2b7ea71c1}">
<Declaration><![CDATA[METHOD GetGripperSize : USINT
VAR_INPUT
Size : INT;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[GetGripperSize := ANY_TO_USINT(Config.SubstrateInformation[Size].GripperSize);]]></ST>
</Implementation>
</Method>
<Method Name="GetRobotGripperSize" Id="{8b479b80-1e9c-49f4-a76c-0bc8013c0e40}">
<Declaration><![CDATA[METHOD GetRobotGripperSize : INT
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[GetRobotGripperSize := RobotControl.rInProgrammNumber;]]></ST>
</Implementation>
</Method>
<Method Name="GetSubstrateThickness" Id="{11610f94-f2db-41ef-9e6b-417cce449169}">
<Declaration><![CDATA[METHOD GetSubstrateThickness : LREAL
VAR_INPUT
Size : INT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[GetSubstrateThickness := Config.SubstrateInformation[Size].Thickness;]]></ST>
</Implementation>
</Method>
<Method Name="INIT" Id="{95f6e2b7-e49a-4e2e-867b-672f915aaa62}">
<Declaration><![CDATA[METHOD INIT : BOOL
]]></Declaration>
<Implementation>
<ST><![CDATA[CASE _Step OF
0:
IF IO.DoorLock.Lock() THEN
_Step := 20;
END_IF
20:
IF RobotControl.INIT(DualArm) THEN
_Step := 0;
INIT := TRUE;
END_IF
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="Initialization" Id="{88bfb747-aa59-4d16-951c-9772477d8072}">
<Declaration><![CDATA[METHOD Initialization : BOOL
VAR_INPUT
iStation : INT;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[InitializationExt(iStation);
iStationStatus.NotInFlow := TRUE;
iStationStatus.NoAutoStart := TRUE;
iStationStatus.NoOperationMode := TRUE;
iStationStatus.ErrorList := 'ROBOT_ErrorNr';
iStationStatus.StationName := 'Robot';
RecipeStationName[iStation] := 'Robot';
ConfigManagement.Initialization(ADR(Config), ADR(ConfigOld), SIZEOF(Config), 'sRobotConfig', 'ROBOT');
ConfigPlausibility REF= Config.ConfigPlausibility;
RobotControl.Initialization(iStation);
RobotControl.Config REF= Config;
IO.Initialization(iStation);
iMediaArray[eRobotMedienNamen.CleanOut].ServiceName[0] := 'Clean Out';
iMediaArray[eRobotMedienNamen.CleanOut].ServiceName[1] := 'Clean Out';
iMediaArray[eRobotMedienNamen.CleanOut].bReferenceControl REF= bInStartRobotCleanOut;
iMediaArray[eRobotMedienNamen.CleanOut].InputAvailable := TRUE;
]]></ST>
</Implementation>
</Method>
<Method Name="MAIN" Id="{eb89df72-7522-4c03-8dd4-e020f254e9e2}">
<Declaration><![CDATA[METHOD MAIN : BOOL
VAR_INPUT
END_VAR
VAR_INST
END_VAR
VAR
fbFormatString : FB_FormatString;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[RobotControl();
IO();
CASE iCMD OF
ChangeCMD:
IF Change() THEN
iCMD := noStationCMD;
END_IF
MTRCMD:
MTR();
GetCMD:
IF Get() THEN
iCMD := noStationCMD;
END_IF
PutCMD:
IF Put() THEN
iCMD := noStationCMD;
END_IF
// ScanCMD:
// IF Scan() THEN
// iCMD := noStationCMD;
// END_IF
END_CASE
fbFormatString(
sFormat:='%d/%d',
arg1:= F_UDINT (PassCounter),
arg2:= F_UDINT (FailCounter),
sOut=> PassFailText
);
iStationStatus.Ist.Busy := iCMD <> noStationCMD;
IF bInStartRobotCleanOut THEN
IF CleanOut() THEN
bInStartRobotCleanOut := FALSE;
END_IF
END_IF
CleanOutNeeded := FALSE;
FOR i:= FirstStation TO LastStation DO
CASE StationsStatus[i].StationType OF
noStationType, TypeGeneral, TypeMedia, TypeCassette:
;
TypeRobot:
IF StationsStatus[i].WaferInfo[0].Number = 100 THEN
CleanOutNeeded := TRUE;
END_IF
IF StationsStatus[i].WaferInfo[1].Number = 100 THEN
CleanOutNeeded := TRUE;
END_IF
ELSE
IF StationsStatus[i].OnlyMoveToStation THEN
CONTINUE;
END_IF
IF StationsStatus[i].WaferInfo[0].Number = 100 THEN
CleanOutNeeded := TRUE;
END_IF
END_CASE
END_FOR
iMediaArray[eRobotMedienNamen.CleanOut].Input := bInStartRobotCleanOut;
iMediaArray[eRobotMedienNamen.CleanOut].Invisible := NOT CleanOutNeeded;
IF StationsStatus[GeneralStation].Ist.Busy OR NOT StationsStatus[GeneralStation].Ist.InitDone OR NOT iStationStatus.Ist.InitDone THEN
iMediaArray[eRobotMedienNamen.CleanOut].Invisible := TRUE;
END_IF
WarmUp();]]></ST>
</Implementation>
</Method>
<Method Name="MTR" Id="{c063de8d-c27a-4bef-abed-01dbdc101737}">
<Declaration><![CDATA[METHOD MTR
VAR_INPUT
END_VAR
VAR_INST
Step : INT;
iSize : USINT;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF StationsStatus[TargetStation].WaferInfo[0].Number > 0 THEN
iSize := StationsStatus[TargetStation].WaferInfo[0].Size;
ELSE
iSize := iStationStatus.WaferInfo[0].Size;
END_IF
// CASSETTE_MAIN[FirstCassette].TraySize;
IF RobotControl.MTR(TargetStation, iSize, TargetPuddle, 1) THEN
iCMD := eStationCMD.noStationCMD;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="PrepareNext" Id="{15c04db3-d969-4855-a7b4-09219270ee9f}">
<Declaration><![CDATA[METHOD PrepareNext : BOOL
VAR_INPUT
TargetStation : INT;
END_VAR
VAR_INST
CassetteNumber : INT;
TargetSlot : INT;
PutFinished : UINT;
NextStation : INT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE StationsStatus[TargetStation].StationType OF
TypeCassette:
RETURN;
END_CASE
CassetteNumber := StationsStatus[TargetStation].WaferInfo[0].CassetteNumber;
TargetSlot := StationsStatus[TargetStation].WaferInfo[0].Number;
PutFinished := StationsStatus[TargetStation].WaferInfo[0].FlowStepNumber;
NextStation := CASSETTE_PROCESS[CassetteNumber][TargetSlot][PutFinished+1].TargetStation;
IF NextStation = 0 THEN
RETURN;
END_IF
IF StationsStatus[NextStation].WaferInfo[0].Number = 0 AND
NOT StationsStatus[NextStation].Ist.Busy AND
StationsStatus[NextStation].Ist.InitDone AND
NOT StationsStatus[NextStation].Ist.PrepIn THEN
StationsStatus[NextStation].WaferInfo[0].Size := StationsStatus[CassetteNumber].WaferInfo[0].Size;
CMD[NextStation] := PrepInCMD;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="Put" Id="{2b7e7e26-0785-476a-8af3-73c09546543b}">
<Declaration><![CDATA[METHOD Put : BOOL
VAR
i : INT;
END_VAR
VAR_INST
OldTarget : INT;
OldTargetSlot : INT;
iSize : USINT;
FinalOffset : sPoint;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE _Step OF
0:
CASE StationsStatus[TargetStation].StationType OF
TypeCassette:
IF iStationStatus.Ist.Service THEN
OldTarget := TargetStation;
OldTargetSlot := TargetSlot;
IF (StationsStatus[TargetStation].Ist.CloseIn OR CMD[TargetStation] = StartCMD) AND
(CASSETTE_MAIN[TargetStation].Signal.Wafer[TargetSlot].WaferStatus = WaferInProccess OR
CASSETTE_MAIN[TargetStation].Signal.Wafer[TargetSlot].WaferStatus = noWafer) THEN
_Step := 5;
ELSE
_Step := 120;
END_IF
ELSE
IF iStationStatus.WaferInfo[TargetPuddle].Defect THEN
OldTarget := TargetStation;
OldTargetSlot := TargetSlot;
TargetStation := LastCassette;
iSize := iStationStatus.WaferInfo[TargetPuddle].Size;
FOR i := 1 TO Config.SubstrateInformation[iSize].MaxNumber DO
IF CASSETTE_MAIN[LastCassette].Signal.Wafer[i].WaferStatus = noWafer THEN
TargetSlot := i;
EXIT;
END_IF
END_FOR
_Step := 5;
ELSIF TargetCassette(TargetSlot) THEN
OldTarget := TargetStation;
OldTargetSlot := TargetSlot;
TargetStation := FirstCassette +1;
_Step := 5;
//ELSE
// RETURN;
END_IF
END_IF
ELSE
IF StationsStatus[TargetStation].OnlyMoveToStation THEN
IF StationsStatus[TargetStation].Ist.PrepIn THEN
IF bInForcePut THEN
_Step := 30;
ELSE
_Step := 70;
END_IF
ELSE
IF NOT StationsStatus[TargetStation].Ist.Busy AND StationsStatus[TargetStation].Ist.InitDone THEN
CMD[TargetStation] := PrepInCMD;
StationsStatus[TargetStation].WaferInfo[0].Size := iStationStatus.WaferInfo[0].Size;
END_IF
IF bInForcePut THEN
_Step := 30;
ELSE
_Step := 70;
END_IF
END_IF
ELSE
StationsStatus[TargetStation].WaferInfo[0].Size := iStationStatus.WaferInfo[TargetPuddle].Size;
IF (StationsStatus[TargetStation].Ist.PrepIn OR StationsStatus[TargetStation].Ist.PrepOut) AND StationsStatus[TargetStation].WaferInfo[0].Number = 0 THEN
_Step := 30;
ELSIF StationsStatus[TargetStation].Ist.Busy AND StationsStatus[TargetStation].Ist.InitDone THEN
_Step := 20;
ELSIF NOT StationsStatus[TargetStation].Ist.Busy AND StationsStatus[TargetStation].Ist.InitDone THEN
CMD[TargetStation] := PrepInCMD;
_Step := 20;
ELSIF NOT StationsStatus[TargetStation].Ist.InitDone THEN
iStationStatus.Error := TRUE;
iStationStatus.ErrorIndex := AlarmSend(iStation:=iStationStatus.iStation,MsgId := iStationStatus.NextError,TRUE, eReportType.Error, sAvailableResponse.Ok, FALSE);
_Step := 110;
END_IF
END_IF
END_CASE
5:
iSize := iStationStatus.WaferInfo[TargetPuddle].Size;
IF RobotControl.MTR(TargetStation, iSize, TargetPuddle, 0) THEN
_Step := 30;
END_IF
20:
iSize := iStationStatus.WaferInfo[TargetPuddle].Size;
IF RobotControl.MTR(TargetStation, iSize, TargetPuddle, 0) THEN
_Step := _Step +1;
END_IF
21:
IF (StationsStatus[TargetStation].Ist.PrepIn OR (StationsStatus[TargetStation].Ist.PrepOut AND StationsStatus[TargetStation].WaferInfo[1].Number <> 0)) AND StationsStatus[TargetStation].WaferInfo[0].Number = 0 THEN
_Step := 30;
ELSIF NOT StationsStatus[TargetStation].Ist.Busy THEN
CMD[TargetStation] := PrepInCMD;
StationsStatus[TargetStation].WaferInfo[0].Size := iStationStatus.WaferInfo[0].Size;
END_IF
30:
CASE StationsStatus[TargetStation].StationType OF
TypeCassette:
iSize := iStationStatus.WaferInfo[TargetPuddle].Size;
IF RobotControl.PUT(TargetStation, iSize, TargetSlot, TargetPuddle) THEN
_Step := 40;
END_IF
ELSE
iSize := iStationStatus.WaferInfo[TargetPuddle].Size;
IF RobotControl.PUT(TargetStation, iSize, 1, TargetPuddle) THEN
_Step := 40;
END_IF
END_CASE
40:
CASE StationsStatus[TargetStation].StationType OF
TypeCassette:
IF CASSETTE_MAIN[TargetStation].Signal.Wafer[TargetSlot].Defect THEN
CASSETTE_MAIN[TargetStation].Signal.Wafer[TargetSlot].WaferStatus := WaferDefect;
ELSE
CASSETTE_MAIN[TargetStation].Signal.Wafer[TargetSlot].WaferStatus := WaferFinish;
END_IF
IF NOT iStationStatus.Ist.Service AND NOT bInStartRobotCleanOut THEN
CASSETTE_MAIN[OldTarget].Signal.Wafer[OldTargetSlot].WaferStatus := noWafer;
END_IF
_Step := _Step +1;
ELSE
StationsStatus[TargetStation].WaferInfo[0] := iStationStatus.WaferInfo[TargetPuddle];
StationsStatus[TargetStation].WaferInfo[0].FlowStepNumber := StationsStatus[TargetStation].WaferInfo[0].FlowStepNumber +1;
_Step := _Step +1;
END_CASE
41:
iStationStatus.WaferInfo[TargetPuddle].Number := 0;
iStationStatus.WaferInfo[TargetPuddle].CassetteNumber := 0;
_Step := 50;
50:
IF iStationStatus.Ist.Service THEN
IF StationsStatus[TargetStation].NoRecipe THEN
CMD[TargetStation] := CloseInCMD;
StationsStatus[TargetStation].Soll.AutoStart := TRUE;
END_IF
_Step := 100;
ELSIF CMD[GeneralStation] = StartCMD THEN
_Step := 60;
ELSE
_Step := 100;
END_IF
60:
CASE StationsStatus[TargetStation].StationType OF
TypeCassette:
IF DeleteWaferFromScheduler(OldTarget, OldTargetSlot) THEN
CASE TargetStation OF
LastCassette:
FailCounter := FailCounter + 1;
CumulativeFailCounter := CumulativeFailCounter +1;
ELSE
PassCounter := PassCounter + 1;
CumulativePassCounter := CumulativePassCounter +1;
END_CASE
_Step := 100;
END_IF
(*FOR i := 0 TO iScheduler.NumberOfjob - 1 DO
IF iScheduler.Job[i].WaferNumber = OldTargetSlot AND
iScheduler.Job[i].CassetteNumber = OldTarget THEN
JobDelete(i);
//iScheduler.Job[i].Delete := TRUE;
_Step := 100;
EXIT;
END_IF
END_FOR*)
ELSE
FOR i := 0 TO iScheduler.NumberOfjob - 1 DO
IF iScheduler.Job[i].WaferNumber = StationsStatus[TargetStation].WaferInfo[0].Number AND
iScheduler.Job[i].CassetteNumber = StationsStatus[TargetStation].WaferInfo[0].CassetteNumber THEN
JobDelete(i);
//iScheduler.Job[i].Delete := TRUE;
_Step := _Step +1;
EXIT;
END_IF
END_FOR
END_CASE
61:
// StationsStatus[TargetStation].WaferInfo[0].RecipeName := RecipeName;
StationsStatus[TargetStation].Soll.AutoStart := TRUE;
CMD[TargetStation] := CloseInCMD;
_Step := 100;
70:
iSize := iStationStatus.WaferInfo[TargetPuddle].Size;
IF RobotControl.MTS(TargetStation, iSize, TargetPuddle) THEN
_Step := _Step +1;
END_IF
71:
StationsStatus[TargetStation].WaferInfo[0] := iStationStatus.WaferInfo[TargetPuddle];
StationsStatus[TargetStation].WaferInfo[0].FlowStepNumber := StationsStatus[TargetStation].WaferInfo[0].FlowStepNumber +1;
CMD[TargetStation] := CloseInCMD;
StationsStatus[TargetStation].Soll.AutoStart := TRUE;
_Step := _Step +1;
72:
IF NOT iStationStatus.Ist.Service THEN
PrepareNext(TargetStation);
END_IF
IF StationsStatus[TargetStation].Ist.PrepOut THEN
iStationStatus.WaferInfo[TargetPuddle] := StationsStatus[TargetStation].WaferInfo[0];
StationsStatus[TargetStation].WaferInfo[0].Number := 0;
_Step := _Step +1;
END_IF
73:
CASE StationsStatus[TargetStation].StationType OF
TypeCodeReader:
IF RobotControl.MTS_DONE(TRUE) THEN
_Step := _Step +1;
END_IF
ELSE
IF RobotControl.MTS_DONE(TRUE) THEN
_Step := _Step +1;
END_IF
END_CASE
74:
IF iStationStatus.Ist.Service THEN
_Step := 0;
Put := TRUE;
ELSE
FOR i := 0 TO iScheduler.NumberOfjob - 1 DO
IF iScheduler.Job[i].WaferNumber = iStationStatus.WaferInfo[0].Number AND
iScheduler.Job[i].CassetteNumber = iStationStatus.WaferInfo[0].CassetteNumber THEN
JobDelete(i);
//iScheduler.Job[i].Delete := TRUE;
_Step := 79;
EXIT;
END_IF
END_FOR
END_IF
79:
_Step := 0;
Put := TRUE;
100:
_Step := 0;
Put := TRUE;
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="Scan" Id="{0c6563dd-9d72-4342-872a-e7afd50b080d}">
<Declaration><![CDATA[METHOD Scan : BOOL
VAR_INST
MAPArray : ARRAY [1..MaxNumberOfSubstratesPerTray] OF BYTE;
_Size : USINT;
MaxNumberOfSlots : SINT;
MAP : ARRAY [1..MaxNumberOfSubstratesPerTray] OF BYTE;
END_VAR
VAR
Empty_MAP : ARRAY [1..MaxNumberOfSubstratesPerTray] OF BYTE;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[CASE _Step OF
0:
MAP := Empty_MAP;
CASE TargetStation OF
FirstCassette:
IF KeyenceCamera.SizeDetection(Out=>_Size) THEN
Step := 10;
END_IF
ELSE
Step := 20;
END_CASE
10:
IF _Size > 0 THEN
LastSizeFound := _Size;
iStationStatus.WaferInfo[0].Size := _Size;
IF KeyenceCamera.Mapping(Size := _Size, Out := MAP) THEN
Step := 20;
END_IF
END_IF
20:
FOR i := 1 TO MaxNumberOfSubstratesPerTray DO
CASE MAP[i] OF
0:
CASSETTE_MAIN[TargetStation].Signal.Wafer[i].WaferStatus := noWafer;
1:
CASSETTE_MAIN[TargetStation].Signal.Wafer[i].WaferStatus := WaferForProccess;
CASSETTE_MAIN[TargetStation].Signal.Wafer[i].Size := _Size;
ELSE
CASSETTE_MAIN[TargetStation].Signal.Wafer[i].WaferStatus := WaferDefect;
END_CASE
END_FOR
Step := 100;
100:
_Step := 0;
Scan := TRUE;
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="Service" Id="{98a59bef-0bf3-4916-b9f2-c95420c6f070}">
<Declaration><![CDATA[METHOD Service : BOOL
VAR_INPUT
END_VAR
VAR
END_VAR
VAR_INST
TargetStationStatus : REFERENCE TO sStationStatus;
i : INT;
OneTime : BOOL;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[RobotSignal.Service.TargetStationNumber := RobotSignal.ListTargetStationNumber[RobotSignal.Service.TargetStation];
TargetStationStatus REF= StationsStatus[RobotSignal.Service.TargetStationNumber];
RobotSignal.Service.GetInvisible := FALSE;
RobotSignal.Service.PutInvisible := FALSE;
RobotSignal.Service.SelectionDisable := FALSE;
RobotSignal.Service.ScanInvisible := FALSE;
RobotSignal.Service.CassetteInvisible := FALSE;
CASE TargetStationStatus.StationType OF
TypeCassette:
RobotSignal.Service.TargetCassette := TargetStationStatus.iStation;
IF TargetStationStatus.Ist.Busy OR
// iStationStatus.WaferInfo[0].Number <> 0 OR
// StationsStatus[RobotStation].WaferNumber[1] <> 0 OR
NOT TargetStationStatus.Ist.InitDone THEN
RobotSignal.Service.ScanInvisible := TRUE;
END_IF
IF NOT TargetStationStatus.Ist.CloseIn THEN
RobotSignal.Service.GetInvisible := TRUE;
RobotSignal.Service.PutInvisible := TRUE;
RobotSignal.Service.CassetteInvisible := TRUE;
END_IF
CASE RobotSignal.Service.TargetPuddle OF
eRobotPaddle.UpperPaddle:
IF iStationStatus.WaferInfo[0].Number = 0 THEN
RobotSignal.Service.PutInvisible := TRUE;
ELSE
RobotSignal.Service.GetInvisible := TRUE;
END_IF
eRobotPaddle.LowerPaddle:
IF iStationStatus.WaferInfo[1].Number = 0 THEN
RobotSignal.Service.PutInvisible := TRUE;
ELSE
RobotSignal.Service.GetInvisible := TRUE;
END_IF
END_CASE
IF CASSETTE_MAIN[RobotSignal.Service.TargetCassette].Signal.Wafer[RobotSignal.Service.TargetSlot].WaferStatus = noWafer THEN
RobotSignal.Service.GetInvisible := TRUE;
ELSE
RobotSignal.Service.PutInvisible := TRUE;
END_IF
IF NOT CASSETTE_MAIN[TargetStationStatus.iStation].IO.CarrierAvailable THEN
RobotSignal.Service.GetInvisible := TRUE;
RobotSignal.Service.PutInvisible := TRUE;
RobotSignal.Service.CassetteInvisible := TRUE;
RobotSignal.Service.ScanInvisible := TRUE;
END_IF
// IF TargetStationStatus.NoPut THEN
// RobotSignal.Service.PutInvisible := TRUE;
// END_IF
// IF TargetStationStatus.NoGet THEN
// RobotSignal.Service.GetInvisible := TRUE;
// END_IF
ELSE
RobotSignal.Service.TargetCassette := FirstCassette;
RobotSignal.Service.ScanInvisible := TRUE;
RobotSignal.Service.CassetteInvisible := TRUE;
IF TargetStationStatus.Ist.Busy OR
NOT TargetStationStatus.Ist.InitDone THEN
RobotSignal.Service.GetInvisible := TRUE;
RobotSignal.Service.PutInvisible := TRUE;
END_IF
IF TargetStationStatus.WaferInfo[0].Number = 0 THEN
RobotSignal.Service.GetInvisible := TRUE;
ELSE
RobotSignal.Service.PutInvisible := TRUE;
END_IF
CASE RobotSignal.Service.TargetPuddle OF
eRobotPaddle.UpperPaddle:
IF iStationStatus.WaferInfo[0].Number = 0 THEN
RobotSignal.Service.PutInvisible := TRUE;
END_IF
eRobotPaddle.LowerPaddle:
IF iStationStatus.WaferInfo[1].Number = 0 THEN
RobotSignal.Service.PutInvisible := TRUE;
END_IF
END_CASE
RobotSignal.Service.ScanInvisible := TRUE;
END_CASE
IF iStationStatus.Ist.Busy THEN
RobotSignal.Service.ScanInvisible := TRUE;
RobotSignal.Service.GetInvisible := TRUE;
RobotSignal.Service.PutInvisible := TRUE;
RobotSignal.Service.SelectionDisable := TRUE;
END_IF
FOR i := FirstCassette TO LastCassette DO
IF CMD[i] = CloseInCMD THEN
RobotSignal.Service.ScanInvisible := TRUE;
RobotSignal.Service.GetInvisible := TRUE;
RobotSignal.Service.PutInvisible := TRUE;
RobotSignal.Service.SelectionDisable := TRUE;
END_IF
END_FOR
IF TargetStationStatus.NoGet THEN
RobotSignal.Service.GetInvisible := TRUE;
END_IF
IF TargetStationStatus.NoPut THEN
RobotSignal.Service.PutInvisible := TRUE;
END_IF
iMediaArray[eRobotMedienNamen.ChuckGet].Invisible := FALSE;
iMediaArray[eRobotMedienNamen.ChuckPut].Invisible := FALSE;
IF iStationStatus.WaferInfo[0].Number > 0 OR iStationStatus.WaferInfo[1].Number > 0 THEN
iMediaArray[eRobotMedienNamen.ChuckGet].Invisible := TRUE;
iMediaArray[eRobotMedienNamen.ChuckPut].Invisible := TRUE;
END_IF
IF RobotControl.HasChuck THEN
iMediaArray[eRobotMedienNamen.ChuckGet].Invisible := TRUE;
ELSE
iMediaArray[eRobotMedienNamen.ChuckPut].Invisible := TRUE;
END_IF
CASE RobotControl.rInTargetStation OF
FirstSpinner:
//IF SPINNER_MAIN[RobotControl.rInTargetStation].iChuckSize = 0 THEN
;
//END_IF
LastSpinner:
;
ELSE
iMediaArray[eRobotMedienNamen.ChuckGet].Invisible := TRUE;
iMediaArray[eRobotMedienNamen.ChuckPut].Invisible := TRUE;
END_CASE
(*CASE RobotControl.rInTargetStation OF
FirstSpinner:
CASE RobotControl.rInTargetChuck OF
1:
2:
3:
END_CASE
LastSpinner:
END_CASE*)
//IF RobotControl.HasChuck THEN
// IF RobotControl.
//END_IF]]></ST>
</Implementation>
</Method>
<Method Name="Stop" Id="{b4484aba-e7c4-4293-beec-cf2af14dcebf}">
<Declaration><![CDATA[METHOD Stop : BOOL
VAR_INPUT
Step : REFERENCE TO INT;
END_VAR
VAR
i,j : INT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE Step OF
0:
Step := 10;
10:
RobotControl.STP();
Step := 20;
20:
Scheduler := EmptyScheduler;
FOR i := GeneralStation TO 100 DO
//IF Scheduler[i].NumberOfjob > 0 THEN
// FOR j := 0 TO Scheduler[i].NumberOfjob-1 DO
// Scheduler[i].Job[j].Delete := TRUE;
// END_FOR
//END_IF
CASE StationsStatus[i].StationType OF
noStationType, TypeRobot, TypeAligner, TypeGeneral, TypeMedia, TypeCassette:
;
//TypeCassette:
// StationsStatus[i].Soll.Stop := TRUE;
ELSE
IF StationsStatus[i].Ist.Busy THEN
StationsStatus[i].Soll.FinishProcess := TRUE;
END_IF
END_CASE
END_FOR
Step := 100;
100:
iStationStatus.Soll.Stop := FALSE;
Step := 0;
END_CASE
]]></ST>
</Implementation>
</Method>
<Method Name="TargetCassette" Id="{facb36b8-cc44-4848-83e8-44579d51912f}">
<Declaration><![CDATA[METHOD TargetCassette : BOOL
VAR_INPUT
TargetSlot : INT;
END_VAR
VAR_INST
Step : INT;
TargetTray : USINT;
RealTargetSlot : INT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE Step OF
0:
RealTargetSlot := TargetSlot;
TargetTray := 0;
WHILE(RealTargetSlot > 100) DO
TargetTray := TargetTray +1;
RealTargetSlot := RealTargetSlot - 100;
END_WHILE
Step := Step +1;
1:
IF TargetTray = CASSETTE_MAIN[FirstCassette+1].TrayFeeder.TrayNumber THEN
Step := 10;
ELSE
Step := 5;
END_IF
5:
IF CASSETTE_MAIN[FirstCassette+1].TrayFeeder.GetTray(TargetTray) THEN
Step := 10;
END_IF
10:
Step := 0;
TargetCassette := TRUE;
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="ToVisu" Id="{87d30a7c-674f-490a-b082-8edc5cb8fbc5}">
<Declaration><![CDATA[METHOD ToVisu : BOOL
VAR_INST
OneTime : BOOL;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[IF NOT OneTime THEN
RobotSignal.NumberOfTargetStation := 0;
FOR i := 1 TO 100 DO
CASE StationsStatus[i].StationType OF
noStationType, TypeRobot, TypeGeneral, TypeMedia:
;
ELSE
RobotSignal.ListTargetStationNumber[RobotSignal.NumberOfTargetStation] := i;
RobotSignal.ListTargetStationString[RobotSignal.NumberOfTargetStation] := StationsStatus[i].StationName;
RobotSignal.NumberOfTargetStation := RobotSignal.NumberOfTargetStation +1;
END_CASE
END_FOR
RobotSignal.NumberOfTargetStation := RobotSignal.NumberOfTargetStation - 1;
OneTime := TRUE;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="WarmUp" Id="{f084c395-069d-4907-bbbf-2e5d02ec4ac4}">
<Declaration><![CDATA[METHOD WarmUp : BOOL
VAR_INPUT
END_VAR
VAR_INST
Step : INT;
Counter : INT;
iSize : INT := 10;
fbFileOpen : FB_FileOpen;
hFile : UINT;
fbFilePuts : FB_FilePuts;
Value : T_MaxString;
fbFileClose : FB_FileClose;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE Step OF
0:
IF iStationStatus.Ist.InitDone AND bStartWarmUp THEN
Step := 10;
END_IF
10:
IF RobotControl.MTR(10, iSize, 0, 0) THEN
Step := 20;
END_IF
20:
IF RobotControl.MTR(11, iSize, 1, 0) THEN
Step := 30;
END_IF
30:
IF RobotControl.MTR(12, iSize, 0, 0) THEN
Step := 40;
END_IF
40:
IF RobotControl.MTR(20, iSize, 1, 0) THEN
Step := 50;
END_IF
50:
IF RobotControl.MTR(21, iSize, 0, 0) THEN
Step := 60;
END_IF
60:
IF RobotControl.MTR(30, iSize, 1, 0) THEN
Step := 70;
END_IF
70:
IF RobotControl.MTR(40, iSize, 0, 0) THEN
Step := 80;
END_IF
80:
IF RobotControl.MTR(50, iSize, 1, 0) THEN
Step := 90;
END_IF
90:
IF RobotControl.MTR(51, iSize, 0, 0) THEN
Counter := Counter +1;
IF Counter = 25 THEN
bStartWarmUp := FALSE;
Step := 0;
Counter := 0;
ELSE
Step := 0;
END_IF
END_IF
100:
IF RobotControl.MTS(AlignerStation, 50, 0) THEN
Step := 110;
END_IF
110:
StationsStatus[AlignerStation].WaferInfo[0] := iStationStatus.WaferInfo[0];
CMD[AlignerStation] := CloseInCMD;
StationsStatus[AlignerStation].Soll.AutoStart := TRUE;
Step := Step +1;
111:
IF StationsStatus[AlignerStation].Ist.PrepOut THEN
iStationStatus.WaferInfo[0] := StationsStatus[AlignerStation].WaferInfo[0];
StationsStatus[AlignerStation].WaferInfo[0].Number := 0;
Step := Step +1;
END_IF
112:
IF RobotControl.MTS_DONE(TRUE) THEN
Step := 120;
END_IF
120:
fbFileOpen.sPathName := 'D:\RobotTest.csv';
fbFileOpen.nMode := FOPEN_MODEAPPEND OR FOPEN_MODETEXT;
fbFileOpen(bExecute := TRUE);
IF fbFileOpen.bBusy THEN
Step := Step +1;
END_IF
121:
IF NOT fbFileOpen.bBusy AND fbFileOpen.hFile <> 0 THEN
hFile := fbFileOpen.hFile;
Step := 130;
END_IF
fbFileOpen(bExecute := FALSE);
130:
//Value := LREAL_TO_STRING(Offset.X);
Value := CONCAT(Value, ';');
//Value := CONCAT(Value, LREAL_TO_STRING(Offset.Y));
Value := CONCAT(Value, ';$N');
Step := 140;
140:
fbFilePuts.hFile := hFile;
fbFilePuts.sLine := Value;
fbFilePuts(bExecute := TRUE);
IF fbFilePuts.bBusy THEN
Step := Step +1;
END_IF
141:
IF NOT fbFilePuts.bBusy THEN
Step := 150;
END_IF
fbFilePuts(bExecute := FALSE);
150:
fbFileClose.hFile := hFile;
fbFileClose(bExecute := TRUE);
IF fbFileClose.bBusy THEN
Step := Step +1;
END_IF
151:
IF NOT fbFileClose.bBusy THEN
Step := 0;
END_IF
fbFileClose(bExecute := FALSE);
END_CASE]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>