Example of Variants in Siemens TIA Portal Shown In Ladder Logic With 2 Variants
Example of Variants in Siemens TIA Portal Shown In Ladder Logic With 2 Variants
Example Of A Single Block Accepting 2 Different Data Type Inputs Using Variants

The Variant data type is a special data type that accepts almost anything. Similar to the ANY data type, TIA Portal essentially creates a pointer to the data and passes that, but with a few extra elements:

  • Start Address – The address that the data starts at
  • Length – The length of the data
  • Original Type – The data type of the original data

Whilst you cannot access the above data directly, TIA Portal offers functions that do interact with the internal data.

Use Cases

Variants are extremely useful when you have a standard function block that requires the ability to service 2 or more variations of a section of the code.

For example, consider a Variable Speed Pump, you have some standard code that works with your system’s SCADA that allows operators to set speeds, start the pump, stop the pump ect. But, from a hardware point of view, you have 2 variations of manufacturer in your asset range.

With Variants, you can pass the structure for VSD 1 to your standard block, and the block will run a section of code for the VSD. When you pass VSD 2 to the same block, on the same pin, the block knows that it’s VSD 2 and runs a different section of code

I’ve written a simplified diagnostic block, pictured above that explains the concepts behind this.

Variant Usage In Blocks – Example

The first thing to note is that Variants cannot be used in Global Data Blocks, or Instance Data Blocks unless being passed as an INOUT, INPUT, or OUTPUT. IT is not possible to create a variant in STATIC data, but you can in TEMP data.

Example of Variant Data in the INOUT interface of a Function

The above image shows a Variant in use in the Function Diagnostic_Check. This means that the variable Data will accept anything

Note
Note
Note

It’s important to understand that a Variant serves to purpose in Logic. You can’t perform many functions on Variables since the instruction cannot determine the type of data, or the data is Complex (A structure for example)

Once the Variant has been passed into the block it is to be used in, the next step is to determine what the data actually is.

The Example from here on in is written in SCL, however you can achieve this in any language with a slightly different instruction set

Checking For Data Type

Using TypeOf, check if the data type within the Variant Data matches a predefined type in the block

The above SCL code is using the TypeOf instruction to check the original data type of the Variant Data. Our interface of our block contains System_A and System_B, which are both UDTs of different types:

System_A and System_B as TEMP variables

These are declared in the TEMP scope of the interface and are used in conjunction with TypeOf to provide a test case in the logic.

If the TypeOf(#Data) = TypeOf(#System_A) is True, then we load #A into a #Type variable. #A is a Constant and is simply providing a numerical value to #Type, so we know which type of system has been passed to the block

At this point, we now know that System A or System B has been passed to the block (or neither if something has been passed)

Moving Data From Variant To Usable Data Type

Now that the Data type is known, the actual data needs to be accessible. This can be done using the BLKMOV instruction:

BLKMOV instruction moving Data into System_A
OPTIMIZED DATA
OPTIMIZED DATA
OPTIMIZED DATA

You cannot use BLKMOV with Optimized Data.

The BLKMOV instruction simply overlays data from one area to another, thus moving data from Data to System_A, even though the data types do not match (Variant and UDT_System_A)

At this point, the data that was originally passed in as UDT_System_A in a TEMP variable called System_A that is also the data type UDT_System_A. This means that System_A can be worked with from this point in and contains the same values as Data

Performing Logic

Example of logic on System_A

The above code shows that if System A is being worked with (Case #Type Of #A), then the following OUTPUT variables are updated:

  • Type_StringSystem_A
  • Data_Buffer – Entire Data Structure as a DWORD
  • Additional_Data16#AE
Passed as OUTPUTS

These variables are passed outside of the block as OUTPUTS

Modifying System_A Data

System_A.Fault is checked and if True, .Signal is modified to False. This works fine, however remember that System_A is in temporary memory, and is disassociated from Data. This means System_A needs to be written back to Data:

BLKMOV moving System_A with updated values, back to Data

The Data variable will then be passed through the INOUT interface, back to the original data, with the updated values.

Complete Example

Below is a complete runthrough of the example

Global Data Block – Systems

Contains instances of UDT_System_A and UDT_System_B. These are passed in the Main block to the Diagnostic_Check Functions.

Main (OB1)

Calls two instances of Diagnostic_Check, the first with "Systems".A and the second with "Systems".B

These two systems contain different data. A contains a Bool data type and B contains a Real data type.

Conventional methods would not allow both of these systems to be passed to the same pin (Data) of the Function because the data types wouldn’t match

Data is defined as a Variant, so both system types are accepted

Diagnostic_Check Function

This Function is taking in the Data Variant and checking the data type.

If System_A (UDT_System_A) is found at the Data pin, then the Case #A is executed

If System_B is found, then Case #B is executed

In both cases, data is moved to the output pins and the Signal is written to a value if Fault is True

The difference between System_A and System_B is that System_A sets a Bool value and System_B sets a Real value at the Signal variable.

Conclusion

Variants can be a difficult concept to wrap your head around, and the above is only a basic example.

They can be super powerful in ensuring you don’t have multiple blocks of code that all perform 95% of the same logic, but have differences because of different data types that need to be handled.

Note
Note
Note

Remember that every data type that needs to have logic executed against it needs to exist in your Function or Function Block.

If you have 1 block that accepts 100 different types, that means that 99% of the code is doing nothing but taking up space

You need to evaluate what is best for your project when using variants to ensure you don’t “over-do-it” with flexibility.

If you have any questions on the topic, hit the comments below, or ask me on LinkedIn via the below link


Check Out Another Post

2 thoughts on “TIA Portal Basics – Working With Variants”
  1. In TIA V17 BLKMOV falls under ‘Legacy’, is there an updated instruction we should use for this operation? I notice there are MOVE_BLK and MOVE_BLK_VARIANT instructions also available. It is a bit frustrating that TIA doesn’t allow us to access the size of the data directly :(.

    1. Hi Dennis,

      That’s interesting, I’m using TIA Portal V17 daily, but can’t say I’ve paid much attention to the classification of the instruction. I’ll do some digging on this!

      What do you mean about accessing the size of the data directly?

Leave a Reply