Writing clean, modular, and maintainable PLC code requires structuring your data and decoupling your logic. In this tutorial, we will look at how to build a flexible software latch/momentary button handler using custom PLC Data Types (UDTs), an instantiated Function Block array, and variable-length array indexing (Array[*]) in Siemens TIA Portal.
Step 1: Define the Data Model with a PLC Data Type (UDT)
Instead of scattering loose booleans across memory, we group command and feedback signals into a single data type called button.
- command: Contains the incoming trigger (enable) and mode selector (isLatched).
- feedback: Holds the operational state (enabled) and an identifier (name).

Step 2: Instantiate the Data in a Global DB
In our global Data Block (globalDB), we define an array of buttons: Array[0..10] of “button”. This centralizes the state for all HMI or field pushbuttons in one clean structure.

Step 3: Create the Core Logic Block (demoButton FB)

To process each button individually, we create a reusable Function Block (demoButton).
Within demoButton, we pass the UDT via the InOut interface (buttons: “button”). The SCL logic detects a rising edge using R_TRIG and toggles the output if isLatched is active, or mirrors the signal if momentary mode is selected:

Step 4: Scale with a Manager Block (demoPanel FB)
Rather than manually calling demoButton 10 or 100 times in ladder networks, we create a master handler block called demoPanel.

Inside demoPanel:

- We declare buttons as Array[*] of “button” in InOut. This makes the block independent of the array size.
- In the Static section, we define an internal array of function blocks: buttonsFunction : Array[0..10] of “demoButton”.
- In SCL, a single FOR loop iterates through all buttons dynamically using LOWER_BOUND and UPPER_BOUND:
Step 5: Call in OB1 and Test
- Call demoPanel inside Main [OB1], allocating its instance data block (demoPanel_DB).
- Pass ‘globalDB’.button directly into the buttons pin.


Live Monitoring:
- Button 0 (Latched mode): When a momentary pulse is simulated on button[0].command.enable, the feedback button[0].feedback.enabled latches to TRUE and stays set even after the pulse goes FALSE.
- Button 1 (Momentary mode): Tracks the command state directly.


If you found this helpful, please consider supporting with a small donation. Thank you!
Leave a Reply