This commit is contained in:
2026-01-08 11:08:17 +01:00
commit fe882dc444
311 changed files with 511562 additions and 0 deletions

View File

@@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.11">
<POU Name="CLEANOUT" Id="{ce0061ae-e812-4a19-b385-951266a3cfdc}" SpecialFunc="None">
<Declaration><![CDATA[PROGRAM CLEANOUT
VAR_INPUT
Scan : BOOL;
CleanOut : BOOL;
TargetStation : INT;
TargetCassette : INT;
TargetSlot : INT;
END_VAR
VAR_OUTPUT
TargetStations : ARRAY[0..12] OF STRING;
TargetStationsN : ARRAY[0..12] OF INT;
TargetCassettes : ARRAY[0..3] OF STRING;
{IF defined (SO1635)}
TargetCassettesMaxIndex : INT := 3;
{END_IF}
{IF defined (SO1636)}
TargetCassettesMaxIndex : INT := 1;
{END_IF}
TargetCassettesMaxIndex : INT := 1;
TargetSlots : ARRAY[0..MaxNumberOfWafer-1] OF STRING;
NumberOfTargetStation : INT;
ScanInvisible : BOOL;
SlotInvisible : BOOL;
CleanoutInvisible : BOOL;
CassetteInvisible : BOOL;
END_VAR
VAR
i : INT;
Step : INT;
iTargetStation : INT;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[NumberOfTargetStation := 0;
CleanOutNeeded := FALSE;
ScanInvisible := FALSE;
SlotInvisible := FALSE;
CleanoutInvisible := FALSE;
CassetteInvisible := FALSE;
FOR i:= FirstStation TO LastStation DO
CASE StationsStatus[i].StationType OF
noStationType, TypeGeneral, TypeMedia:
;
TypeCassette:
TargetCassettes[i-FirstCassette] := StationsStatus[i].StationName;
IF StationsStatus[i].Ist.Busy THEN
ScanInvisible := TRUE;
SlotInvisible := TRUE;
END_IF
ELSE
IF StationsStatus[i].OnlyMoveToStation THEN
CONTINUE;
END_IF
IF StationsStatus[i].WaferInfo[0].Number = 100 THEN
TargetStations[NumberOfTargetStation] := StationsStatus[i].StationName;
TargetStationsN[NumberOfTargetStation] := i;
CleanOutNeeded := TRUE;
NumberOfTargetStation := NumberOfTargetStation +1;
END_IF
IF StationsStatus[i].StationType = TypeRobot THEN
IF StationsStatus[i].WaferInfo[0].Number = 100 THEN
TargetStations[NumberOfTargetStation] := StationsStatus[i].StationName;
TargetStationsN[NumberOfTargetStation] := i;
CleanOutNeeded := TRUE;
NumberOfTargetStation := NumberOfTargetStation +1;
END_IF
IF StationsStatus[i].Ist.Busy THEN
ScanInvisible := TRUE;
SlotInvisible := TRUE;
END_IF
END_IF
END_CASE
END_FOR
IF NOT CASSETTE_MAIN[TargetCassette + FirstCassette].IO.CarrierAvailable THEN
ScanInvisible := TRUE;
END_IF
IF StationsStatus[RobotStation].WaferInfo[0].Number <> 0 THEN
ScanInvisible := TRUE;
END_IF
IF TargetStationsN[TargetStation] = RobotStation THEN
CassetteInvisible := TRUE;
END_IF
IF StationsStatus[FirstCassette + TargetCassette].Ist.CloseIn THEN
FOR i := 0 TO MaxNumberOfWafer - 1 DO
IF CASSETTE_MAIN[FirstCassette + TargetCassette].Signal.Wafer[i+1].WaferStatus = noWafer THEN
TargetSlots[i] := INT_TO_STRING(i+1);
ELSE
TargetSlots[i] := CONCAT(INT_TO_STRING(i+1), ' (Not Available)');
END_IF
END_FOR
ELSE
SlotInvisible := TRUE;
END_IF
IF FIND(TargetSlots[TargetSlot], '(Not Available)') > 0 THEN
CleanoutInvisible := TRUE;
END_IF
IF SlotInvisible THEN
CleanoutInvisible := TRUE;
END_IF
CASE Step OF
0:
IF CleanOut THEN
Step := 10;
END_IF
10:
iTargetStation := TargetStationsN[TargetStation];
IF NOT StationsStatus[iTargetStation].Ist.Busy AND NOT StationsStatus[RobotStation].Ist.Busy THEN
ROBOT_MAIN.TargetStation := iTargetStation;
CMD[RobotStation] := GetCMD;
Step := Step +1;
END_IF
11:
IF NOT StationsStatus[RobotStation].Ist.Busy THEN
Step := 30;
END_IF
20:
IF NOT StationsStatus[RobotStation].Ist.Busy THEN
ROBOT_MAIN.TargetStation := TypeAligner;
CMD[RobotStation] := PutCMD;
Step := Step +1;
END_IF
21:
IF NOT StationsStatus[RobotStation].Ist.Busy THEN
Step := 30;
END_IF
30:
IF NOT StationsStatus[RobotStation].Ist.Busy THEN
ROBOT_MAIN.TargetStation := TypeCassette + TargetCassette;
ROBOT_MAIN.TargetSlot := TargetSlot +1;
CASSETTE_MAIN[ROBOT_MAIN.TargetStation].Signal.Wafer[ROBOT_MAIN.TargetSlot].Defect := TRUE;
CMD[RobotStation] := PutCMD;
Step := Step +1;
END_IF
31:
IF NOT StationsStatus[RobotStation].Ist.Busy THEN
CleanOut := FALSE;
Step := 0;
END_IF
END_CASE
]]></ST>
</Implementation>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.6">
<POU Name="ConcatWithD" Id="{32e9294a-ec6c-497b-87b4-a36e1be02f29}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION ConcatWithD : STRING
VAR_INPUT
CurrentStep : USINT;
StepCount : USINT;
END_VAR
VAR
TempString : STRING;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TempString := USINT_TO_STRING(CurrentStep);
TempString := CONCAT(TempString, ' / ');
TempString := CONCAT(TempString, USINT_TO_STRING(StepCount));
ConcatWithD := TempString;]]></ST>
</Implementation>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,624 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.13">
<POU Name="GENERAL_MAIN_FB" Id="{b5148723-afa6-43ad-b3aa-b206f2e9a813}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK GENERAL_MAIN_FB EXTENDS Station_GENERAL_MAIN_FB IMPLEMENTS I_STATION_CMD_CALL
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
i,j : UDINT;
RobotJob : REFERENCE TO sScheduler;
CassetteNumber : INT;
TargetStation : UDINT;
NextProcess : INT;
RobotStatus : REFERENCE TO sStationStatus;
bInitialization : BOOL;
bFirstCall : BOOL;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
<Method Name="CheckMachineForCoolDown" Id="{c7a2b26a-bc4c-459a-ac82-81f159ae8d89}">
<Declaration><![CDATA[METHOD CheckMachineForCoolDown : BOOL
VAR_INPUT
END_VAR
VAR
i : INT;
END_VAR
VAR_INST
Ready : BOOL;
Timer : TON;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[Ready := FALSE;
FOR i := FirstStation TO LastStation DO
IF StationsStatus[i].Ist.Busy THEN
Ready := TRUE;
END_IF
IF StationsStatus[i].Ist.Service THEN
Ready := TRUE;
END_IF
END_FOR
Timer(IN := NOT Ready, PT := T#10M);
bCoolDown := Timer.Q;]]></ST>
</Implementation>
</Method>
<Method Name="FB_Init" Id="{0fee2ebc-13f3-4dc2-9c22-e1eb5f8daca1}">
<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
VAR
i : INT;
Count : INT;
TempString : STRING;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[StationsStatus[GeneralStation].StationType := TypeGeneral;
StationsStatus[GeneralStation].StationCMDCall := GENERAL_MAIN;
StationsStatus[GeneralStation].StationCMDCall.Initialization(GeneralStation);]]></ST>
</Implementation>
</Method>
<Method Name="FirstCall" Id="{6041a1c1-a08f-43ec-abfe-0c44478731a1}">
<Declaration><![CDATA[METHOD FirstCall : BOOL
VAR_INPUT
END_VAR
VAR
TempString : STRING;
i, count : INT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[PaddleMode := ePaddleMode.UpperPaddle;
FOR i := FirstCassette TO LastCassette DO
StationsStatus[i].StationType := TypeCassette;
END_FOR
StationsStatus[AlignerStation].StationType := TypeAligner;
StationsStatus[CodeReaderStation].StationType := TypeCodeReader;
FOR i := FirstSpinner TO LastSpinner DO
StationsStatus[i].StationType := TypeCleaner;
END_FOR
FOR i := FirstHotplate TO LastHotplate DO
StationsStatus[i].StationType := TypeHotplate;
END_FOR
FOR i := FirstCoolplate TO LastCoolplate DO
StationsStatus[i].StationType := TypeCoolplate;
END_FOR
StationsStatus[FirstHV].StationType := TypeHVHot;
StationsStatus[LastHV].StationType := TypeHVCold;
FOR i := FirstLelaxStation TO LastRelaxStation DO
StationsStatus[i].StationType := TypeRelax;
END_FOR
StationsStatus[MediaStation].StationType := TypeMedia;
StationsStatus[RobotStation].StationType := TypeRobot;
FOR i:= FirstStation TO LastStation DO
CASE StationsStatus[i].StationType OF
ELSE
CONTINUE;
TypeCassette:
StationsStatus[i].StationCMDCall := CASSETTE_MAIN[i];
TypeAligner:
StationsStatus[i].StationCMDCall := ALIGNER_MAIN;
TypeCodeReader:
StationsStatus[i].StationCMDCall := CodeReader_MAIN;
TypeCleaner:
StationsStatus[i].StationCMDCall := SPINNER_MAIN[i];
TypeHotplate, TypeCoolplate:
StationsStatus[i].StationCMDCall := HOTPLATE_MAIN[i];
TypeHVHot, TypeHVCold:
StationsStatus[i].StationCMDCall := HV_MAIN[i];
TypeMedia:
StationsStatus[i].StationCMDCall := MEDIA_MAIN;
TypeRobot:
StationsStatus[i].StationCMDCall := ROBOT_MAIN;
TypeRelax:
StationsStatus[i].StationCMDCall := RETRY_MAIN[i];
END_CASE
StationsStatus[i].StationCMDCall.Initialization(i);
Count := StationAlternative[StationsStatus[i].StationType].Count +1;
StationAlternative[StationsStatus[i].StationType].List[Count] := i;
StationAlternative[StationsStatus[i].StationType].ListName[Count] := StationsStatus[i].StationName;
StationAlternative[StationsStatus[i].StationType].Count := Count;
END_FOR
GetRecipeTypeList();
bFirstCall := TRUE;
SlowTaskEnable := TRUE;]]></ST>
</Implementation>
</Method>
<Method Name="INIT" Id="{7cd33883-92b8-4ace-91bb-779b0d425e30}">
<Declaration><![CDATA[METHOD INIT : BOOL
VAR_INST
i,j : INT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[(*CASE Step OF
0:
IF NOT MEDIA_MAIN.IO.bInCDAOk THEN
iStationStatus.Error := TRUE;
iStationStatus.StepRetry := 0;
iStationStatus.ErrorIndex := AlarmSend(iStation,MsgId := MAIN_ErrorNr.eCDA,TRUE, eReportType.Error, sAvailableResponse.RetryCancel, FALSE);
RETURN;
END_IF
(* IF NOT MEDIA_MAIN.IO.bInVacOk THEN
iStationStatus.Error := TRUE;
iStationStatus.ErrorIndex := AlarmSend(iStation,MsgId := MAIN_ErrorNr.eVacuum,TRUE, eReportType.Error, sAvailableResponse.RetryCancel, FALSE);
RETURN;
END_IF*)
Step := 10;
10:
IF NOT StationsStatus[RobotStation].Ist.Busy THEN
CMD[RobotStation] := InitCMD;
step := step +1;
END_IF
11:
IF StationsStatus[RobotStation].Ist.InitDone THEN
step := 20;
END_IF
20:
FOR i:= FirstStation TO LastStation DO
CASE StationsStatus[i].StationType OF
noStationType, TypeRobot, TypeGeneral:
;
ELSE
IF StationsStatus[i].Ist.Busy THEN
RETURN;
END_IF
END_CASE
END_FOR
step := step +1;
21:
FOR i:= FirstStation TO LastStation DO
CASE StationsStatus[i].StationType OF
noStationType, TypeRobot, TypeGeneral:
;
ELSE
IF NOT StationsStatus[i].Ist.InitDone AND OperationMode[i] <> DisableMode THEN
CMD[i] := InitCMD;
END_IF
END_CASE
END_FOR
step := step +1;
22:
FOR i:= FirstStation TO LastStation DO
CASE StationsStatus[i].StationType OF
noStationType, TypeRobot, TypeGeneral, TypeMedia:
;
ELSE
IF NOT StationsStatus[i].Ist.InitDone AND OperationMode[i] <> DisableMode THEN
RETURN;
END_IF
END_CASE
END_FOR
step := 30;
30:
step := 100;
100:
INIT := TRUE;
Step := 0;
END_CASE*)
CASE _Step OF
0:
IF NOT MEDIA_MAIN.IO.bInCDAOk THEN
iStationStatus.Error := TRUE;
iStationStatus.StepRetry := 0;
iStationStatus.ErrorIndex := AlarmSend(iStation,MsgId := MAIN_ErrorNr.eCDA,TRUE, eReportType.Error, sAvailableResponse.RetryCancel, FALSE);
RETURN;
END_IF
(*IF NOT MEDIA_MAIN.IO.bInVacOk THEN
iStationStatus.Error := TRUE;
iStationStatus.ErrorIndex := AlarmSend(iStation,MsgId := MAIN_ErrorNr.eVacuum,TRUE, eReportType.Error, sAvailableResponse.RetryCancel, FALSE);
RETURN;
END_IF*)
_Step := 10;
10:
IF NOT StationsStatus[RobotStation].Ist.Busy THEN
CMD[RobotStation] := InitCMD;
_Step := _Step +1;
END_IF
11:
IF StationsStatus[RobotStation].Ist.InitDone THEN
_Step := 20;
END_IF
20:
FOR i:= FirstStation TO LastStation DO
CASE StationsStatus[i].StationType OF
noStationType, TypeRobot, TypeGeneral:
;
ELSE
IF OperationMode[i] = DisableMode THEN
CONTINUE;
END_IF
StationsStatus[i].Soll.Stop := TRUE;
END_CASE
END_FOR
_Step := _Step +1;
21:
FOR i:= FirstStation TO LastStation DO
CASE StationsStatus[i].StationType OF
noStationType, TypeRobot, TypeGeneral:
;
ELSE
IF OperationMode[i] = DisableMode THEN
CONTINUE;
END_IF
IF StationsStatus[i].Soll.Stop OR StationsStatus[i].Ist.Busy THEN
RETURN;
END_IF
END_CASE
END_FOR
_Step := _Step +1;
22:
DelayTimer(IN := TRUE, PT := T#1S);
IF DelayTimer.Q THEN
DelayTimer(IN := FALSE);
_Step := _Step +1;
END_IF
23:
FOR i:= FirstStation TO LastStation DO
CASE StationsStatus[i].StationType OF
noStationType, TypeRobot, TypeGeneral:
;
ELSE
IF NOT StationsStatus[i].Ist.InitDone AND OperationMode[i] <> DisableMode THEN
CMD[i] := InitCMD;
END_IF
END_CASE
END_FOR
_Step := _Step +1;
24:
FOR i:= FirstStation TO LastStation DO
CASE StationsStatus[i].StationType OF
noStationType, TypeRobot, TypeGeneral, TypeMedia:
;
ELSE
IF CMD[i] = InitCMD THEN
RETURN;
END_IF
END_CASE
END_FOR
_Step := 30;
30:
_Step := 100;
100:
bInitialization := FALSE;
INIT := TRUE;
_Step := 0;
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="Initialization" Id="{e51989ad-3094-4485-bbc7-87361ec6fa7f}">
<Declaration><![CDATA[METHOD Initialization : BOOL
VAR_INPUT
iStation : INT;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_VisuName := 'SYSTEM';
_NoConfigFile := TRUE;
InitializationExt(iStation);
RobotStatus REF=StationsStatus[RobotStation];
iStationStatus.StationName := 'System';
iStationStatus.ErrorList := 'SystemErrorList';
RobotJob REF= Scheduler[RobotStation];
iMediaArray[eMainMedienNamen.Pause].ServiceName[0] := 'Pause';
iMediaArray[eMainMedienNamen.Pause].ServiceName[1] := 'Pause';
iMediaArray[eMainMedienNamen.Pause].bReferenceControl REF= bPause;
iMediaArray[eMainMedienNamen.Pause].InputAvailable := TRUE;
iMediaArray[eMainMedienNamen.Empty].ServiceName[0] := 'Empty';
iMediaArray[eMainMedienNamen.Empty].ServiceName[1] := 'Empty';
iMediaArray[eMainMedienNamen.Empty].bReferenceControl REF= bEmpty;
iMediaArray[eMainMedienNamen.Empty].InputAvailable := TRUE;
iMediaArray[eMainMedienNamen.Initialization].ServiceName[0] := 'Initialization';
iMediaArray[eMainMedienNamen.Initialization].ServiceName[1] := 'Initialization';
iMediaArray[eMainMedienNamen.Initialization].bReferenceControl REF= bInitialization;
iMediaArray[eMainMedienNamen.Initialization].InputAvailable := TRUE;
iMediaArray[eMainMedienNamen.Initialization].NoErrorInput := TRUE;]]></ST>
</Implementation>
</Method>
<Method Name="MAIN" Id="{4e8331ba-95d4-46bc-9181-64b3616fc779}">
<Declaration><![CDATA[METHOD MAIN : BOOL
VAR_INST
i : INT;
Step : INT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[IF NOT bFirstCall THEN
FirstCall();
END_IF
KeyenceCamera();
CheckMachineForCoolDown();
nCounter := nCounter +1;
IF bResetCounter THEN
nCounter := 0;
END_IF
FOR i := FirstCassette TO LastCassette DO
IF CMD[i] = StartCMD THEN
iCMD := StartCMD;
EXIT;
END_IF
END_FOR
IF bInitialization AND NOT iStationStatus.Ist.Busy THEN
iCMD := InitCMD;
END_IF
iMediaArray[eMainMedienNamen.Initialization].Input := iStationStatus.Ist.InitDone;
iMediaArray[eMainMedienNamen.Initialization].Invisible := NOT InAktorspannung;
iMediaArray[eMainMedienNamen.Pause].Invisible := iCMD <> StartCMD;
iMediaArray[eMainMedienNamen.Empty].Invisible := iCMD <> StartCMD;
WaferInSystem := FALSE;
FOR i := FirstSpinner TO RobotStation DO
IF StationsStatus[i].WaferInfo[0].Number > 0 THEN
WaferInSystem := TRUE;
END_IF
END_FOR
IF StationsStatus[RobotStation].WaferInfo[1].Number > 0 THEN
WaferInSystem := TRUE;
END_IF
CASE PaddleMode OF
ePaddleMode.All:
TimeBetweenProcesses := 10;
ePaddleMode.LowerPaddle, ePaddleMode.UpperPaddle:
TimeBetweenProcesses := 20;
END_CASE
SubstrateOnRetry := FALSE;
FOR i := FirstLelaxStation TO LastRelaxStation DO
IF StationsStatus[i].WaferInfo[0].Number > 0 THEN
SubstrateOnRetry := TRUE;
END_IF
END_FOR
]]></ST>
</Implementation>
</Method>
<Method Name="Start" Id="{1bb288b1-fbde-4125-a70c-cc4741de9337}">
<Declaration><![CDATA[METHOD Start : BOOL
VAR_INPUT
END_VAR
VAR_INST
i,j : INT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[IF NOT Safety_PRG.MediaOk THEN
bEmpty := TRUE;
END_IF
CASE _Step OF
0:
IF bPause THEN
RETURN;
END_IF
IF RobotJob.NumberOfjob > 0 THEN
_Step := 10;
ELSE
FOR i := FirstCassette TO LastCassette DO
IF StationsStatus[i].Ist.Busy THEN
RETURN;
END_IF
END_FOR
_Step := 90;
END_IF
10:
IF bPause THEN
RETURN;
END_IF
IF RobotJob.NumberOfjob = 0 OR ChuckChangeBusy THEN
_Step := 0;
RETURN;
END_IF
IF StationsStatus[RobotStation].Ist.Busy THEN
_Step := 0;
RETURN;
END_IF
FOR i := 0 TO MIN(20, RobotJob.NumberOfjob) DO
IF IsTargetReady(RobotJob.Job[i]) THEN
CassetteNumber := RobotJob.Job[i].CassetteNumber;
ROBOT_MAIN.TargetSlot := RobotJob.Job[i].WaferNumber;
CASE CASSETTE_MAIN[CassetteNumber].Signal.Wafer[ROBOT_MAIN.TargetSlot].WaferStatus OF
WaferForProccess:
IF SubstrateOnRetry THEN
CONTINUE;
END_IF
END_CASE
_Step := 20;
RETURN;
END_IF
END_FOR
20:
CASE CASSETTE_MAIN[CassetteNumber].Signal.Wafer[ROBOT_MAIN.TargetSlot].WaferStatus OF
WaferForProccess:
ROBOT_MAIN.TargetStation := CassetteNumber;
//ROBOT_MAIN.Size := CASSETTE_MAIN[CassetteNumber].Signal.Wafer[ROBOT_MAIN.TargetSlot].Size;
_Step := _Step +1;
ELSE
FOR i := FirstStation TO LastStation DO
IF StationsStatus[i].WaferInfo[0].CassetteNumber = CassetteNumber AND StationsStatus[i].WaferInfo[0].Number = ROBOT_MAIN.TargetSlot THEN
ROBOT_MAIN.TargetStation := i;
_Step := _Step +1;
RETURN;
END_IF
END_FOR
END_CASE
21:
IF NOT RobotStatus.Ist.Busy THEN
CASE PaddleMode OF
ePaddleMode.All, ePaddleMode.UpperPaddle:
ROBOT_MAIN.TargetPuddle := 0;
ePaddleMode.LowerPaddle:
ROBOT_MAIN.TargetPuddle := 1;
END_CASE
CMD[RobotStation] := GetCMD;
_Step := _Step +1;
END_IF
22:
IF RobotStatus.Ist.Busy THEN
_Step := _Step +1;
END_IF
23:
IF NOT RobotStatus.Ist.Busy THEN
IF RobotStatus.WaferInfo[0].Number > 0 OR RobotStatus.WaferInfo[1].Number > 0 THEN
_Step := 30;
ELSE
_Step := 0;
END_IF
END_IF
30:
IF StationsStatus[RobotStation].WaferInfo[0].Number > 0 THEN
NextProcess := StationsStatus[RobotStation].WaferInfo[0].FlowStepNumber +1;
ELSIF StationsStatus[RobotStation].WaferInfo[1].Number > 0 THEN
NextProcess := StationsStatus[RobotStation].WaferInfo[1].FlowStepNumber +1;
ELSE
RETURN;
END_IF
IF CASSETTE_PROCESS[CassetteNumber][ROBOT_MAIN.TargetSlot][NextProcess].TargetStation = 0 THEN
ROBOT_MAIN.TargetStation := CassetteNumber;
ELSE
ROBOT_MAIN.TargetStation := CASSETTE_PROCESS[CassetteNumber][ROBOT_MAIN.TargetSlot][NextProcess].TargetStation;
END_IF
IF StationsStatus[ROBOT_MAIN.TargetStation].WaferInfo[0].Number = 0 THEN
_Step := 50;
ELSE
_Step := 40;
END_IF
40:
IF RobotStatus.Ist.Busy THEN
RETURN;
END_IF
CMD[RobotStation] := ChangeCMD;
_Step := _Step +1;
41:
IF RobotStatus.Ist.Busy THEN
RETURN;
END_IF
IF RobotStatus.WaferInfo[0].Number > 0 THEN
CassetteNumber := RobotStatus.WaferInfo[0].CassetteNumber;
ROBOT_MAIN.TargetSlot := RobotStatus.WaferInfo[0].Number;
ELSIF RobotStatus.WaferInfo[1].Number > 0 THEN
CassetteNumber := RobotStatus.WaferInfo[1].CassetteNumber;
ROBOT_MAIN.TargetSlot := RobotStatus.WaferInfo[1].Number;
ELSE
_Step := 0;
RETURN;
END_IF
_Step := _Step +1;
42:
_Step := 30;
50:
IF StationsStatus[RobotStation].WaferInfo[0].Number > 0 AND StationsStatus[RobotStation].WaferInfo[1].Number = 0 THEN
ROBOT_MAIN.TargetPuddle := 0;
ELSIF StationsStatus[RobotStation].WaferInfo[1].Number > 0 AND StationsStatus[RobotStation].WaferInfo[0].Number = 0 THEN
ROBOT_MAIN.TargetPuddle := 1;
ELSE
RETURN;
END_IF
IF RobotStatus.Ist.Busy THEN
RETURN;
END_IF
CASE StationsStatus[ROBOT_MAIN.TargetStation].StationType OF
TypeCassette:
IF StationsStatus[ROBOT_MAIN.TargetStation].Ist.CloseIn OR CMD[ROBOT_MAIN.TargetStation] = StartCMD THEN
CMD[RobotStation] := PutCMD;
_Step := _Step +1;
END_IF
ELSE
CMD[RobotStation] := PutCMD;
_Step := _Step +1;
END_CASE
51:
IF RobotStatus.Ist.Busy THEN
_Step := _Step +1;
END_IF
52:
IF RobotStatus.Ist.Busy THEN
RETURN;
END_IF
IF StationsStatus[ROBOT_MAIN.TargetStation].OnlyMoveToStation THEN
_Step := 30;
ELSE
_Step := 10;
END_IF
90:
ROBOT_MAIN.RobotControl.bOut_EndOfCycle := TRUE;
IF ROBOT_MAIN.RobotControl.bIn_PGNO_REG THEN
ROBOT_MAIN.RobotControl.bOut_EndOfCycle := FALSE;
_Step := 100;
END_IF
100:
bEmpty := FALSE;
Start := TRUE;
_Step := 0;
END_CASE
]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,368 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.13">
<POU Name="KeyenceCamera_FB" Id="{e04efa2a-35e2-41b0-8dcf-22b085953a3c}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK KeyenceCamera_FB EXTENDS Peripherie_FB
VAR_INPUT
Trigger AT %Q* : BOOL;
Result_Ack AT %Q* : BOOL;
Go_to_Run AT %Q* : BOOL;
Go_to_Setting AT %Q* : BOOL;
rOutProgramNumber AT %Q* : UDINT;
bOutProgramLoadExecute AT %Q* : BOOL;
END_VAR
VAR_OUTPUT
CameraInputData : ARRAY [0..288] OF BYTE;
ResultData128 AT %I* : ARRAY [0..127] OF BYTE;
ResultData32 AT %I* : ARRAY [1..5] OF ARRAY [0..31] OF BYTE;
ToolJudge AT %I* : ARRAY[0..3] OF BYTE;
ToolJudgeArray AT %I* : ARRAY[0..3] OF ARRAY[0..7] OF BOOL;
Trigger_Ready AT %I* : BOOL;
Trigger_Ack AT %I* : BOOL;
Run_Status AT %I* : BOOL;
Result_Ready AT %I* : BOOL;
rInProgramNumber AT %I* : UDINT;
bOutProgramLoadComplete AT %I* : BOOL;
bOutBusy : BOOL;
END_VAR
VAR
i : LWORD;
END_VAR
VAR CONSTANT
SizeDetectionDataSize : USINT := 15;
MappingDataSize : SINT := 79;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[MEMMOVE(ADR(CameraInputData), ADR(ResultData128), SIZEOF(ResultData128));
FOR i := 1 TO 5 DO
MEMMOVE(ADR(CameraInputData)+128+(i-1)*32, ADR(ResultData32[i]), SIZEOF(ResultData32[i]));
END_FOR]]></ST>
</Implementation>
<Method Name="DMC" Id="{823d2044-934c-4f9a-bd4c-2fe6af4ff611}">
<Declaration><![CDATA[METHOD DMC : BOOL
VAR_INPUT
Size : USINT;
Data : REFERENCE TO T_MaxString;
END_VAR
VAR_INST
Step : INT;
Counter : INT;
ManualData : T_MaxString;
END_VAR
VAR CONSTANT
cProgram : UDINT := 400;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE Step OF
0:
IF bOutBusy THEN
RETURN;
END_IF
bOutBusy := TRUE;
Step := 10;
Counter := 0;
10:
IF RunProgram(cProgram+Size) THEN
Step := 20;
END_IF
20:
CASE CameraInputData[28] OF
0:
Counter := Counter +1;
IF Counter > 3 THEN
DMC := TRUE;
Step := 0;
bOutBusy := FALSE;
//Step := 110;
ELSE
Step := 10;
END_IF
1:
Step := 30;
END_CASE
30:
Data := '';
MEMMOVE(ADR(Data), ADR(CameraInputData[30]), CameraInputData[29]);
DMC := TRUE;
Step := 0;
bOutBusy := FALSE;
40:
Data := ManualData;
DMC := TRUE;
bOutBusy := FALSE;
Step := 0;
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="GetCurrentCameraPosition" Id="{7a36b66a-c0d0-4d66-a705-d59bc7557dd3}">
<Declaration><![CDATA[METHOD GetCurrentCameraPosition : ARRAY[0..MaxNumberOfSubstratesPerTray-1] OF ARRAY[0..1] OF UINT;
VAR_INPUT
END_VAR
VAR
i : INT;
DummyData : ARRAY[0..1] OF BYTE;
END_VAR
VAR_INST
Data : ARRAY[0..MaxNumberOfSubstratesPerTray*4-1] OF BYTE;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[MEMMOVE(ADR(Data), ADR(CameraInputData[29]), SIZEOF(Data));
FOR i := 0 TO MaxNumberOfSubstratesPerTray-1 DO
DummyData[0] := Data[(i)*4+1];
DummyData[1] := Data[(i)*4];
MEMMOVE(ADR(GetCurrentCameraPosition[i][0]), ADR(DummyData), SIZEOF(DummyData));
DummyData[0] := Data[(i)*4+3];
DummyData[1] := Data[(i)*4+2];
MEMMOVE(ADR(GetCurrentCameraPosition[i][1]), ADR(DummyData), SIZEOF(DummyData));
END_FOR]]></ST>
</Implementation>
</Method>
<Method Name="Mapping" Id="{e769376f-5b47-48bb-b89d-28e7c6e5ce78}">
<Declaration><![CDATA[METHOD Mapping : BOOL
VAR_INPUT
Size : USINT;
Out : REFERENCE TO ARRAY[1..MaxNumberOfSubstratesPerTray] OF BYTE;
END_VAR
VAR_INST
Step : INT;
Data : ARRAY[0..MaxNumberOfSubstratesPerTray*4-1] OF BYTE;
NumberOfSubstrateDetected : SINT;
MappingArrayPosition : ARRAY[1..MaxNumberOfSubstratesPerTray] OF ARRAY[0..1] OF UINT;
MaxNumberOfWafer : INT;
_Size : USINT;
END_VAR
VAR
i,j : INT;
DummyData : ARRAY[0..1] OF BYTE;
X, Y : DINT;
END_VAR
VAR CONSTANT
cProgram : UDINT := 100;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE Step OF
0:
_Size := Size;
IF bOutBusy THEN
RETURN;
END_IF
bOutBusy := TRUE;
Step := 20;
20:
IF _Size > 0 THEN
IF RunProgram(cProgram+_Size) THEN
Step := 30;
END_IF
END_IF
30:
FOR i := 1 TO MaxNumberOfSubstratesPerTray DO
Out[i] := 0;
END_FOR
NumberOfSubstrateDetected := BYTE_TO_SINT(CameraInputData[28]);
MaxNumberOfWafer := ROBOT_MAIN.Config.SubstrateInformation[_Size].MaxNumber;
IF NumberOfSubstrateDetected = MaxNumberOfWafer THEN
FOR i := 1 TO NumberOfSubstrateDetected DO
Out[i] := 1;
END_FOR
Step := 100;
ELSIF NumberOfSubstrateDetected > 0 THEN
Step := 40;
ELSE
Step := 100;
END_IF
40:
MappingArrayPosition := GetCurrentCameraPosition();
MaxNumberOfWafer := ROBOT_MAIN.Config.SubstrateInformation[_Size].MaxNumber;
i := 1;
Step := 50;
50:
IF i > MaxNumberOfWafer THEN
Step := 100;
ELSE
Step := 60;
END_IF
60:
FOR j := 1 TO NumberOfSubstrateDetected DO
X := UINT_TO_DINT(CASSETTE_MAIN[FirstCassette].Config.TeachPosition[_Size].Position[i].Camera[0]) - UINT_TO_DINT(MappingArrayPosition[j][0]);
Y := UINT_TO_DINT(CASSETTE_MAIN[FirstCassette].Config.TeachPosition[_Size].Position[i].Camera[1]) - UINT_TO_DINT(MappingArrayPosition[j][1]);
IF ABS(X) < 50 AND ABS(Y) < 50 THEN
Out[i] := 1;
EXIT;
END_IF
END_FOR
i := i +1;
Step := 50;
100:
Mapping := TRUE;
Step := 0;
bOutBusy := FALSE;
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="RunProgram" Id="{cd0e6869-d425-4e3a-8113-1920b8b06cec}">
<Declaration><![CDATA[METHOD RunProgram : BOOL
VAR_INPUT
In : UDINT;
END_VAR
VAR_INST
Step : INT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE Step OF
0:
Go_to_Run := TRUE;
IF Run_Status THEN
Go_to_Run := FALSE;
Step := 10;
END_IF
10:
rOutProgramNumber := In;
IF rInProgramNumber = rOutProgramNumber THEN
Step := 20;
ELSE
Step := Step +1;
END_IF
11:
bOutProgramLoadExecute := TRUE;
IF bOutProgramLoadComplete THEN
bOutProgramLoadExecute := FALSE;
Step := 10;
END_IF
20:
IF Trigger_Ready THEN
Trigger := TRUE;
Step := Step +1;
END_IF
21:
IF Trigger_Ack THEN
Trigger := FALSE;
Step := Step +1;
END_IF
22:
IF Result_Ready THEN
Result_Ack := TRUE;
Step := Step +1;
END_IF
23:
IF NOT Result_Ready THEN
Result_Ack := FALSE;
Step := 30;
END_IF
30:
RunProgram := TRUE;
Step := 0;
END_CASE]]></ST>
</Implementation>
</Method>
<Method Name="SizeDetection" Id="{ef8e9d1a-4440-4fe2-97d1-cebcaf436cc6}">
<Declaration><![CDATA[METHOD SizeDetection : BOOL
VAR CONSTANT
cProgram : UDINT := 1;
END_VAR
VAR_INPUT
Stop : BOOL := FALSE;
END_VAR
VAR_OUTPUT
Out : USINT;
END_VAR
VAR_INST
Step : INT;
Data : ARRAY[0..SizeDetectionDataSize] OF BYTE;
Found : BOOL;
Counter : INT;
SizeFound : USINT;
END_VAR
VAR
i : USINT;
j : SINT;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF Stop THEN
Step := 0;
RETURN;
END_IF
CASE Step OF
0:
IF bOutBusy THEN
RETURN;
END_IF
bOutBusy := TRUE;
Step := 10;
SizeFound := 0;
Found := FALSE;
Counter := 0;
10:
IF Counter < 3 THEN
Step := 20;
ELSE
Step := 110;
END_IF
20:
IF RunProgram(cProgram) THEN
Step := 30;
END_IF
30:
MEMMOVE(ADR(Data), ADR(CameraInputData[28]), SIZEOF(Data));
FOR i := 0 TO SizeDetectionDataSize DO
FOR j := 0 TO 7 DO
IF GETBIT32(Data[i], j) AND NOT Found THEN
SizeFound := i * 8 + SINT_TO_USINT(j) + 1;
Found := TRUE;
ELSIF GETBIT32(Data[i], j) AND Found THEN
SizeFound := 0;
Counter := Counter +1;
Step := 10;
RETURN;
END_IF
END_FOR
END_FOR
IF Found THEN
Step := 40;
ELSE
Counter := Counter +1;
Step := 10;
END_IF
40:
Out := SizeFound;
SizeDetection := TRUE;
Step := 0;
bOutBusy := FALSE;
110:
SizeDetection := TRUE;
Out := 0;
Step := 0;
bOutBusy := FALSE;
END_CASE]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>