So, working program should wait 1 second after motor achieves desired position and than the motor should be started in other direction, and after also 1 sec(count other timer) after one output is set the other output should be reset.
When FB is in OB35 motor is immediately started after it achieves the position(motor in level) and outputs is also immediately reset.
here is the code of my FB:
FUNCTION_BLOCK FB 52
TITLE =
VERSION : 0.1
VAR
StartFromBottom : BOOL ;
GoDown : BOOL ;
OnBottom : BOOL ;
GO_1 : BOOL ;
GO_2 : BOOL ;
Start : BOOL ;
GO_3 : BOOL ;
StartEdge : BOOL ;
DoneEdge : BOOL ;
Busy : BOOL ;
go_down : BOOL ;
PosNo : INT := 1;
PCylinder : BOOL ;
Timer1 : BOOL ;
T1_out : BOOL ;
T2_out : BOOL ;
TimerF : BOOL ;
Timer2F : BOOL ;
Timer2 : BOOL ;
UnLoad : BOOL ;
UnLoad0 : BOOL ;
UnLoad1 : BOOL ;
UnLoad2 : BOOL ;
UnLoad3 : BOOL ;
PosLevel1 : INT ;
PosLevel2 : INT ;
PosLevel3 : INT ;
PosLevel4 : INT ;
PosBottom : INT ;
END_VAR
VAR_TEMP
PosPointer : DWORD ;
OrderPointer : DWORD ;
StockPointer : DWORD ;
END_VAR
BEGIN
NETWORK
TITLE =Choose position
U #go_down;
FP #GO_2;
SPB M006;
U "MOrderFound"; //jezeli znalizlismy 1 w tablicy
FP #GO_1;
SPB M001;
U #Busy;
SPB Done;
M006: L 6; //Pos=bottom
T #PosNo;
S #Busy;
SPA SET;
M001: S #Busy;
SPA SET;
//*** Travel order finished?
Done: U "DB_M_Abs1".Done;
FP #DoneEdge;
R "DB_M_Abs1".Execute;
SPBN NDon; // Jump if no DONE
//*** Start evaluation
NDon: UN "MAutomatik_Manual";
SPB Manu;
S "DB_M_Abs1".Execute;
FP #StartEdge;
SPBN Manu; // Jump if no restart
Manu: U "DB_M_Abs1".Execute;
FP #StartEdge;
SPBN EMC; // Jump if no restart
//*** The position number is valid, so travel to this position!
// Calculate the addresses of position and velocity suitable for this position number in
// DB_POS_05, read their values and transfer to FB MoveAbsolute.
SET: L #PosNo;
SLW 3; // Adr_Position = PosNo x 8 - 6
L 6;
-I ;
SLW 3; // and read position value
T #PosPointer;
AUF "DB_POS_05"; // into pointer format
L DBD [#PosPointer];
T "DB_M_Abs1".Position; // Transfer position to FB
L #PosPointer; // the velocity
L P#4.0; // is in the DB behind
+D ; // the position
T #PosPointer;
AUF "DB_POS_05"; // read velocity
L DBD [#PosPointer];
T "DB_M_Abs1".Velocity; // transfer velocity to FB
EMC: NOP 0;
NETWORK
TITLE =Check where the lift is
CALL "WhichPosition" , DB 9 (
PosLevel1 := 100,
PosLevel2 := 200,
PosLevel3 := 300,
PosLevel4 := 400,
PosBottom := 0,
OnLevel1 := "MLevel1",
OnLevel2 := "MLevel2",
OnLevel3 := "MLevel3",
OnLevel4 := "MLevel4",
Bottom := "MBottom");
NETWORK
TITLE =Check if there is request to go (1 in DB2)
CALL "CheckGoRequest" , DB 57 (
Search := "MSearchForOrder",
LevelToGo := "MOrderinLevel",
OneFound := "MOrderFound");
NETWORK
TITLE =Start searching for order
U "CylinderBottom";
FN #OnBottom;
O( ;
U( ;
O "ELoadBlockLevel4";
O "ELoadBlockLevel3";
O "ELoadBlockLevel2";
O "ELoadBlockLevel1";
) ;
FP #Start;
) ;
R "MOrderFound";
= "MSearchForOrder";
NETWORK
TITLE =Check if the lift is on the desired position
CALL "OnPosition" , DB 58 (
PosNo := #PosNo,
OnPosition := "MLiftOnBottom");
U "MLiftOnBottom";
FP #GoDown;
SPBN NDow;
S #Timer2;
SPA OnBo;
NDow: U "MBottom";
FP #GO_3;
SPBN OnBo;
S #Timer1;
S "CylinderBottom";
R #go_down;
OnBo: NOP 0;
NETWORK
TITLE =
U "MLevel1";
= "ALevel1";
NETWORK
TITLE =
U "MLevel2";
= "ALevel2";
NETWORK
TITLE =
U "MLevel3";
= "ALevel3";
NETWORK
TITLE =
U "MLevel4";
= "ALevel4";
NETWORK
TITLE =
U "MBottom";
= "ABottom";
NETWORK
TITLE =Activate pneumatic cylinders
L "MOrderinLevel";
T #PosNo;
U "MLiftOnBottom";
SPBN ENDC;
L 1;
==I ;
SPBN C2;
S "CylinderLevel1";
S #Timer1;
SPA ENDC;
C2: L #PosNo;
L 2;
==I ;
SPBN C3;
S "CylinderLevel2";
S #Timer1;
SPA ENDC;
C3: L #PosNo;
L 3;
==I ;
SPBN C4;
S "CylinderLevel3";
S #Timer1;
SPA ENDC;
C4: L #PosNo;
L 4;
==I ;
SPBN ENDC;
S "CylinderLevel4";
S #Timer1;
SPA ENDC;
ENDC: NOP 0;
NETWORK
TITLE =Start timer1
U #Timer1;
L S5T#1S;
SE T 1;
U #T1_out;
R T 1;
NOP 0;
NOP 0;
U T 1;
= #T1_out;
// U #Timer1
// = L 12.0
// BLD 103
// U #T1_out
// = L 12.1
// BLD 103
// CALL "Timer" , DB16
// TimerNR :=T1
// TimeToGo :=S5T#1S
// StartTimer:=L12.0
// ResetTimer:=L12.1
// Done :=#T1_out
// NOP 0
NETWORK
TITLE =When T1_out 0->1 then reset cylinders
U #T1_out;
FP #TimerF;
SPBN TEND;
R #Timer1;
R "CylinderLevel1";
R "CylinderLevel2";
R "CylinderLevel3";
R "CylinderLevel4";
R "CylinderBottom";
TEND: NOP 0;
NETWORK
TITLE =Start Timer2
U #Timer2;
L S5T#1S;
SE T 2;
U #T2_out;
R T 2;
NOP 0;
NOP 0;
U T 2;
= #T2_out;
// U #Timer2
// = L 12.0
// BLD 103
// U #T2_out
// = L 12.1
// BLD 103
// CALL "Timer" , DB17
// TimerNR :=T2
// TimeToGo :=S5T#1S
// StartTimer:=L12.0
// ResetTimer:=L12.1
// Done :=#T2_out
// NOP 0
NETWORK
TITLE =When T2_out 0->1 go down
U #T2_out;
FP #Timer2F;
SPBN T2EN;
R #Timer2;
S #go_down;
T2EN: NOP 0;
NETWORK
TITLE =
U "CylinderBottom";
FN #UnLoad;
SPBN ULoa;
R "BlockOnPlatform";
ULoa: NOP 0;
NETWORK
TITLE =
U "CylinderLevel4";
FN #UnLoad0;
SPBN UL1;
S "BlockOnPlatform";
R "BlockOnLevel4";
UL1: NOP 0;
NETWORK
TITLE =
U "CylinderLevel3";
FN #UnLoad1;
SPBN UL2;
S "BlockOnPlatform";
R "BlockOnLevel3";
UL2: NOP 0;
NETWORK
TITLE =
U "CylinderLevel2";
FN #UnLoad2;
SPBN UL3;
S "BlockOnPlatform";
R "BlockOnLevel2";
UL3: NOP 0;
NETWORK
TITLE =
U "CylinderLevel1";
FN #UnLoad3;
SPBN UL4;
S "BlockOnPlatform";
R "BlockOnLevel1";
UL4: NOP 0;
END_FUNCTION_BLOCK