Initial
This commit is contained in:
394
PLC/5 Relax/POUs/RETRY_MAIN_FB.TcPOU
Normal file
394
PLC/5 Relax/POUs/RETRY_MAIN_FB.TcPOU
Normal file
@@ -0,0 +1,394 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.13">
|
||||
<POU Name="RETRY_MAIN_FB" Id="{deb316fa-00f1-498b-8982-796ab9b4b8f3}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK RETRY_MAIN_FB EXTENDS Station_GENERAL_MAIN_FB
|
||||
VAR_INPUT
|
||||
RetryFlowName : T_MaxString;
|
||||
END_VAR
|
||||
VAR_OUTPUT
|
||||
END_VAR
|
||||
VAR
|
||||
Recipe : sCassetteRecipe;
|
||||
RecipeLoad : sCassetteRecipe;
|
||||
RecipeRead : sCassetteRecipe;
|
||||
|
||||
ProcessCounter : USINT;
|
||||
Processes : ARRAY [1..MaxNumberOfProcesses] OF sProcess;
|
||||
CurrentTime : DT;
|
||||
|
||||
CassetteNumber : INT;
|
||||
WaferNumber : INT;
|
||||
|
||||
SavedScheduler : sFullScheduler;
|
||||
END_VAR
|
||||
VAR CONSTANT
|
||||
MaxNumberOfProcesses : INT := 100;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[]]></ST>
|
||||
</Implementation>
|
||||
<Folder Name="Scheduler" Id="{5f836bb7-6d1d-47d6-983e-32b9efe1e071}" />
|
||||
<Method Name="CheckAlternative" Id="{847d1c23-a152-443d-82f0-cba1c1fc607b}" FolderPath="Scheduler\">
|
||||
<Declaration><![CDATA[METHOD CheckAlternative : BOOL
|
||||
VAR_OUTPUT
|
||||
NoAlternative : BOOL;
|
||||
END_VAR
|
||||
VAR
|
||||
i,j,k : INT;
|
||||
TargetStation : INT;
|
||||
END_VAR
|
||||
VAR_INST
|
||||
Step : INT;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[CASE Step OF
|
||||
0: //Check ready Station
|
||||
FOR i := 1 TO ProcessCounter DO
|
||||
FOR j := 1 TO Processes[i].NumberOfAlternative DO
|
||||
TargetStation := Processes[i].Alternative[j];
|
||||
CASE StationsStatus[TargetStation].StationType OF
|
||||
TypeRobot:
|
||||
;
|
||||
ELSE
|
||||
IF OperationMode[TargetStation] = AutomaticMode AND StationsStatus[TargetStation].Ist.InitDone THEN
|
||||
StationsStatus[TargetStation].Soll.CheckFlowName := Processes[i].Recipe;
|
||||
StationsStatus[TargetStation].Soll.CheckFlow := TRUE;
|
||||
StationsStatus[TargetStation].StandbyNotAllowed := TRUE;
|
||||
//CheckFlowGripperSize[TargetStation] := TrayFeeder.SubstrateGripperSize;
|
||||
END_IF
|
||||
END_CASE
|
||||
END_FOR
|
||||
END_FOR
|
||||
Step := 10;
|
||||
10: //Wait till all Station are Checked
|
||||
FOR k := FirstStation TO LastStation DO
|
||||
IF StationsStatus[k].Soll.CheckFlow THEN
|
||||
RETURN;
|
||||
END_IF
|
||||
END_FOR
|
||||
Step := 20;
|
||||
20: //Remove unready Station
|
||||
FOR i := 1 TO ProcessCounter DO
|
||||
FOR j := 1 TO Processes[i].NumberOfAlternative DO
|
||||
TargetStation := Processes[i].Alternative[j];
|
||||
CASE StationsStatus[TargetStation].StationType OF
|
||||
TypeRobot:
|
||||
;
|
||||
ELSE
|
||||
IF NOT StationsStatus[TargetStation].Ist.ReadyForFlow THEN
|
||||
Processes[i].Alternative[j] := 0;
|
||||
END_IF
|
||||
END_CASE
|
||||
END_FOR
|
||||
END_FOR
|
||||
Step := 30;
|
||||
30: //Sort Alternative
|
||||
FOR k := 1 TO ProcessCounter DO
|
||||
Processes[k] := SortAlternative(Processes[k]);
|
||||
IF Processes[k].NumberOfAlternative = 0 THEN
|
||||
NoAlternative := TRUE;
|
||||
CheckAlternative := TRUE;
|
||||
Step := 0;
|
||||
RETURN;
|
||||
END_IF
|
||||
END_FOR
|
||||
Step := 40;
|
||||
40:
|
||||
CheckAlternative := TRUE;
|
||||
Step := 0;
|
||||
END_CASE
|
||||
|
||||
]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="CloseInOut" Id="{9a2c1df1-32c8-4c19-9779-06f2021fcd3a}">
|
||||
<Declaration><![CDATA[METHOD CloseInOut : BOOL
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[CASE _Step OF
|
||||
0:
|
||||
CASE iCMD OF
|
||||
CloseInCMD:
|
||||
IF CMD[FirstStation] = StartCMD THEN
|
||||
_Step := 10;
|
||||
ELSE
|
||||
iStationStatus.Soll.AutoStart := FALSE;
|
||||
_Step := 100;
|
||||
END_IF
|
||||
CloseOutCMD:
|
||||
_Step := 100;
|
||||
END_CASE
|
||||
10:
|
||||
CassetteNumber := iStationStatus.WaferInfo[0].CassetteNumber;
|
||||
WaferNumber := iStationStatus.WaferInfo[0].Number;
|
||||
_Step := _Step +1;
|
||||
11:
|
||||
IF DeleteWaferFromScheduler(CassetteNumber, WaferNumber) THEN
|
||||
_Step := 20;
|
||||
END_IF
|
||||
20:
|
||||
iStationStatus.RecipeName := RetryFlowName;
|
||||
IF noCMD = RecipeManagement.CMD THEN
|
||||
RecipeManagement.ProcessRecipeName := iStationStatus.RecipeName;
|
||||
RecipeManagement.ReadRecipeType := eRecipeType.TypeProcess;
|
||||
RecipeManagement.CMD := CMDLoadRcpToStation;
|
||||
_Step := _Step +1;
|
||||
END_IF
|
||||
21:
|
||||
IF noCMD = RecipeManagement.CMD THEN
|
||||
_Step := 100;
|
||||
END_IF
|
||||
100:
|
||||
_Step := 0;
|
||||
CloseInOut := TRUE;
|
||||
END_CASE]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="FB_Init" Id="{6285961a-ace9-421b-a13a-bc3c048df021}">
|
||||
<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[_NoConfigFile := TRUE;
|
||||
_PersistentProductCheck := TRUE;
|
||||
_VisuName := 'RETRY';
|
||||
_NoService := TRUE;]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="Initialization" Id="{ea43bc97-4ca3-4d50-829b-2e399ae3ef7f}">
|
||||
<Declaration><![CDATA[METHOD Initialization : BOOL
|
||||
VAR_INPUT
|
||||
iStation : INT;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[InitializationExt(iStation);
|
||||
|
||||
iStationStatus.NoRecipe := TRUE;
|
||||
iStationStatus.NoOperationMode := TRUE;
|
||||
|
||||
iStationStatus.NoProductCheck := TRUE;
|
||||
|
||||
iStationStatus.StationName := CONCAT('Retry ', StationIndex);
|
||||
|
||||
|
||||
RecipeStationName[iStation] := 'Flow';
|
||||
RecipeManagement.Initialization(
|
||||
iStation,
|
||||
ADR(RecipeLoad),
|
||||
ADR(CASSETTE_RECIPE_EDITE),
|
||||
ADR(CASSETTE_RECIPE_EMPTY),
|
||||
ADR(RecipeRead),
|
||||
ADR(Recipe),
|
||||
SIZEOF(sCassetteRecipe),
|
||||
'sCassetteRecipe',
|
||||
SIZEOF(sCassetteStepData)
|
||||
);]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="ProcessesBlock" Id="{f9ed0a0a-99f0-4d86-9132-6c68d5626f73}" FolderPath="Scheduler\">
|
||||
<Declaration><![CDATA[METHOD ProcessesBlock : BOOL;
|
||||
VAR_INPUT
|
||||
END_VAR
|
||||
VAR
|
||||
i,j : USINT;
|
||||
DummyTime : TIME;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[ProcessCounter := 0;
|
||||
FOR i := 1 TO Recipe.STEP_COUNT DO
|
||||
//Robot Block
|
||||
ProcessCounter := ProcessCounter +1;
|
||||
Processes[ProcessCounter].StartTime := CurrentTime;
|
||||
|
||||
IF StationsStatus[RecipeGetStationType(Recipe.DATA[i].StationType)].OnlyMoveToStation THEN
|
||||
CurrentTime := CurrentTime + LINT_TO_TIME(TimeBetweenProcesses*500);
|
||||
ELSE
|
||||
CurrentTime := CurrentTime + LINT_TO_TIME(TimeBetweenProcesses*1000);
|
||||
END_IF
|
||||
|
||||
Processes[ProcessCounter].EndTime := CurrentTime;
|
||||
Processes[ProcessCounter].StationType := TypeRobot;
|
||||
Processes[ProcessCounter].Alternative[1] := RobotStation;
|
||||
Processes[ProcessCounter].NumberOfAlternative := 1;
|
||||
ProcessCounter := ProcessCounter +1;
|
||||
//
|
||||
|
||||
//Process Block
|
||||
Processes[ProcessCounter].StartTime := CurrentTime;
|
||||
DummyTime := GetSchedulerStationTime(RecipeGetStationType(Recipe.DATA[i].StationType), Recipe.DATA[i].RecipeName, FALSE);
|
||||
// IF AND DummyTime = T#60M THEN
|
||||
// ProcessesBlock := FALSE;
|
||||
// RETURN;
|
||||
// END_IF
|
||||
CurrentTime := CurrentTime + DummyTime;
|
||||
Processes[ProcessCounter].EndTime := CurrentTime;
|
||||
Processes[ProcessCounter].Recipe := Recipe.DATA[i].RecipeName;
|
||||
Processes[ProcessCounter].StationType := RecipeGetStationType(Recipe.DATA[i].StationType);
|
||||
Processes[ProcessCounter].Alternative := FindAlternativeList(RecipeGetStationType(Recipe.DATA[i].StationType), Recipe.DATA[i].Alternative);
|
||||
|
||||
Processes[ProcessCounter].Retry := Recipe.DATA[i].Retry;
|
||||
// Processes[ProcessCounter].Defect := NOT Recipe.DATA[i].Retry;
|
||||
Processes[ProcessCounter].RetryFlowName := Recipe.DATA[i].RetryFlowName;
|
||||
|
||||
FOR j := 1 TO MaxNumberOfAlternative DO
|
||||
IF Processes[ProcessCounter].Alternative[j] > 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;]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Method Name="Start" Id="{bfa08185-d4a7-43d8-b8d6-51e46e7e25f8}">
|
||||
<Declaration><![CDATA[METHOD Start : BOOL
|
||||
VAR_INST
|
||||
i : INT;
|
||||
j : UINT;
|
||||
|
||||
FlowStepNumber : UINT;
|
||||
|
||||
|
||||
OldTimeAsDT : DT;
|
||||
|
||||
FirstLevelScheduler : sFullScheduler;
|
||||
SecondLevelScheduler : sFullScheduler;
|
||||
|
||||
StepCounter : INT;
|
||||
|
||||
NoAlternative : BOOL;
|
||||
|
||||
AlternativeCounter : INT;
|
||||
TargetStation : INT;
|
||||
NumberOfJob : INT;
|
||||
|
||||
RobotHasSubstrate : BOOL;
|
||||
END_VAR]]></Declaration>
|
||||
<Implementation>
|
||||
<ST><![CDATA[RobotHasSubstrate := StationsStatus[RobotStation].WaferInfo[0].Number > 0 OR StationsStatus[RobotStation].WaferInfo[1].Number > 0;
|
||||
IF StationsStatus[RobotStation].Ist.Busy OR RobotHasSubstrate THEN
|
||||
IF _Step >= 0 AND _Step < 40 THEN
|
||||
_Step := 0;
|
||||
RETURN;
|
||||
END_IF
|
||||
END_IF
|
||||
|
||||
CASE _Step OF
|
||||
0:
|
||||
FOR i := FirstLelaxStation TO LastRelaxStation DO
|
||||
IF i <> iStation THEN
|
||||
IF iStationStatus.WaferInfo[0].Number > StationsStatus[i].WaferInfo[0].Number and StationsStatus[i].WaferInfo[0].Number <> 0 THEN
|
||||
RETURN;
|
||||
END_IF
|
||||
END_IF
|
||||
END_FOR
|
||||
|
||||
CurrentTime := timeAsDT;
|
||||
IF OldtimeAsDT <> timeAsDT THEN
|
||||
OldtimeAsDT := CurrentTime;
|
||||
_Step := _Step +1;
|
||||
END_IF
|
||||
1:
|
||||
IF ProcessesBlock() THEN
|
||||
_Step := 10;
|
||||
ELSE
|
||||
_Step := 0;
|
||||
END_IF
|
||||
10:
|
||||
IF CheckAlternative(NoAlternative => NoAlternative) THEN
|
||||
IF NoAlternative THEN
|
||||
_Step := 0;
|
||||
ELSE
|
||||
SavedScheduler := Scheduler;
|
||||
SecondLevelScheduler := Scheduler;
|
||||
StepCounter := 0;
|
||||
_Step := 20;
|
||||
END_IF
|
||||
END_IF
|
||||
20:
|
||||
StepCounter := StepCounter +1;
|
||||
IF StepCounter > ProcessCounter THEN
|
||||
_Step := 40;
|
||||
ELSE
|
||||
FirstLevelScheduler := SecondLevelScheduler;
|
||||
_Step := 30;
|
||||
END_IF
|
||||
30:
|
||||
AlternativeCounter := 0;
|
||||
_Step := _Step +1;
|
||||
31:
|
||||
AlternativeCounter := AlternativeCounter +1;
|
||||
IF AlternativeCounter > Processes[StepCounter].NumberOfAlternative THEN
|
||||
_Step := 0;
|
||||
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 := CassetteNumber;
|
||||
SecondLevelScheduler[TargetStation].Job[NumberOfJob].WaferNumber := WaferNumber;
|
||||
SecondLevelScheduler[TargetStation].NumberOfjob := NumberOfJob +1;
|
||||
|
||||
IF CheckReservation(SecondLevelScheduler, TargetStation) THEN
|
||||
Processes[StepCounter].TargetStation := TargetStation;
|
||||
FirstLevelScheduler := SecondLevelScheduler;
|
||||
_Step := 20;
|
||||
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 := 0;
|
||||
RETURN;
|
||||
END_IF
|
||||
END_IF
|
||||
END_FOR
|
||||
|
||||
|
||||
IF SchedulerChangeOk(SavedScheduler) THEN
|
||||
Scheduler := FirstLevelScheduler;
|
||||
ELSE
|
||||
_Step := 0;
|
||||
RETURN;
|
||||
END_IF
|
||||
|
||||
FlowStepNumber := iStationStatus.WaferInfo[0].FlowStepNumber;
|
||||
|
||||
FOR j := 2 TO ProcessCounter BY 2 DO
|
||||
CASSETTE_PROCESS[CassetteNumber][WaferNumber][FlowStepNumber+j/2].TargetStation := Processes[j].TargetStation;
|
||||
CASSETTE_PROCESS[CassetteNumber][WaferNumber][FlowStepNumber+j/2].Recipe := Processes[j].Recipe;
|
||||
|
||||
CASSETTE_PROCESS[CassetteNumber][WaferNumber][FlowStepNumber+j/2].Retry := Processes[j].Retry;
|
||||
CASSETTE_PROCESS[CassetteNumber][WaferNumber][FlowStepNumber+j/2].RetryFlowName := Processes[j].RetryFlowName;
|
||||
END_FOR
|
||||
|
||||
_Step := 90;
|
||||
90:
|
||||
Start := TRUE;
|
||||
_Step := 0;
|
||||
END_CASE]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
</POU>
|
||||
</TcPlcObject>
|
||||
Reference in New Issue
Block a user