Siemens PLCs do not include native enums, but we can replicate them using global symbolic states names under the user constants tab of a PLC tag table. This is a case study using the conveyor and Banner K100 beacon shown in Figure 1.
This article is part of the DigiKey Field Guide for Industrial Automation
Location: Program It → State Machines
Difficulty:
Engineer — difficulty levels explained
Author: Aaron Dahlen | MSEE | Senior Applications Engineer, DigiKey
Last update: 06 Mar 2026
Figure 1: Benchtop view of a conveyor section with Banner beacon and Siemens ET 200 in the background.
What are enumerated states?
A state of an FSM is maintained as an integer. There are two ways for a programmer to refer to this memory location including:
-
Directly by the numeric value: We use numeric values such as 0, 1, 2 or 3 to identify the states.
-
Symbolic constants: Instead of numeric state, we use symbolic constants such as idle, halted, running, or fault. These named (enumerated) states are significantly easier to follow, especially for the technicians and engineers who maintain and modify the system. As an example, consider the snippet in Listing 1. This is part of a larger case statement describing the exit conditions for the running state.
"gcCONV_STATE_RUNNING":
#strDebugState := 'Running';
IF NOT #xEnable THEN // Not enabled
#intState := "gcCONV_STATE_HOLD";
ELSIF #TimerQ.xMaxTravelTime THEN // Jam
#intState := "gcCONV_STATE_FAULT";
#strFault := 'Error STATE_RUNNING: Part did not exit in preset time.';
ELSIF (#intAccum = 0) THEN // Conveyor empty
#intState := "gcCONV_STATE_DELAY_OFF";
END_IF;
Listing 1: Portion of the conveyor sequencer’s case statement.
Tech Tip: The state names include the Hungarian-style prefix global constant (gc). They are also formatted in a screaming snake case for easy differentiation from local variables.
Does Siemens support enums?
Siemens does not currently support C-like enums as shown in Listing 2. However, we can achieve enumerated constants using:
-
Local constants defined within a function block. This is effective, but the scope of the constants is limited to the sequencer.
-
Symbolic states names defined within a database. This is not safe as the variables may be overwritten (mutable).
-
Global user constants defined within a PLC tag.
We will focus on the last option, as the symbolic references are global and cannot be accidentally overwritten. This is a simple solution for sharing the state variable between the conveyor’s sequencer and the Banner beacon. The integer variable itself is maintained locally within the conveyor sequencer. It is then passed to external blocks. The programmer uses the same symbolic references across sequencer and display block.
// This is C code example, not structured text.
typedef enum {
STATE_IDLE = 0,
STATE_HALTED,
STATE_RUNNING,
STATE_FAULT }
States;
Listing 2: Conventional enum found in C programming.
Defining the State Constants
An example is shown in Figure 2 where the conveyor’s symbolic states are defined in the User constants of a PLC tag. Recall that the PLC tags tables are where we map the PLC’s physical I/O into convenient tags such as gxSW1 or gxPLGreen.
Note that we must manually add the numbers to the enumeration. This isn’t automatic like our C counterpart (Listing 2), however, it takes seconds to assign the numbers after the symbolic names have been entered.
In this example I chose to use an independent tag table for the conveyor states. I could have integrated them into the tag table associated with the conveyor. This would have closely associated the physical device with its constants. However, in this project, I chose to keep the ET 200 distributed tags as a single entity.
The conveyor’s state constants are included as Figure 2.
Figure 2: The state constants are held in the user constants tab within a PLC tag table.
Using the Symbolic State Constants
Figure 3 shows the blocks for the conveyor’s sequencer and the Ladder logic showing the conveyor sequencer and the BannerK100 Blocks. Observe that the sequencer exposes intState which is coupled to the tag MainTags.intState.
Listing 1 demonstrates the utility of the symbolic constants within the sequencer block. Figure 4 shows how they are used in the Banner K100 function. In this example, the K100 beacon’s black wire is driven if the conveyor is in the pre-arrival state of the running state.
Figure 3: Ladder logic showing the conveyor sequencer and the Banner K100 Blocks.
Tech Tip: Technically, intState is just another integer. It is the symbolic names that make it easy to remember across function blocks. Instead of remembering what happens in state 2, we can easily remember STATE_RUNNING.
Figure 4: Usage of the global state variables in the Banner K100 function.
Direction of the Enumerated States
There is no intrinsic direction for handling the enumerated states:
-
Sequencer to beacon: The beacon uses the sequencer’s state constants such as CONVEYOR_RUNNING or CONVEYOR_FAULT.
-
Beacon to sequencer: The sequencer uses the beacon’s constants such as DISPLAY_RUNNING or DISPLAY_FAULT.
Keep the program simple. After all, the sequencer is already too complex. We should pass the mapping task to the beacon function where it can be handled in a few lines of ladder logic as shown in Figure 4.
Parting Thoughts
Clarity is one of the most important aspects of PLC programming. The global enumerated constants described in this article greatly simplified the program. This is especially true for the sequencer where we can use simple constants across all modules.
Best wishes,
APDahlen
Continue Exploring Industrial Control Systems
If this discussion was helpful, you may also want to explore:
DigiKey Navigation
- Full Catalog: Industrial Control & Automation
Related Foundational Articles
- Introduction to the 3-Wire Start-Stop Circuit
- Use of an Interposing Relay for Increased Contactor Speed
- Applications of Type PNP and NPN Sensors
About This Author
Aaron Dahlen, LCDR USCG (Ret.), is a Senior Applications Engineer at DigiKey in Thief River Falls. His background in electronics and industrial automation was shaped by a 27-year military career as both technician and engineer, followed by over a decade of teaching.
Dahlen holds an MSEE from Minnesota State University, Mankato. He has taught in an ABET-accredited electrical engineering program, served as coordinator of an electronic engineering technology program, and instructed military technicians in component-level repair.
Today, he has returned to his home in northern Minnesota, completing a decades-long journey that began with a search for capacitors. Read his story here.



