FUNCTION_BLOCK

Top  Previous  Next

Function blocks are an extremely important facility when developing VPL programs. A function block can accept and deliver different values to the calling program. As all function blocks are instantiated once and thereafter keep their own variables etc. in memory, they survive between calls to them, and can therefore deliver different results for each call. This is opposite to a function which has no knowledge of the previous times it was called (the variables of a function will not survive between multiple calls).

 

 

Have a look at the following function block, which in fact is a function block taken from the RTCU environment and therefore is available "right out of the box". You can find some more details about the CTD function block here.

 

FUNCTION_BLOCK CTD;
 
VAR_INPUT
   cd : BOOL R_EDGE; | count down (R_EDGE will detect a leading edge on the signal)
   ld : BOOL;       | load preset value
   pv : INT;         | preset value
END_VAR;
 
VAR_OUTPUT
   q : BOOL; | count down occurred
   cv : INT; | current value
END_VAR;
 
IF ld THEN
   cv := pv;
ELSIF cd
   cv := cv-1;
END_IF;
q := cv <= 0;
END_FUNCTION_BLOCK;

 

 

When declaring a variable of the type BOOL in the VAR_INPUT section, it is possible to define that the variable only become TRUE if either a leading edge (R_EDGE) is detected or if a falling edge (F_EDGE) is detected.

 

The CTD function block above is very usable in cases where one needs to count down on some event. The CTD function block will decrement its counter value by 1 on each leading edge on "cd". Setting "ld" to TRUE will load the preset value "pv" into the counter "cv". The output "q" will be TRUE when the counter "cv" reaches 0.

 

CTD is a wonderful example of the many benefits of using function blocks. The complete logic of the CTD "function" is encapsulated in a unit with a very well-defined interface to the outside world. When one has a large library of predefined and developed function blocks (and functions), development of new programs will both be easier and also less time consuming. The number of errors introduced to a new program will also be reduced as many of the function blocks that one uses already have been used many times before and are therefore thoroughly tested.

 

As it was the case with functions, variables declared in the VAR_INPUT section can only be modified outside of the function block as variables in the VAR_OUTPUT section can only be read outside the function block (but not modified). Declarations in the VAR section are the private variables of the function block and can therefore only be used from inside the function block.

 

The instantiation of a function block is done in the following way:

 

AAA : CTD;

 

To get access to the inputs and outputs of AAA, the following notation is used: AAA.<variable>

 

To set the initial value of the CTD (pv, preset value), one can use the following code:

 

AAA.pv := 1000;

 

This will set the default value (preset value) to 1000.

 

Another way to accomplish this is initializing the "pv" to 1000 and at the same time call the function block so it will be executed:

 

 AAA(pv:=1000);

 

This has exactly the same effect as first assigning the value 1000 to "pv" and then calling the function block:

 

 AAA.pv := 10000;

 AAA();

 

Example on the use of CTD:

 

// Simple example showing the use of CTD
 
INCLUDE RTCU.INC
 
VAR_INPUT
  i1 : BOOL; | An input
  i2 : BOOL; | Another input
  a : CTD;
END_VAR;
 
VAR_OUTPUT
  o : BOOL; | output
END_VAR;
 
PROGRAM CTD_test;
 
a.pv := 1000; // set preset value
 
BEGIN
  IF i1 THEN
    // load default value
     a(ld := TRUE);
     a(ld := FALSE);
  ELSE
     a(cd := i2);
  END_IF;
  IF a.q THEN
    // count down:
     o := NOT o;
  END_IF;
END;
 
END_PROGRAM;

 

 

It is possible to separate the interface and implementation part of a function block using the INTERFACE / IMPLEMENTATION functionality.