In the article The wonders of ANY, Jakob Sagatowski shows how the data type ANY can be effectively used. In the example described, a function compares two variables to determine whether the data type, data length and content are exactly the same. Instead of implementing a separate function for each data type, the same requirements […]
In the article The wonders of ANY, Jakob Sagatowski shows how the data type ANY can be effectively used. In the example described, a function compares two variables to determine whether the data type, data length and content are exactly the same. Instead of implementing a separate function for each data type, the same requirements can be implemented much more elegantly with only one function using data type ANY.
Some time ago, I had a similar task. A method should be developed that accepts any number of parameters. Both the data type and the number of parameters were random.
During my first attempt to find solution, I tried to use a variable-length array of type ARRAY [*] OF ANY. However, variable-length arrays can only be used as VAR_IN_OUT and the data type ANY only as VAR_INPUT (see also IEC 61131-3: Arrays with variable length). This approach was therefore ruled out.
As an alternative to data type ANY, structure T_Arg is also available. T_Arg is declared in the TwinCAT library Tc2_Utilities and, in contrast to ANY, is also available at TwinCAT 2. The structure of T_Arg is similar to the structure used for the data type ANY (see also The wonders of ANY).
TYPE T_Arg :
STRUCT
eType : E_ArgType := ARGTYPE_UNKNOWN; (* Argument data type *)
cbLen : UDINT := 0; (* Argument data byte length *
pData : UDINT := 0; (* Pointer to argument data *)
END_STRUCT
END_TYPE
T_Arg can be used at any place, including in the VAR_IN_OUT range.
The following function adds any amount of numbers whose data type can also be random. The result is returned as LREAL.
However, calling the function is somewhat more complicated than with the data type ANY.
PROGRAM MAIN
VAR
sum : LREAL;
args : ARRAY [1..4] OF T_Arg;
a : INT := 4567;
b : REAL := 3.1415;
c : DINT := 7032345;
d : USINT := 13;
END_VAR
args[1] := F_INT(a);
args[2] := F_REAL(b);
args[3] := F_DINT(c);
args[4] := F_USINT(d);
sum := F_AddMulti(args);
The array passed to the function must be initialized first. The library Tc2_Utilities contains help functions that convert a variable into a structure of type T_Arg (F_INT(), F_REAL(), F_DINT(), …). The function for adding the values has only one input variable of type ARRAY [*] OF T_Arg.
The data type T_Arg is used, for example, in the function block FB_FormatString() or in the function F_FormatArgToStr() of TwinCAT. The function block FB_FormatString() can replace up to 10 placeholders in a string with values of PLC variables of type T_Arg (similar to fprintf in C).
An advantage of ANY is the fact that the data type is defined by the IEC 61131-3 standard.
Even if the generic data types ANY and T_Arg do not correspond to the generics in C# or the templates in C++, they still support the development of generic functions in IEC 61131-3. These can now be designed in such a way that the same function can be used for different data types and data structures.
Größtenteils wird es hier um .NET und C# gehen. In Gegensatz zu vielen anderen Blogs, werde ich versuchen die einzelnen Themen intensiv zu behandeln. Aus diesem Grund bestehen die meisten Beiträge aus mehreren Teilen. Die einzelnen Teile bauen aufeinander auf, können aber auch einzeln betrachtet werden.