Building a Structured Text User-Defined Function Block (UDFB) using Siemens TIA Portal

Article summary

Continue an exploration of a PLC state machine contained within a UDFB. A previous article introduced the UDFB in ladder logic form. This article expands and refines the UDFB using a structured text solution. It is written for intermediate PLC programmers taking the next step into program structure and organization.

:stopwatch: Estimated reading time: 6 minutes

Introduction to the structured text UDFB for a motor starter

The User-Defined Function Block (UDFB) is the cornerstone of Programmable Logic Controller (PLC) programming. The UDFB encapsulates PLC code into a convenient container that is then instantiated into a larger program. The power and convenience of the UDFB becomes apparent when a collection of UDFBs is maintained to form the core of a PLC library. The programmer operating with the confines of the PLC software tools is free to program the UDFB using their preferred IEC 61131-3 PLC languages.

This engineering brief is a continuation of the Siemens TIA Portal UDFB conversation as developed and tested on a Siemens S7-1200 CPU 1215 FC. A previous article introduced a ladder logic-based UDFB used to control and monitor a three-phase motor starter. This installment provides the equivalent UDFB built using Structured Text (ST) featuring a case statement as shown in Figure 1.

This is a valuable exercise as constructing the same logic functionality but with different languages allows us to compare the results. We can then make a qualitative statement about which method is better for both the technicians and the PLC programmers.

The reader is assumed to have experience with both ladder logic and structured text. The ability to fluidly translate combinational logic circuit between languages is assumed as is the use the move function.

The UDFB description may be downloaded:

Figure 1: Structured text showing a case statement commanding the state machine to act based on the value of unsigned integer uiState.

Author’s reflections (experience): This article would not be complete without mentioning the changing landscape of AI. Perhaps you have heard about “vibe coding” along with the contrasting promise and danger associated with AI.

In my opinion the AI is a powerful tool that can help organize and even code reasonably complex structured code for your PLC. This is especially true for UDFB design as the problem space is well defined and limited in scope. This is the perfect place to leverage the strength of the AI.

Does this imply that the programmer will be replaced? I sincerely doubt it as the greater PLC programs are anything but simple. The control world will still need a knowledgeable programmer to understand the relationship between PLC program and machine operation. There is also the continued benefits of ladder logic based solution for ease of real-time debugging.

Perhaps we can agree that the responsibilities will shift from low level programmer to PLC architect with the AI constructing the lower level building blocks.

Tech Tip: Hungarian notation is used for the featured program. This practice is addressed in the PLCopen Coding Guidelines. While it is assigned a low priority, it is useful in an education or collaborative environment as it adds a degree of program clarity. It is especially useful in a UDFB, as each type is clearly identified This is especially useful when instantiating a UDFB in a top-level ladder diagram.

The prefix as used in this document are:

  • x = type Boolean
  • ui = type unsigned integer
  • tim = type time
  • str = type string (character array)

In addition, we used the St prefix to indicate a state constant. As will be shown in the next section, this greatly increases program readability.

Review of the state-based logic for the motor starter UDFB

Down arrow to open the summary

In the previous article we described the motor starter control logic in terms of states. The states and fault triggering conditions are repeated here for your convenience:

Motor starter states

There are five states incorporated into the UDFB. The rudimentary failure associated with each state may be detected by monitoring the feedback from the motor starter’s auxiliary contacts.

  1. Open: The motor starter is in an inactive state with no power applied to the contactor’s coil. The UDFB will enter a fault state if the motor starter unexpectedly closes for longer than timGlitch. This could occur when a technician uses an insulated screwdriver to force the motor starter’s armature.

  2. Closing: The motor starter’s contactor is transitioning from an open to a physically closed state. The UDFB will enter a fault state if the contacts fail to close within timTransition. Figure 1 shows the UDFB that has faulted from this state.

  3. Closed: The motor starter on the associated motor is running. The UDFB will enter a fault state if the sensor signal is momentarily lost for a period longer than timGlitch. This fault could be caused by a loose drive wire leading to the motor starter or the feedback line. It could also be caused by an overload event which would trip the motor starter via the thermal overload block.

  4. Opening: The motor starter’s contactor is transitioning from a closed to an open state. A fault is triggered if the contacts do not open within timTransition as this implies that the primary or interposing relay contacts have been welded together.

  5. Fault: The motor starter is in a fault condition. It will be released when the enable signal is disabled and the reset button is pressed.

Components of a structured text UDFB

The structured text UDFB is organized as a state machine. This structure is reflected in this code snippet. We start with a case statement that switches based on the value held in #uiState. Then, like the previous ladder logic program, we enumerate the states using constant. For example, the uiStClosed is mapped to the decimal value 2 which is defined as an unsigned integer. Be sure to review the previous article for a full description of the sates.

CASE #uiState OF
    #uiStOpen:
        ;
    #uiStClosing:
        ;
   #uiStClosed:
        ;
   #uiStOpening:
        ;
   #uiStFault:
        ;
    ELSE
        ;
END_CASE;

State structure of the motor starter UDFB

Each state is designed with the following structure:

  • Default timer configuration.

  • State change based on xEnable. This UDFB is level sensitive with xEnable as the primary input. Under normal condition, the state machine will transition through the transition states uiStClosing and uiStOpening on its way to uiStClosed and uiStOpen.

  • State change based on xSensor. This input is the primary feedback mechanism used to ensure that the motor starter is responding and enters the correct state at the correct time.

  • State change based on a timer timeout such as when the motor starter contactor fails to close in timTransition.

  • Logic for four UDFB’s Boolean outputs.

TechTip: While the ladder logic and the state machine implementation look different, they are fundamentally the same structure. Recall that it took five ladder logic networks to describe the code. Now, in this example, we see that it takes about 100 lines of structured text code.

Note that the advanced (single use) timer implementation expands the size of the structured text.

Also, there is some redundancy in the structured text for consistency of code structure. This is most notable in uiStClosed state where the ELSIF statement checks xSensor when we know that the critical data is implicit in the xTimedOut variable. To understand this statement consider the operation of TON when fed xTimerEnable := NOT #xSensor;.

Timer consideration for the motor starter UDFB

A PLC’s timer consumes a finite memory as well as time as the PLC cycles through the program. In the previous ladder logic solution, we deliberately prioritized clarity by using four independent timers.

In this ST implementation we use a single instantiation of TON which is used across four states. Use of a single timer adds complexity as the timer requires multiple lines of code including:

  • Timer instantiation
  • Load of a state-specific timer Preset Time (PT)
  • Maintenance of a state-specific activation of the timer (enabled at the correct time)
  • Conditional statements to determine if the timer has expired

Example timer instantiation

The timer instantiation is included in the following code snippet. This is a typical instantiation of a TON called Timer. The enable input signal is mapped to xTimerEnable and the PT is mapped to the variable tiDelay. Finally, for program clarity the Q output is mapped to the local variable xTimedOut.

(* This single TON is used across multiple states
     CAUTION: Be sure to momentarily turn off (reset) the TON's enable signal for each state transition.
*)

"Timer".TON(IN:=#xTimerEnable,
            PT:=#timDelay);

#xTimedOut := "Timer".Q;

TechTip: When reusing a timer across multiple states we must ensure that the enable signal is disabled when reloading PT which occurs for state transitions. This prevents unintended changes in the TON’s Q output which could in turn trigger unintended state transitions.

Example timer reload and activation

The following code snippet presents the logic for the motor starter’s open state. The are five lines of code associated with the timer.

  • The first line in this state enables the timer based on the state of the sensor. The second line sets PT to the timGlitch input. Together this enables the timer with the ability to reject glitches such as contact bounce.

  • We see a #xTimerEnable := FALSE; statement associated with every state transition. Note that these are effectively one-shot operations. Consequently, the timer will be disabled for a single cycle.

  • Finally, we see the IF statement using the value of #xTimedOut. This statement will force a transition to the fault state if the sensor does not toggle within timGlitch.

    #uiStOpen:
        
        #xTimerEnable := #xSensor;          // Allow for contact bounce
        #timDelay := #timGlitch;
        
        IF #xEnable THEN
            #uiState := #uiStClosing;
            #xTimerEnable := FALSE;
        ELSIF #xSensor AND #xTimedOut THEN  // Technically, there is no need to check #xSensor as the value is reflected in the TON.Q. Retain the structure for clarity.
            #uiState := #uiStFault;
            #xTimerEnable := FALSE;
            #strFaultCondition := 'Contactor Forced';
        END_IF;
        
        #xCoilDrive := FALSE;
        #xValid := TRUE;
        #xBusy := FALSE;
        #xFault := FALSE;

Real time monitoring and debugging of a structured text program

Real-time monitoring and debugging are essential skills for people who interact with a PLC. This includes the service technician, the installer, and the original programmer. Ladder logic with its graphical rung, contact, and coil highlighting has a distinct advantage as it is easy to read. Yet, it’s important to recognize that PLC debugging tools are not limited to ladder logic.

Structured text has similar monitoring tools as shown in Figure 2. Here we see a real-time representation of the featured UDFB running on a Siemens S7-1200 CPU 1215 FC.

A series of reference numbers have been added to the Figure 2 graphic to clearly identify the variable of interest. We begin by recognizing that the IF statement evaluates as true, as indicated by the green highlighted block. Also observe that the down arrow associated with green Result box has been opened revealing the value of the variables used within the IF statement.

In English, this conditional statement tells us to leave the fault state when the block is disabled, the sensor (motor auxiliary feedback) is disabled and when the reset button is pressed. The red highlighted number indicate the placement of the associated variables within the IF statement as well as the right-hand debug window.

We observe the values for xEnable, xSensor, and xReset as FALSE, FALSE, and TRUE respectively. Close inspection reveals that xEnable and xSensor are negated from within the IF statement. Taken together, we see that all three values are true, causing the IF statement to evaluate as true.

While this is not a complicated process, it does add slight cognitive load as the NOT operator is not explicitly included in the right-hand debug window. Unlike ladder logic, we need to consider both the modifiers (e.g., negation) and the variables at the same time. There is a good argument to be made for the simplicity of ladder logic especially in those 3 AM service calls.

Figure 2: Screen capture of the live debug for structured text showing that the IF statement evaluates as true.

Is structured text better than ladder logic?

Strictly speaking, no!

The best programming language is the one that reduced equipment down time over the lifetime of the equipment. Always remember that equipment downtime with cost ranging from $100 to $1000 per minute will quickly erode any front equipment or programming costs.

In my opinion, the ladder logic vs structured text debate is complex and demands that we consider:

  • Type of PLC
  • Type of equipment being controlled
  • Complexity of program including the total number of operations as well as the hierarchical design
  • Workforce training, especially when we consider that technician training may not have time to explore structured text
  • Workforce turnover
  • Emergence of AI programming with a clear preference for assistance with structured text.

Parting thoughts

As seen in these two articles, ladder logic and structured text may be designed with similar logic namely, the state machine with the state maintained as uiState. The ability to fluidly transition between the two languages is a skill every PLC programmer should master.

Like an archer, we learn to hit the target not by making 1000 shots from the same position but 1000 shots from slightly different positions. Stated another way, explore a variety of PLC and programming languages as there is no one best solution and you are likely to encounter many variations in your career.

Best wishes,

APDahlen

Related articles by this author

If you enjoyed this article, you may also find these related articles helpful:

TL;DR

  • Review operation of a UDFB encapsulated state machine designed to control and monitor a three-phase motor starter
  • Guidelines for use of a single timer across multiple states
  • Guidance for the age-old question: “is ladder logic is better than structured text?"
  • A series of academically rigorous questions are available
  • A PDF of the structured text is available for download here: UDFB_ST.pdf (148.0 KB)

About this author

Aaron Dahlen, LCDR USCG (Ret.), serves as an application engineer at DigiKey. He has a unique electronics and automation foundation built over a 27-year military career as a technician and engineer which was further enhanced by 12 years of teaching (interwoven). With an MSEE degree from Minnesota State University, Mankato, Dahlen has taught in an ABET-accredited EE program, served as the program coordinator for an EET program, and taught component-level repair to military electronics technicians. Dahlen has returned to his Northern Minnesota home and thoroughly enjoys researching and writing articles such as this.