Understanding the InOut Interface Pattern in TIA Portal

October 3, 2025 · tia-portalplc-programmingbest-practicessiemensarchitecture

Did you know you can use a single interface variable for all your top-level function blocks?

When I first posted about this on LinkedIn, it generated the most engagement of any post I have published – nearly 7,000 impressions and detailed technical discussions from automation engineers around the world. That tells me this is a pattern many people are curious about but not many are using.

The InOut interface type in TIA Portal is one of the most underused features in function block design. With it, you can create a clean data architecture where every block in your program connects through a shared, structured interface. It sounds unconventional, but it comes down to proper data structure design.

What Is the InOut Interface?

In TIA Portal, function blocks have several interface sections: Input, Output, InOut, Static, Temp, and Constant. Most programmers use Input and Output extensively, but InOut gets overlooked.

The key difference: InOut parameters are passed by reference, not by value. When you pass a variable as InOut, the function block does not get a copy of the data – it gets a pointer to the actual data. Any changes the block makes are immediately visible to everything else that references the same data.

This is what makes the pattern possible. Instead of copying data in and out of every block, all your top-level blocks can read from and write to the same shared data structure.

The Pattern: System-Level UDT Hierarchy

Here is how I structure it in practice:

Step 1: Machine-Level UDTs

Each machine or subsystem gets its own UDT (User-Defined Type) that defines all the data it needs. This UDT is structured into clear sections:

  • Inputs – sensor values, feedback signals, process measurements
  • Commands – start, stop, mode selection, setpoints from the operator interface
  • Outputs – actuator commands, control signals sent to the field
  • Status – current state, active alarms, operational flags reported back to the operator

For example, a conveyor might have a UDT with motor speed feedback in Inputs, a run command in Commands, a motor speed reference in Outputs, and a running/faulted status in Status.

Step 2: System-Level UDT

The system-level UDT is simply a composition of all your machine-level UDTs. If your system has a conveyor, a robot, and a packaging station, the system UDT contains one instance of each machine UDT.

This creates a hierarchy: System contains Machines, each Machine contains Inputs, Commands, Outputs, and Status.

Step 3: Global Data Block

Create one global data block with a single variable of the system UDT type. This is the single location where all interface data lives.

Step 4: Connect Everything Through InOut

Every top-level function block receives the system UDT (or its relevant machine UDT) as an InOut parameter. The machine FB reads from Inputs and Commands, implements its control logic, then writes to Outputs and Status. The operator control FB reads Status from all machines and writes Commands.

Because InOut passes by reference, all blocks are working with the same data. There is no copying, no synchronization issues, and no stale data.

How Machine FBs Read and Write

Each machine function block follows a consistent pattern within its scan cycle:

  1. Read Inputs. The FB reads sensor values and feedback signals from the Inputs section of its UDT.
  2. Read Commands. The FB reads operator commands (start, stop, mode changes) from the Commands section.
  3. Execute Logic. Based on inputs and commands, the FB runs its state machine, PID controllers, sequencing, or whatever control logic it implements.
  4. Write Outputs. The FB writes actuator commands and control signals to the Outputs section.
  5. Write Status. The FB writes its current state, alarm conditions, and operational flags to the Status section.

The operator control FB does the reverse: it reads Status from all machines to display on the HMI, and writes Commands based on operator actions.

Write Ownership: The Critical Rule

This is the most important discipline when using this pattern: plan carefully which section is writable by which function block.

The rule is simple:

  • Commands are written only by the operator control FB (or HMI interface FB).
  • Status is written only by the equipment FB that owns that machine.
  • Outputs are written only by the equipment FB.
  • Inputs are written only by the IO mapping (or the block that reads physical inputs).

No two blocks should write to the same section within the same scan cycle. If a conveyor FB writes its Status and the operator FB also writes to the same Status section, you get unpredictable overwrites depending on execution order.

This is not a limitation of the pattern – it is a feature. It forces you to think clearly about data ownership, which prevents an entire category of hard-to-debug problems.

Benefits Over Traditional Approaches

Single Source of Truth

All interface data lives in one global DB. Need to check the current speed of a conveyor? Look in the system DB under Conveyor.Status. Need to see what command the operator sent? Same DB, under Conveyor.Commands. No searching through dozens of blocks to find where a variable is stored.

Online Diagnostics Made Easy

During commissioning or troubleshooting, you can monitor the entire system state by watching one data block. Every input, output, command, and status value is right there, organized by machine. No need to go online on individual FBs to see their internal state.

UDT-Driven Updates

Need to add a new variable to a machine interface? Update the UDT definition. After compiling, the change applies automatically to every block that uses it – the global DB, every FB that receives it as InOut, and every HMI tag that references it. One change, everywhere.

Clean Architecture

The pattern naturally enforces separation of concerns. Each FB is responsible for its own machine. Communication between machines happens through the shared data structure, not through hidden global variables or direct block-to-block connections. The architecture is visible and understandable.

When This Pattern Works Best

This approach is most valuable for:

  • Multi-machine systems where several subsystems need to share data
  • Projects with operator interfaces where HMI needs to read status and write commands
  • Scalable designs where you might add machines or modify interfaces over time
  • Team projects where multiple engineers need to understand the data flow

For very small programs with one or two function blocks, the overhead of creating UDT hierarchies may not be worth it. But for anything with three or more interacting subsystems, this pattern pays for itself in clarity and maintainability.

Getting Started

If you want to try this pattern, start simple:

  1. Define one machine UDT with Inputs, Commands, Outputs, and Status sections.
  2. Create a system UDT that contains your machine UDTs.
  3. Create a global DB with one variable of the system UDT type.
  4. Wire it into your top-level FBs as an InOut parameter.
  5. Enforce write ownership from the beginning.

Once you see how clean the data flow becomes, you will wonder why you ever passed dozens of individual variables through block interfaces.

Planning a project? Contact us to discuss how we can help.

Planning a new project? Message us to see how we can help.