PLC游戲來了!猜猜它是干什么的?
FUNCTION_BLOCK FB01
VAR_INPUT
PositionDB : INT;
ForceDB : INT;
AnalysisMode : INT;
NumPointsAverage : INT;
ServoPosOffest : REAL;
LgDiaForceDelta : REAL;
SmDiaForceDelta : REAL;
MinForceExpected : REAL;
PointOffset : INT;
END_VAR
VAR_IN_OUT
DoneGood : BOOL;
DoneFail : BOOL;
END_VAR
VAR_OUTPUT
FinalForce : REAL;
SmDia_StartForce : REAL;
SmDia_StartPosition : REAL;
SmDia_EndForce : REAL;
SmDia_EndPosition : REAL;
LgDia_StartForce : REAL;
LgDia_StartPosition : REAL;
END_VAR
VAR
iInitData:INT:=1;
Seq:STRUCT
bStart:BOOL;
bStartEdgeStore:BOOL;
iStepNo:INT;
END_STRUCT;
temp : BOOL;
PositionDBWord : WORD;
ForceDBWord : WORD;
x : WORD;
y : INT;
z : DWORD;
i : INT;
j : INT;
Count: INT;
Arraycounter: INT;
kk :INT;
L: WORD; // Position
LL: DWORD; // StatForce
PreviousForce :REAL;
FinalPosition :REAL;
NumberOfDataPoints :INT;
CurrentForce :REAL;
CurrentPosition :REAL;
Acc_Real :REAL;
ChangeInPosition :REAL;
ChangeInForce :REAL;
StartIndex :INT;
Zone2StartIndex :INT;
Zone2EndIndex:INT;
SmallDia_Start_Index :INT;
Peak_Force_Temp :REAL;
Current_Force_T :REAL;
Previous_Force_Temp :REAL;
SumArray_Force :REAL;
TransArrayForce :REAL;
StartPosition :REAL;
LgDia_StartForce_Temp : REAL;
LgDia_StartPosition_Temp: REAL;
TransitionForce :ARRAY [1..30] OF REAL;
TransitionPosition :ARRAY [1..30] OF REAL;
END_VAR
LABEL
Fail;
Done;
TopOfCurve;
Scanning;
LgDiaStart;
SmDiaEnd;
SmDiaStart;
TransitionForceCase;
END_LABEL
BEGIN
CASE Seq.iStepNo of
0: //init data
// Code Section
FinalForce := 0.0;
SmDia_StartForce := 0.0;
SmDia_StartPosition := 0.0;
SmDia_EndForce := 0.0;
SmDia_EndPosition := 0.0;
LgDia_StartForce := 0.0;
LgDia_StartPosition := 0.0;
PreviousForce := 0.0;
FinalPosition:= 0.0;
CurrentForce := 0.0;
CurrentPosition := 0.0;
Acc_Real := 0.0;
ChangeInPosition := 0.0;
ChangeInForce := 0.0;
Peak_Force_Temp := 0.0;
Current_Force_T :=0.0;
Previous_Force_Temp:= 0.0;
DoneGood := 0;
DoneFail := 0;
Arraycounter:=1;
//Array Intialization
// TransitionForce[1..30] OF Real: = 30(0);
FOR Count:= 1 TO 30 DO
TransitionForce [Count] :=0;
TransitionPosition [Count] :=0;
END_FOR;
PositionDBWord := INT_TO_WORD(PositionDB);
ForceDBWord := INT_TO_WORD(ForceDB);
//find number of data points
x := WORD_TO_BLOCK_DB(PositionDBWord).DW[2];
NumberOfDataPoints := WORD_TO_INT (x) - 1; //Data Starts at Zero
y := (NumberOfDataPoints * 4) + 4;
z := WORD_TO_BLOCK_DB(ForceDBWord).DD[y];
Acc_Real := DWORD_TO_REAL (z);
IF NumPointsAverage > NumberOfDataPoints Then
Seq.iStepNo:=99;// Fail;
ELSE
Seq.iStepNo:=Seq.istepNo+1;
END_IF;
//.....................
// Find the final force by taking the average of the
// data points at the end of the curve. The number
// of data points is an input to the FC.
1:
FOR i := (NumberOfDataPoints - 1)TO (NumberOfDataPoints - NumPointsAverage + 1) BY -1 DO
//Add Current Force To Acc_Real
y := (i * 4) + 4;
z := WORD_TO_BLOCK_DB(ForceDBWord).DD[y];
Acc_Real := Acc_Real + DWORD_TO_REAL (z);
END_FOR;
FinalForce := Acc_Real/NumPointsAverage;
Seq.iStepNo:=Seq.istepNo+1;
//.....................
2:
// LOACTION: TOp of the Curve
// Start scanning from top of the Curve to bottom and
y := (NumberOfDataPoints * 4) + 4;
z := WORD_TO_BLOCK_DB(ForceDBWord).DD[y];
Previous_Force_Temp:= DWORD_TO_REAL (z);
FOR i := ((NumberOfDataPoints - 1))TO 10 BY-1 DO
//Get Current Force
y := (i * 4) + 4;
z := WORD_TO_BLOCK_DB(ForceDBWord).DD[y];
Current_Force_T := DWORD_TO_REAL (z);
Peak_Force_Temp:= Current_Force_T;
IF Current_Force_T > Previous_Force_Temp THEN
Peak_Force_Temp:= Current_Force_T;
ELSE
Previous_Force_Temp:= Current_Force_T;
END_IF;
END_FOR;
Seq.iStepNo:=Seq.istepNo+1;
//..............................
3:
// Zone#2= ServoPOS(StartPosition + 5, FinalPosition - Offset Position)
//Get Final Position
y := (NumberOfDataPoints * 4) + 4;
z := WORD_TO_BLOCK_DB(PositionDBWord).DD[y];
FinalPosition := DWORD_TO_REAL (z);
//Get Start Position of the Servo
L:= WORD_TO_BLOCK_DB(PositionDBWord).DW[4];
StartPosition:= DWORD_TO_REAL (L);
LL :=WORD_TO_BLOCK_DB(ForceDBWord).DW[4];
CurrentForce := DWORD_TO_REAL (LL);
FOR i := (NumberOfDataPoints - 1)TO 10 BY -1 DO
//Get Current Position
y := (i * 4) + 4;
z := WORD_TO_BLOCK_DB(PositionDBWord).DD[y];
CurrentPosition := DWORD_TO_REAL (z);
ChangeInPosition := FinalPosition - CurrentPosition;
IF ChangeInPosition > ServoPosOffest THEN
z := WORD_TO_BLOCK_DB(ForceDBWord).DD[y];
PreviousForce := DWORD_TO_REAL (z);
StartIndex := i;
Zone2StartIndex:=i;
Seq.iStepNo:=Seq.istepNo+1;
//..............................
//Location: Start of SmallDia
// SmDia Start Force AND Start Position
FOR j := 1 TO StartIndex BY 1 DO
IF CurrentForce > MinForceExpected THEN
SmDia_StartForce := PreviousForce;
y := ((i+1) * 4) + 4;
z := WORD_TO_BLOCK_DB(PositionDBWord).DD[y];
SmDia_StartPosition := DWORD_TO_REAL (z);
SmallDia_Start_Index:= j;
Seq.iStepNo:=Seq.istepNo+1;
//..............................
ELSE
PreviousForce := CurrentForce;
END_IF;
END_FOR;
//GOTO Scanning;
END_IF;
END_FOR;
Seq.iStepNo:=99; //failt
//..............................
4:
// LOACTION: Start of Large Diameter Press
FOR i := (Zone2StartIndex)TO SmallDia_Start_Index BY -1 DO
//Get Current Force
y := (i * 4) + 4;
z := WORD_TO_BLOCK_DB(ForceDBWord).DD[y];
CurrentForce := DWORD_TO_REAL (z);
ChangeInForce := PreviousForce - CurrentForce;
IF ChangeInForce < SmDiaForceDelta THEN //<100
SmDia_EndForce := PreviousForce;
y := ((i+1) * 4) + 4;
z := WORD_TO_BLOCK_DB(PositionDBWord).DD[y];
SmDia_EndPosition := DWORD_TO_REAL (z);
StartIndex := i;
Zone2ENDIndex:= i;
Seq.iStepNo:=Seq.istepNo+1;
//..............................
ELSE
PreviousForce := CurrentForce;
END_IF;
END_FOR;
Seq.iStepNo:=99;
//..............................
5:
//Check and Redo
FOR i := (Zone2StartIndex - 1)TO Zone2EndIndex BY -1 DO
//Get Current Force
y := (i * 4) + 4;
z := WORD_TO_BLOCK_DB(ForceDBWord).DD[y];
CurrentForce := DWORD_TO_REAL (z);
ChangeInForce := PreviousForce - CurrentForce;
Seq.iStepNo:=Seq.istepNo+1;
//IF ChangeInForce > 150
IF ChangeInForce > LgDiaForceDelta THEN
LgDia_StartForce := PreviousForce;
y := ((i+1) * 4) + 4;
z := WORD_TO_BLOCK_DB(PositionDBWord).DD[y];
LgDia_StartForce_Temp := PreviousForce;
LgDia_StartPosition_Temp := DWORD_TO_REAL (z);
// The idea is when ever the condition is true I save the valus in the Array
transitionForce[Arraycounter]:= LgDia_StartForce_Temp;
// Problem with Arrays
TransitionPosition[Arraycounter]:= LgDia_StartPosition_Temp;
Arraycounter := Arraycounter+1;
ELSE
PreviousForce := CurrentForce;
END_IF;
END_FOR;
IF Arraycounter =1 THEN
Seq.iStepNo:=99;
//..............................
ELSE
Seq.iStepNo:=Seq.istepNo+1;
//..............................
END_IF;
6:
CASE Arraycounter OF
1 :
LgDia_StartForce := transitionForce[1];
LgDia_StartPosition :=TransitionPosition[1];
1, 2 :
LgDia_StartForce := transitionForce[2];
LgDia_StartPosition :=TransitionPosition[2];
1..5 :
SumArray_Force := transitionForce[2]+transitionForce[3]+transitionForce[4];
LgDia_StartForce := SumArray_Force/3;
LgDia_StartPosition :=TransitionPosition[3];
1..14:
SumArray_Force := transitionForce[3]+transitionForce[4]+transitionForce[5]+transitionForce[6];
LgDia_StartForce := SumArray_Force/4;
LgDia_StartPosition :=TransitionPosition[4];
14..30:
SumArray_Force := transitionForce[4]+transitionForce[5]+transitionForce[6]+transitionForce[7]+transitionForce[8];
LgDia_StartForce := SumArray_Force/5;
LgDia_StartPosition :=TransitionPosition[6];
ELSE
Seq.iStepNo:=99;
//..............................
END_CASE;
Seq.iStepNo:=Seq.istepNo+1;
//..............................
7: DoneGood:=1;
DoneFail:=0;
temp:=1;
Seq.iStepNo:=0;
99:
DoneGood:=0;
DoneFail:=1;
temp:=1;
Seq.iStepNo:=0;
END_CASE;
END_FUNCTION_BLOCK;