VPL Introduction Manual

Top  Previous  Next

 

The VPL language is a high-level programming language similar to Basic or Pascal, but there is a big difference which makes the VPL language very suitable for typical M2M applications.

 

 

Look at the following simple VPL program:

 

1.   include rtcu.inc;
2.
3.   var_input
      iA : bool; | This is P122
      iB : bool; | This is P123
      qA : bool; | This is P124
    end_var;

 
4. var
      t : bool;
    end_var;
 
5.   program test;
 
6. begin
      if iA and iB then
          qA := not qA;
      end_if;
    end;
    end_program;

 

(The numbers to the left are not part of the actual program.)

 

The above is a very simple VPL program which just inverts a variable when two others are true.

 

 

 

Description of the above items

 

 

1.The file "rtcu.inc" always has to be included. In this file, all the standard functions/function blocks are defined. Naturally, the user can create his own files with his own functions/function blocks which can then can be included.

 

2.At this place, there would, in a more realistic VPL program, be defined functions and function blocks.

 

3.The definition of the variables which can be configured outside the program with the help of the Configurator. Typically, the candidates will be the variables which have to reflect the physical in- or outputs. Apart from that, you often can find instances of assorted function blocks as timers. The text after "|" is a special comment which is attached to the variable. This information will be present in the translated program so that the exact information about a variable always will be available. VPL also offers traditional comments where the text is ignored by the translator:

//

the rest of the line is ignored.

/**/

the content between /* and */ is ignored.

 

 

4.The variables which are local for the program. These cannot be configured outside of the program.

 

5.This indicates that the actual program begins here.

 

6.Main program.

 

When a VPL program is written and translated, one or more jobs will need to be created.  Each job is then configured before the actual download and execution can be done.

The configuration "tie" the logic variable-names to the physical I/O.

 

 


 

Declaration of variables / arrays

 

VPL offers, among others, these basic types:

 

- BOOL

Can hold the values TRUE or FALSE.

- SINT

Can hold the values from –128 til 127.

- INT

Can hold the values from –32768 to 32767.

- DINT

Can hold the values from –2147483648 to 2147483647.

- STRING

Can hold a string.

 

 

When choosing a type, it is preferable to select the most suitable because a bigger range of values occupies more space in the working storage.

A variable-name (identifier) consists of letters and numbers. The first character has to be a letter. An initial value can be assigned in the declaration. If no assignment in the declaration statement is done, the value of the variable will always be 0 (false, off).
 
An identifier (variable name) has a maximum length of 80 significant characters except for global VAR_INPUT / VAR_OUTPUT declarations where the number of allowable characters is 20.

 

The assignment of the initial value is done like this:

 

  := <constant> after the type of the variable.

 

For example:

 

  BB : DINT := 100;

 

When defining constants, VPL can use decimal, binary, octal and hexadecimal notations. This is done by adding respectively: 2#, 8# and 16# before the constant in question.

For example:

 

  BB : DINT := 16#ABCD;

  CC : INT  := 2#1000_1111;

 

The last example indicates that it is allowed to add '_' (underscore) at an arbitrary place in a constant for enhancing the readability.

 


 

Arrays:

VPL allows declarations of one-dimensional arrays.

 

 

For example:

  DD : ARRAY[10..20] OF BOOL;

 

The above line declares DD as an array of BOOL with an indexing range from 10…20 which means that DD contains 11 elements. The usage of such a variable could be something like this:

 

  FOR j:=10 TO 20 DO

    DD[j]:=ON;

  END_FOR;

 

The above line assigns all the elements in DD the value ON. If an illegal indexing is tried, it will trigger a run-time error.  

 

 

Arrays can also be assigned initial-values, like:

 

  DD : ARRAY[10..20] OF INT := 1234,5678,2234,5677;

 

In the above example, the elements with indexes 10,11,12,13 will be initialized to the above values while the remaining elements will automatically be set to 0 (zero).

 

 


 

Control structures

In this section, we will describe a number of control structures which the VPL language offers.

These structures will be shown in some small template-like applications.

 

Selection: IF statement

  IF <expression> THEN  
    <statement> <statement>
  END_IF;
 
  IF <expression> THEN  
    <statements>
  ELSIF <expression> THEN
    <statements>
  ELSIF <expression> THEN
    <statements>
  ELSE
    <statements>
  END_IF;

 

 

Selection: CASE statement

  CASE <expression> OF
    <constant> : <statements>
    <constant> : <statements>
    <constant> : <statements>
  ELSE
    <statements>
  END_CASE;

 

 

  CASE <expression> OF
  <constant 1>,<constant 2>,<constant 3>:
    <statements>
  <constant 1>..<constant 2>:  
    <statements>  
  <constant 1>..<constant 2>,<constant 3>:
    <statements>  
  ELSE
    <statements>
  END_CASE;

 

 

Iteration: WHILE statement

  WHILE <expression> DO
    <statements>
  END_WHILE;

 

 

 

Iteration: REPEAT statement        

  REPEAT
    <statements>
  UNTIL <expression>
  END_REPEAT;

 

Iteration: FOR statement

  FOR j:=<expression> TO <expression> DO
    <statements>
  END_FOR;
 
  FOR j:=<expression> TO <expression> BY <expression> DO
    <statements>
  END_FOR;

 

 

Iteration: EXIT

In all iteration structures (WHILE, REPEAT and FOR) the word EXIT can appear. EXIT will terminate the inner-most loop.  

 

 

Ex:

 

  WHILE a AND b DO
  FOR j:=1 TO 1000 DO
    IF c THEN EXIT; END_IF;
    END_FOR;
  END_WHILE;

 

If the 'c' is true (c<>0), it will terminate the FOR loop but NOT out of the WHILE loop. EXIT outside iterations will create a syntax error.

 

 

RETURN

 

 

Finally, the key word 'RETURN' will be mentioned. This returns immediately from a function or a function block (please refer to the description of functions and function blocks).

 

 


Functions

 

A function is declared like this:

 

 

  FUNCTION name : returntype;
  VAR_INPUT
     variable : type;
     ... ...
     variable : type;
    END_VAR;
   
    VAR
     variable : type;
     ... ...
     variable : type;
  END_VAR;
 
   <statements>
  END_FUNCTION;

 

 

The return type has to be a simple type - such as BOOL, SINT, INT or DINT. VAR_INPUT contains the variables which have to be assigned a value outside the function. That means that these variables can't be modified inside the function but only be read. The VAR section is the private variables of the function. These can only be read/modified from within the function. The variables can be assigned an initial-value. The statements, which are in the function body, can only use the variables which are declared as input or private variables.

 

 

An example on a function which adds three numbers

 

  FUNCTION Add : INT;
  VAR_INPUT
    a : INT;
    b : INT;
    c : INT;
  END_VAR;
    Add := a+b+c;
  END_FUNCTION;

 

The assignment of the return value is done in the "Add := …." statement.

This function could be used like this:

 

 

  j := Add(a:=3,b:=4,c:=10);

 

After this statement, the variable j will contain the value 17.

 

Please note how the variable of the function is explicitly assigned by writing the name of the variable. It is possible not to assign a value to the variable of a function; in this case its initial value will be used.

 

 

For example:

 

  j := Add(c:=5,a:=2);

 

These call will assign the initial-value for b, that is 0, the value of j will after these call correctly be 7. Please note that the order of these assignments is arbitrary.

 

 

Parameter passing by value or by reference

 

In the above example, the parameters to the function were passed by value. It is also possible to pass the parameters to a function by reference.

When a parameter is passed by value, a copy of the parameter is made. Therefore, changes made to the formal parameter by the called function is not possible and will therefore have no effect on the corresponding actual parameter.

 

When a parameter is passed by reference, conceptually, the actual parameter itself is passed (and just given a new name - the name of the corresponding parameter). Therefore, any changes made to the formal parameter do affect the actual parameter. For example:

 

  FUNCTION test;
  VAR_INPUT
    a : ACCESS INT;
  END_VAR;
    a := a + 1;
  END_FUNCTION;
 
  VAR
    x : INT := 10;
  END_VAR;

 

  test(a:=x);

 

In this example, the "test"'s parameter is passed by reference by using the ACCESS attribute. Therefore, the assignment to "a" in "test" is actually changing the variable "x" so that the value of x after the function call is 11.

 

 

For more information regarding the use of passing reference parameters, please refer to the ACCESS keyword.

 


 

Function blocks

The function block is an extremely useful structural facility when developing VPL programs. A function block that is executed can deliver one or more values to the surrounding world. By repeated execution, the delivered values will not necessarily be the same every time. This is because a function block has a state that is stored between each call. These have to be viewed in relation to a function which always generates the same value by repetition of the same call.

 

Please observe this very useful function block:

 

 

  FUNCTION_BLOCK CTD;
  VAR_INPUT
    cd : BOOL R_EDGE; | count down
    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;

 

By declaration of variable of the type BOOL in a VAR_INPUT section, it can be defined that a variable only has to be true if there is either detected a rising edge (R_EDGE) or a falling edge (F_EDGE).

 

 

The above function block is very useful for countdown applications. CTD (count down) will at each rising edge "cd" count down its current counter value. "Id" will load the preset value "pv" in "cv". Finally "q" states whether the counter has reached 0.

 

CTD is a brilliant example at the many advantages of using function blocks. All the logic for a CTD is contained in a single unit with a well-defined interface. A well-developed library of function blocks will make developing VPL programs much easier and it will also reduce the number of errors.

 

As it was with the functions, the variables in the section of VAR_INPUT can only be modified outside the function block, and the variables in the VAR_OUTPUT section can only be read outside the function and not modified. The statement in the VAR section is the private variable of the function block and can therefore only be used inside the function block.

 

 

The instantiation of a function block is done like this:

 

 

  AAA : CTD;

 

To get access to AAA input/output variables, the following notation is used: AAA.<variable>

For example, the initial-value can be set to 1000 with the help of:

 

 

  AAA.pv := 1000;

 

Alternatively, calling the function-block can do the assignment:

 

 

  AAA(pv:=1000);

 

This has the same effect as making an assignment followed by a call to the function block.

 

 

An example of using the CTD:

 

 

  VAR_INPUT
    i1 : BOOL; | input
    i2 : BOOL; | another input
  END_VAR;
 
  VAR_OUTPUT
    o   : BOOL; | output
  END_VAR;
 
  VAR
    a   : CTD;
    tmp : BOOL;
  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;

 

 

This was a short introduction to VPL. There are many features not described in this section, most importantly multithreading, that is also an integral part of the language.

 

Please also have a look at Reserved words.