START_TIME ); Signal.START_TIME := START_TIME; START_TIME := CONCAT(LOG_MAIN_PATH, START_TIME); CreateDir(sPathName := START_TIME, bExecute := TRUE); _Step := _Step +1; 41: IF CreateDir.bError THEN _Step := 50; ELSIF NOT CreateDir.bBusy THEN _Step := 50; END_IF CreateDir(bExecute := FALSE); 50: IF LEN(Signal.LotID) > 0 THEN ; ELSE format := '%02.0f%02.0f'; faTime[0] := LocalTime.wHour; faTime[1] := LocalTime.wMinute; fbFormat( sFormat:=format, arg1:= F_REAL (faTime[0]), arg2:= F_REAL (faTime[1]), sOut=> Signal.LotID ); END_IF StringWithLotID := CONCAT(LOG_MAIN_PATH, Signal.START_TIME); StringWithLotID := CONCAT(StringWithLotID, '/'); StringWithLotID := CONCAT(StringWithLotID, Signal.LotID); _Step := 60; 60: CreateDir(sPathName := StringWithLotID, bExecute := TRUE); _Step := _Step +1; 61: IF CreateDir.bError THEN _Step := 100; ELSIF NOT CreateDir.bBusy THEN _Step := 100; END_IF CreateDir(bExecute := FALSE); 100: CloseInOut := TRUE; _Step := 0; END_CASE ]]> 0 THEN JobList := EmptyList; Counter := 0; Path := CONCAT(JOB_MAIN_PATH, JobID); Path := CONCAT(Path, '.txt'); Step := 10; END_IF 10: fbFileOpen( sPathName := Path, nMode := FOPEN_MODEREAD, bExecute := TRUE ); IF fbFileOpen.bError THEN Step := 110; ELSIF fbFileOpen.bBusy THEN Step := Step +1; END_IF 11: IF fbFileOpen.bError THEN Step := 110; ELSIF NOT fbFileOpen.bBusy THEN hFile := fbFileOpen.hFile; Step := 20; END_IF fbFileOpen(bExecute := FALSE); 20: fbFileGets( hFile := hFile, bExecute := TRUE ); IF fbFileGets.bError THEN Step := 110; ELSIF fbFileGets.bBusy THEN Step := Step +1; END_IF 21: IF fbFileGets.bError THEN Step := 110; ELSIF fbFileGets.bEOF THEN Step := 30; ELSIF NOT fbFileGets.bBusy THEN JobList[Counter] := fbFileGets.sLine; Counter := Counter +1; Step := 20; END_IF fbFileGets(bExecute := FALSE); 30: fbFileClose( hFile := hFile, bExecute := TRUE ); IF fbFileClose.bError THEN Step := 110; ELSIF fbFileClose.bBusy THEN Step := Step +1; END_IF 31: IF fbFileClose.bError THEN Step := 110; ELSIF NOT fbFileClose.bBusy THEN Step := 40; END_IF fbFileClose(bExecute := FALSE); 40: FOR i := 0 TO Counter -1 DO Pos := find(JobList[i], '$N'); IF Pos > 0 THEN JobList[i] := LEFT(JobList[i], Pos-1); END_IF END_FOR Step := 50; 100: ExternalControl := TRUE; Step := 0; 110: JobID := ''; Step := 0; END_CASE]]> 0 THEN Counter := Counter +1; END_IF IF StationsStatus[i].WaferInfo[1].Number > 0 THEN Counter := Counter +1; END_IF END_FOR GetNumberOfSubstrateInSystem := Counter;]]> 0 THEN NIO_ToUnload := TRUE; END_IF CASE Step OF 0: IF NIO_ToProduction THEN NIO_InProduction := FALSE; NIO_InUnload := FALSE; Step := 10; END_IF IF NIO_ToUnload THEN NIO_InProduction := FALSE; NIO_InUnload := FALSE; Step := 50; END_IF 10: IF IO.DoorLock.Lock() THEN Step := 20; END_IF 20: IF IO.TrayLock[1].Up() AND IO.TrayLock[2].Up() THEN NIO_ToProduction := FALSE; NIO_InProduction := TRUE; Step := 0; END_IF 50: IF IO.TrayLock[1].Down() AND IO.TrayLock[2].Down() THEN Step := 60; END_IF 60: IO.DoorLock.UnLock(); FOR i := 1 TO 50 DO CASSETTE_MAIN[LastCassette].Signal.Wafer[i].WaferStatus := noWafer; END_FOR NIO_ToUnload := FALSE; NIO_InUnload := TRUE; Step := 0; END_CASE]]> 0 THEN Processes[ProcessCounter].NumberOfAlternative := j; END_IF END_FOR // END_FOR //Final Robot Block ProcessCounter := ProcessCounter +1; Processes[ProcessCounter].StartTime := CurrentTime; CurrentTime := CurrentTime + LINT_TO_TIME(TimeBetweenProcesses*1000); Processes[ProcessCounter].EndTime := CurrentTime; Processes[ProcessCounter].StationType := TypeRobot; Processes[ProcessCounter].Alternative[1] := RobotStation; Processes[ProcessCounter].NumberOfAlternative := 1; ProcessesBlock := TRUE;]]> noCMD THEN RETURN; END_IF END_CASE END_FOR Step := 10; 10://Find Step Type FOR i := 0 TO FlowRecipeTypeCounter DO IF CurrentStepStationType = FlowRecipeTypeFound[i] THEN CurrentStepRecipeList := StationsStatus[CurrentStepStationType].IRecipe.GetProcessList; FlowRecipeSelectedTypeIndex := i; Step := 30; RETURN; END_IF END_FOR 30://Find Step Recipe IF CASSETTE_RECIPE_EDITE.DATA[RecipeCurrentStep].RecipeName <> '' THEN FOR j := 1 TO CurrentStepRecipeList.NumberOfRecipe DO IF CASSETTE_RECIPE_EDITE.DATA[RecipeCurrentStep].RecipeName = CurrentStepRecipeList.RecipeList[j] THEN FlowRecipeSellectedRecipe := j; Step := 40; RETURN; END_IF END_FOR END_IF FlowRecipeSellectedRecipe := 0; Step := 40; 40://Find Step Alternative CurrentStepOld := RecipeCurrentStep; Timer(IN := TRUE, PT := T#100MS); IF Timer.Q THEN Timer(IN := FALSE); Step := 100; END_IF 100: IF CurrentStepOld <> RecipeCurrentStep THEN Step := 10; VisuCassetteMaxNumberOfRecipe := 100; RETURN; END_IF VisuCassetteMaxNumberOfRecipe := CurrentStepRecipeList.NumberOfRecipe; IF CASSETTE_RECIPE_EDITE.DATA[RecipeCurrentStep].Alternative = 0 THEN CASSETTE_RECIPE_EDITE.DATA[RecipeCurrentStep].Alternative := 2; END_IF IF iStationStatus.Soll.RecipeExit THEN Step := 0; iStationStatus.Ist.Recipe := FALSE; iStationStatus.Soll.RecipeExit := FALSE; RETURN; END_IF END_CASE]]> timeAsDT THEN _Step := 20; END_IF ELSE WaferCounter := WaferCounter +1; END_IF IF WaferCounter > MaxNumberOfWafer OR WaferCounter = 0 OR iCMD <> StartCMD THEN _Step := 90; END_IF 20: ProcessCounter := 0; CurrentTime := timeAsDT + UDINT_TO_TIME(TimeCounter*1000); IF TimeCounter > 10 THEN TimeCounter := 0; OldtimeAsDT := timeAsDT; END_IF TimeCounter := TimeCounter +1; IF NOT ProcessesBlock() THEN _Step := 10; RETURN; END_IF _Step := _Step +1; 21: IF CheckAlternative(NoAlternative => NoAlternative) THEN IF NoAlternative THEN _Step := 10; ELSE SavedScheduler := Scheduler; SecondLevelScheduler := Scheduler; StepCounter := 0; _Step := 30; END_IF END_IF 30: StepCounter := StepCounter +1; IF StepCounter > ProcessCounter THEN _Step := 40; ELSE FirstLevelScheduler := SecondLevelScheduler; _Step := 35; END_IF 35: AlternativeCounter := 0; _Step := _Step +1; 36: AlternativeCounter := AlternativeCounter +1; IF AlternativeCounter > Processes[StepCounter].NumberOfAlternative THEN _Step := 10; RETURN; END_IF TargetStation := Processes[StepCounter].Alternative[AlternativeCounter]; NumberOfJob := SecondLevelScheduler[TargetStation].NumberOfjob; SecondLevelScheduler[TargetStation].Job[NumberOfJob].StartTime := Processes[StepCounter].StartTime; SecondLevelScheduler[TargetStation].Job[NumberOfJob].EndTime := Processes[StepCounter].EndTime; SecondLevelScheduler[TargetStation].Job[NumberOfJob].CassetteNumber := iStation; SecondLevelScheduler[TargetStation].Job[NumberOfJob].WaferNumber := WaferCounter; SecondLevelScheduler[TargetStation].NumberOfjob := NumberOfJob +1; IF CheckReservation(SecondLevelScheduler, TargetStation) THEN Processes[StepCounter].TargetStation := TargetStation; FirstLevelScheduler := SecondLevelScheduler; _Step := 30; ELSE SecondLevelScheduler := FirstLevelScheduler; END_IF 40: FOR i := FirstStation TO LastStation DO IF NOT StationsStatus[i].OnlyMoveToStation THEN IF NOT CheckReservation(FirstLevelScheduler, i) THEN _Step := 10; RETURN; END_IF END_IF END_FOR IF SchedulerChangeOk(SavedScheduler) THEN Scheduler := FirstLevelScheduler; ELSE _Step := 10; RETURN; END_IF FOR i := 2 TO ProcessCounter BY 2 DO CASSETTE_PROCESS[iStation][WaferCounter][i/2].TargetStation := Processes[i].TargetStation; CASSETTE_PROCESS[iStation][WaferCounter][i/2].Recipe := Processes[i].Recipe; //CASSETTE_PROCESS[iStation].Cassette[WaferCounter].WaferProcess[i/2].Defect := Processes[i].Defect; CASSETTE_PROCESS[iStation][WaferCounter][i/2].Retry := Processes[i].Retry; CASSETTE_PROCESS[iStation][WaferCounter][i/2].RetryFlowName := Processes[i].RetryFlowName; CASSETTE_PROCESS[iStation][WaferCounter][i/2].MaxLaytime := Processes[i].MaxLaytime; CASSETTE_PROCESS[iStation][WaferCounter][i/2].NumberOfAlternative := Processes[i].NumberOfAlternative; CASSETTE_PROCESS[iStation][WaferCounter][i/2].Alternative := Processes[i].Alternative; END_FOR _Step := _Step +1; 41: IF StationsStatus[RobotStation].Ist.Busy AND (ROBOT_MAIN.TargetStation <> iStation OR ROBOT_MAIN.TargetSlot <> WaferCounter) THEN _Step := 45; RETURN; END_IF IF bEmpty THEN _Step := 45; RETURN; END_IF IF StationsStatus[RobotStation].Ist.Busy AND ROBOT_MAIN.TargetStation = iStation AND ROBOT_MAIN.TargetSlot = WaferCounter THEN _Step := 42; RETURN; END_IF CASE Signal.Wafer[WaferCounter].WaferStatus OF WaferForProccess: ; WaferInProccess: _Step := 0; WaferNotForProccess, noWafer: _Step := 45; END_CASE 42: CASE Signal.Wafer[WaferCounter].WaferStatus OF WaferInProccess: _Step := 0; noWafer: _Step := 45; END_CASE 45: IF DeleteWaferFromScheduler(iStation, WaferCounter) THEN _Step := 0; END_IF 90: FOR i := 1 TO MaxNumberOfWafer DO IF Signal.Wafer[i].WaferStatus = WaferInProccess THEN _Step := 0; RETURN; END_IF END_FOR _Step := 100; 100: Signal.LotID := ''; Start := TRUE; _Step := 0; END_CASE ]]>