This example shows a function block that can be used as a Toggle Switch. A Toggle Switch changes status each time the switch is activated, and can be used as a start and stop switch for an electrical component (eg motor, fan or light).
The advantage of a Toggle Switch is that you only need to use one switch, instead of using a switch for on and a switch for off.
To the right, a time diagram is shown. The signal from the switch is CLK and the component to be switched off or on must be connected to Q. CLK_OLD is an internal variable used as a OneShot and ensures that there is only one change in Q status, every time CLK is activated.
The example is based on the do-it-yourself implementation of the Oneshot, (see page →), which ensures that the solution can be used in all types of PLCs:
FUNCTION_BLOCK FBToggle VAR_INPUT CLK: BOOL; // Input signal END_VAR VAR // Remember previous signal on CLK CLK_OLD: BOOL := FALSE; END_VAR VAR_OUTPUT Q: BOOL; // Output END_VAR
Change of status is made at #2, where Q is set to the inverted value of Q.
//Code for FUNCTION BLOCK: Toogle //When CLK is moves from FALSE to TRUE //Q will be TRUE if FALSE or FALSE if TRUE //Detect the rising edge on the input signal IF CLK AND NOT CLK_OLD THEN CLK_OLD:= TRUE; //#1 Q:= NOT Q; //#2 END_IF; //Reset the rising edge detection IF NOT CLK THEN CLK_OLD:= FALSE; END_IF;
Program example:
PROGRAM MAIN VAR MyToogle: FBToggle; K1: BOOL := FALSE; S1: BOOL; //Contact switch END_VAR //Example program: MyToogle (CLK:= S1, Q=> K1);
This chapter shows an example of a PLC program used to handle cars inside a car park.
When the car is inserted into the car park house by the robot, the program has to first find a vacant space to ensure the robot knows where to place the car.
When the car is picked up by the car driver, the car must first be located by the program, so the robot knows where to pick up the car from.
Due to the fact that a car license plate is unique, it is used as the identifier, and as it contains numbers and letters it is set to a STRING data type in the PLC program. The length of the STRING is limited to 15 characters to save memory in the program. The constant for this is named STR15.
It is possible to insert, find or remove cars from the parking house. To reuse as much of the program code as possible, only one function named CarHandle is implemented which takes one of the following parameters: CAR_INSERT, CAR_FIND or CAR_DEL.
A location inside the 3D parking house consists of x, y and z coordinates and therefore a STRUCT named Pos is declared because this gives a clear structure to the code.
TYPE Pos : STRUCT x: INT; y: INT; z: INT; END_STRUCT END_TYPE VAR_GLOBAL CONSTANT STR15 : INT:= 15; //Car number CAR_INSERT : INT := 1; CAR_FIND : INT:= 2; CAR_DEL : INT:= 3; END_VAR VAR_GLOBAL CONSTANT X_MAX: WORD := 2; Y_MAX: WORD := 3; Z_MAX: WORD := 4; END_VAR
Below see how the CarHandle function can be used:
PROGRAM Main VAR MyPos: Pos; //Location inside the car park house ArCarPark: ARRAY[1.. GVL.X_MAX, 1.. GVL.Y_MAX, 1.. GVL.Z_MAX] OF STRING[GVL.STR15]; END_VAR // REMEMBER TO run the code only once! ArCarPark [1,3,1]:= 'YD 12345'; //Insert car directly into the 3D Array CarHandle ('YD 12345', GVL.CAR_FIND, ArCarPark, MyPos); //MyPos.x = 1, MyPos.y =3, MyPos.z = 1 CarHandle ('AB 12345', GVL.CAR_INSERT, ArCarPark, MyPos); CarHandle ('AB 12345', GVL.CAR_DEL, ArCarPark, MyPos); FUNCTION CarHandle : BOOL VAR_INPUT CarStr: STRING; //Number plate for the car Handle: INT; // What action to take? CAR_FIND, CAR_DEL or CAR_INSERT END_VAR VAR_IN_OUT arPark: ARRAY[*, *, *] OF STRING [GVL.STR15]; //Pointer to 3D ARRAY CarP: Pos; // Location of the car END_VAR VAR Loop, Found : Pos; //Working STRUCT Ctrl: BOOL := FALSE; //Control the operation inside this function. If FALSE an error occur END_VAR //Copy ARRAY sizes to local variables to maintain readable program code for the LOOPs Loop.x:= DINT_TO_INT (UPPER_BOUND (arPark, 1)); //Size 1D Loop.y:= DINT_TO_INT (UPPER_BOUND (arPark, 2)); //Size 2D Loop.z:= DINT_TO_INT (UPPER_BOUND (arPark, 3)); //Size 3D //LOOP through all locations in the 3D car park house FOR CarP.x:= 1 TO Loop.x DO FOR CarP.y := 1 TO Loop.y DO FOR CarP.z:= 1 TO Loop.z DO //Condition only passes when no action has been taken IF Ctrl = FALSE THEN IF FIND (ArPark [CarP.x, CarP.y, CarP.z], CarStr) > 0 THEN CASE Handle OF GVL.CAR_FIND : Found:= CarP; //Copy coordinates where the car was located GVL.CAR_DEL : ArPark [CarP.x, CarP.y, CarP.z]:= ''; //Set STRING to empty END_CASE Ctrl:= TRUE; //done END_IF; //Insert the car at the first free location in the parking house IF Handle = GVL.CAR_INSERT AND ArPark [CarP.x, CarP.y, CarP.z] = '' THEN ArPark [CarP.x, CarP.y, CarP.z]:= CarStr; //Insert Ctrl:= TRUE; //done END_IF; END_IF; END_FOR; //z END_FOR; //y END_FOR; //x //Set return values (copy x, y, z coordinates inside STRUCT) and error code CarP:= Found; CarHandle := Ctrl;