DMC, Inc.
Grey HMI screen on a red background

Getting Started with Beckhoff TwinCAT HMI: Simple Project Setup Tutorial

Beckhoff TwinCAT HMI provides a responsive engineering design environment for building industrial web-based user interfaces. Because it is built on standard HTML5 technologies, TwinCAT HMI applications can run in any modern web browser. Its flexible architecture and extensive built‑in feature set make it well-suited for everything from simple operator panels to complex, scalable HMI systems. In this article, we will go over basic project setup for TwinCAT HMI by walking through a simple project. 

Prerequisites 

  1. TwinCAT XAE installed 
  2. TwinCAT HMI installed 
  3. PLC Project built and running (see bonus information for the PLC Code used in this example)

Project Setup

Creating the Project

With the prerequisites checked off, we can start the basic project setup for the HMI. Begin by right-clicking the solution in the Solution Explorer project tree and selecting Add > New Project. When the Add New Project window launches, navigate to TwinCAT HMI > TwinCAT HMI Project and name it whatever you like.

Context menu in Microsoft Visual Studio, a widely used integrated development environment (IDE) for software engineering.
This image shows the "Add New Project" dialog box within the Beckhoff TwinCAT 3 engineering environment.

Linking Tags 

The first step in setting up a TwinCAT HMI project is linking PLC symbols to the user interface. This is done by exposing symbols to the TwinCAT HMI Server and binding them directly to HMI control properties.

Navigate to TwinCAT HMI > Windows >  TwinCAT HMI Configuration.

From TwinCAT HMI Configuration, navigate to All symbols > ADS > PLC, and wherever you have your variables defined, in my case ‘MAIN’.

Note: If ADS is not appearing, check your ADS Route (review the bonus information to learn how). 

From here, you can right-click on a variable and hit ‘Map Symbol’. You can also simply double-click on a symbol to map it. We have now successfully pulled the PLC data into the HMI Server.

Now, we can bind these tags to controls in the HMI screen. Navigate to ‘Desktop.view’. This is the main screen on which we will develop.

Screenshot showing the TwinCAT HMI Configuration window in Beckhoff TwinCAT 3 engineering software.
Image displaying the project structure for a Beckhoff TwinCAT HMI project within Visual Studio.

Creating Controls 

On the right pane, we have properties and the toolbox. These are used to add and edit controls within the project. We’ll start by dragging a Button into the project.

After your component is added, you can then select it to edit the Properties tab. For a basic button, we will want to create a data binding for the state symbol. Click the square to the right of the text field to link tags and select ‘Create data binding’.

Image of a property configuration menu within the Beckhoff TwinCAT 3 HMI engineering environment, specifically allowing users to bind properties to data or functions

This opens the symbol browser where you can select mapped PLC variables. On my screen, some variable groups include ‘ADS’, ‘PLC1’, ‘Global_Version’, and ‘MAIN’. Within the ‘MAIN’ category, we’ll select the bRun variable. It is worth noting that you can also map symbols from this screen using the same method as in HMI configuration.

You should now see the name for that symbol populated in the ‘StateSymbol’ box. You can also hover over property names to see a description of what they do. Now, we will drag in an Ellipse to show how the Events tab works.

Image displaying the properties for a TcHmiEllipse control within the Beckhoff TwinCAT 3 HMI Engineering environment.

With your ellipse selected, navigate over to the Events tab indicated by the lightning bolt symbol. From here, you can see that there are many built-in events to configure, like .onMouseDoubleClick, .onMouseEnter, .onMouseLeave, etc. You also have the option to configure a custom event.

Click the small square next to the Custom field to map a symbol to this control. In our case, we will select ‘bState’. Once that symbol is mapped, click the pencil icon to open and edit the custom event associated with the control.

In the Events tab, you will see a drag-and-drop interface that allows you to define logic for the controller’s behavior. This visual workflow makes it easy to configure interactions without writing traditional code. For this example, we will use a Condition block. Drag the condition into the steps section, then begin populating the auto-generated fields.

This screenshot shows the Actions and Conditions Editor in Beckhoff's TwinCAT 3 HMI software

Here, we want to check whether the boolean variable bRun is set to ‘True’. If the condition evaluates to true, we will update the ellipse’s appearance to indicate an active state. To do this, drag the FillColor property into both the ‘then’ and ‘else’ branches. Set the ‘then’ color to green to represent a running state, and the ‘else’ color to grey to indicate that the system is not running.

This image shows the Beckhoff TwinCAT HMI development environment, specifically the MAIN screen configuration area.

Testing in Live View

After configuring this logic, it’s also important to establish your screen’s behavior. Return to the Desktop.View, where you will see a set of controls on the right-hand side. Click the ‘L’ button to launch the live view.

As you interact with the interface, observe the ellipse once again. When the button is pressed and held, the condition should evaluate to true, and the circle should toggle from red to green in real time. This confirms that your event logic is working as expected and that the control is properly responding to changes in the mapped variable.

User Controls 

As your HMI projects grow in size and complexity, maintaining reusability and consistency becomes increasingly important. TwinCAT HMI addresses this need through User Controls, which are reusable templates that combine multiple HMI elements into configurable, modular components.

To get started, create a new folder in your project called ‘UserControls’. This helps keep your project organized as your library of reusable components expands. Within this folder, add a new item and select ‘User Control’. From here, you can begin building a custom control that can be reused across screens, reducing development time and ensuring a consistent user interface.

Screenshot showing the context menu within the Beckhoff TwinCAT 3 HMI Engineering environment, specifically under the Solution Explorer with "New Folder" highlighted.
Image of a context menu in TwinCAT HMI Engineering within Visual Studio with "New Item" highlighted.

Once again, on the right‑hand side of the screen, you’ll see a set of small buttons. Selecting the ‘P’ button opens the User Control parameters. These parameters are configurable values that are passed into each instance of the User Control, allowing multiple instances to be created without modifying the control’s internal layout, grouping, or logic. 

Dialog box used to define parameters for a UserControl in TwinCAT HMI, allowing for custom, reusable interface elements.

We are going to create two parameters:

  • One for the HMI_PbLight struct
  • One String for the name of the component

Note: If your struct does not show up, try closing parameters, adding a button to your user control, and linking HMI_PbLight. Return to the parameters and the datatype should now appear as PLC1.HMI_PbLight, with String for sName.

Image shows the Edit/Define Parameters dialog window in TwinCAT HMI engineering software.

With the User Control parameters defined, we can now build the control in much the same way as before, with one key difference: instead of binding directly to PLC symbols, we bind each element to properties exposed by the User Control. The pushbutton is configured so its state and behavior reference the bRun member of the HMI_PbLight parameter, allowing each instance of the control to respond to its own data source.

In the same way, the ellipse used as a status indicator is bound to the bState variable within the same struct, and simple logic is applied to drive its fill color, green when the run condition is true and red when it is false. Finally, we’ll add a text element and bind its Text property to the sName string parameter, enabling each instance to display a unique label.

Image showing the Actions and Conditions editor within Beckhoff TwinCAT 3 HMI Engineering (TE2000).

Notice that none of the elements inside the User Control are bound directly to PLC symbols. Instead, each element references the variables exposed by the HMI_PbLight struct parameter. This indirection is what makes the control reusable.

Image of an HMI property configuration screen within TwinCAT program.

After saving the User Control, switch back to Desktop.View and you will see it appear in the toolbox alongside the standard HMI elements. From there, drag the control onto a screen, bind the HMI_PbLight parameter to a specific instance of the struct, and assign a name. Boom! With that single step, the control is fully configured, and you can now drop in as many instances as needed while maintaining consistent behavior, appearance, and logic across your HMI.

Bonus Information

Adding a Combobox

This section introduces a Combobox that allows the operator to change the light’s color behavior within the User Control. Rather than hard-coding the color logic, the Combobox provides a simple, configurable way to select between predefined color states at runtime.

Configuration dialog box for a TwinCAT HMI ComboBox control, allowing a user to add color entries for different system states.

To add the Combobox, navigate to SrcData, click the three dots on the right-hand side, and create a new data source that will hold the selected value. This data source is then bound to the Combobox and referenced by the User Control logic, allowing the selected option to drive how the indicator is displayed. By handling the color selection this way, the control remains flexible and reusable while giving each instance the ability to behave differently based on user input.

Next, define the selectable color options for the Combobox. Add three entries labeled Green, Yellow, and Red, and assign each one a corresponding hex color value in the Value category. These values will be used directly by the User Control logic to drive the appearance of the status indicator.

Once the options are in place, navigate back to the ellipse inside the User Control and update its custom action. For the bRun true condition, set the fill color using a function binding that references the Combobox selection: ({ color: %ctrl%TcHmiCombobox_1::SelectedValue%/ctrl% })

This binding allows the ellipse color to be determined dynamically based on the selected Combobox value rather than fixed logic. With that complete, you can add additional instances of the User Control to your screen, bind each one to a different HMI_PbLight [HO16.1] struct instance, and select the desired color from the Combobox. Each control now behaves independently, while still leveraging the same reusable design.

Basic PLC Project 

This section walks through setting up a simple PLC project to support a basic pushbutton and light, which will later be consumed by the TwinCAT HMI. Start by creating a new solution and selecting ‘TwinCAT XAE Project’. This initializes the TwinCAT environment and provides the framework needed to add PLC logic and HMI communication.

Image of s a Structured Text (ST) program, likely within a PLC environment like TwinCAT or CODESYS, used to control light indicators.

Once the project is created, navigate to the Solution Explorer, right-click on PLC, and add a new PLC project. This creates the runtime environment where the control logic will live. With the PLC project in place, we can define the shared data structure used by the HMI. Right-click on DUTs, select Add > DUT, and choose Structure. Name this structure HMI_PbLight and add two boolean members: bRun to represent the pushbutton command, and bState to represent the resulting status of the light.

Next, navigate to POUs > MAIN (PRG) and declare an instance of the HMI_PbLight struct along with any supporting variables. Add simple logic that drives bState based on the value of bRun, mimicking the behavior of a pushbutton controlling a status light. This keeps the PLC logic intentionally straightforward while clearly demonstrating the data flow between the PLC and HMI.

With the code in place, activate the configuration and log in to the PLC. If you are running TwinCAT on a local host, be sure to execute the required .bat script before logging in. At this point, the PLC is ready, and the HMI_PbLight structure can be bound to the HMI elements and User Controls created in the previous sections.

Updating to User Mode Runtime ADS Route

Image showing and ADS (Automation Device Specification) configuration screen within the TwinCAT HMI Server Configuration.

This final step ensures that the TwinCAT HMI Server is communicating with the correct runtime by updating the ADS route to point to the User Mode Runtime. Begin by opening the TwinCAT HMI Server configuration by going to TwinCAT HMI > Windows > TwinCAT Server Configuration. From there, navigate to ADS > Runtimes > AMSNetId. This setting defines which TwinCAT runtime the HMI will connect to for symbol access and data exchange.

Verify that the AMSNetId is set to the AmsNetId of your User Mode runtime, if that is the runtime you are using.

Image of a configuration screen for industrial network communication showing AMS Net ID field, selectable IP address options, and a setting to allow read-only access for connected devices.

This is especially important when running TwinCAT locally or when multiple runtimes are present, as an incorrect AMSNetId will prevent the HMI from resolving PLC symbols and binding data correctly.

Once the AMSNetId is confirmed, the HMI and PLC are fully aligned, allowing the User Controls and bindings configured in the previous sections to function as expected at runtime.

Conclusion

This tutorial walked through the foundational steps required to build a simple, reusable TwinCAT HMI project, starting with PLC structure design and basic HMI bindings, then expanding into User Controls and runtime configuration. By introducing the HMI_PbLight struct and gradually abstracting symbol bindings into User Control parameters, we demonstrated how to move from a single hard-coded screen toward a scalable, modular HMI architecture. The use of events, visual logic blocks, and configurable parameters highlights how TwinCAT HMI enables powerful interaction design without requiring custom scripting.

By the end of this project, you should have a working HMI that connects cleanly to a PLC, supports multiple instances of a reusable control, and allows runtime configuration via simple UI elements such as a Combobox. These same concepts scale directly to larger applications, where consistency, maintainability, and development speed become critical. Whether you are building a small operator interface or a plant-wide visualization system, following these patterns will help you create HMIs that are flexible, readable, and easy to extend.

Have an upcoming project? DMC can help you take the next step.

Take your project to the next level with engineering solutions from DMC. Learn more about our Beckhoff programming expertise and contact us to get started today!