TwinCAT HMI – Your first project (project, upload, server config)

The web based TwinCAT HMI brings us many new unseen posibilities in the world of industrial HMI development. This post will guide you thru the whole process of creating project, using some basic elements, bind variables from PLC, load HMI to PLC and setup HMI server.


  • You should able to create a TwinCAT PLC project and load it into a PLC
  • You should have a clue that TwinCAT’s software PLC runtime on an industrial computer is literally the same thing that runs on your computer after you install TwinCAT. + how to load the program into this Local PLC
  • You should have some knowledge of working with the TwinCAT XAE Shell or Visual Studio environment
  • Administrator privileges for installation of the HMI on your computer

What you should expect form this article

  • Add HMI as a part of another solution with the PLC program
  • Create the most basic HMI screen with a few elements
  • Link these elements with PLC variables
  • Try a few ways to work with elements and variables
  • Use Live View (somebody would call that a simulator)
  • Load the HMI to the PLC
  • The article may seem long but there is a lot of pictures and actually just a few things to do
  • This article was made with HMI version 1.12.758.8. Other versions of HMI was and probably will be same or very similar

*I will use terms PLC and IPC interchangably.

*Pardon me my grammar

Table of Contents

What is it even about?

So you’ve got to work with Beckhoff’s new TwinCAT HMI. Product page talks about future and the claims are not actually big. So what are we actually looking at right now? What does the future HMI hold? Let’s uncover possibilities of the TwinCAT HMI.

Installation files

First thing to consider is that we have two products of similar name laying in front of us. One is TF2000 and the other one is TE2000. And you gonna need both of them. The first one is the server. You gonna need this thing installed both on your workstation and on your IPC to run HMI. The latter one is the editor (or as the Beckhoff likes to call it – designer). It is WYSIWYG (means graphical) editor that will extend your TwinCAT development environment so you can create your screens (thus it is not needed on IPC).


First things first. You can download installation files for the two from the links in the previous paragraph. *Files are as usually free to download but you have to be registered at Beckhoff’s website. After that launch the installers and let them install one after another. Beckhoff’s installation process is simple as always …just click the Next button few times and you should be done. You must have TwinCAT XAE (the TwinCAT IDE) installed first before you run these.

Create the project

Before we head into creating HMI project, we have to create PLC project first. We will create some basic example PLC program just to show off some basic HMI functions later. So please create solution and the PLC project and continue with the next paragraph.

We will now add the new HMI project to the solution you have just created. In the Solution Explorer right click the Solution, than head to Add -> New Project.

Add another project to the solution

In the New Project window select the TwinCAT HMI Project option. Name your project and hit Ok!

Choose HMI Project

We have just created the HMI project.

Your Solution Explorer should look similar to this. It does not matter whether the HMI project or PLC project is
first or second.


To use TF2000 you have to add TF2000 licence to your PLC. The Server licence should include connection of one client. If you want to connect to the HMI from multiple devices at the same time you will need some of Client Pack licences.

Example code for PLC

We will try just few basic functionalities so the code will be simple. You will be sufficient with only the MAIN program which you should already have. Copy these lines into your MAIN file.

This program checks whether increment variable was just set and if it was it adds 1 to the counter variable. The modulo operator keeps the variable in range from 0 to 10.

	increment		: BOOL;
	counter			: INT;
	incrementTrigger	: R_TRIG;
incrementTrigger(CLK := increment);

IF incrementTrigger.Q THEN
	counter := (counter + 1) MOD 11;

Then load this PLC program to your Local PLC using Activate configuration. Try to login to verify it runs. When you are done, let’s finaly get started with the HMI!

Finally HMI – Add some basic elements

In the Solution Explorer under the HMI project open Desktop.view file as shown on the last picture. This is the default file that HMI server shows on HMI. It is similar to index.html when creating webpage.

On the right side of the TwinCAT editor you should see Properties/Toolbox window. I advise to pin it so it stays visible because you are gonna use it a lot. Also resize the window a little bit wider so you can conveniently edit Properties.

Toolbox window on the right

Our HMI description – what is it gonna do

We will create one button that will be binded to the increment variable. Thus when clicked will add +1 to counter variable. One input field to be able to directly change our counter variable. Then there will be two Textblocks (just simple element to display text). One of them will use an expression to add string and variable together. The other one will use event to watch for counter variable and then change color based on it’s value.

Now switch into Toolbox tab and drag and drop Button element into Desktop. Then add one Numeric Input and two Textblocks. Arrange them nicely.

Select desired element by clicking on it. You can resize it by using common controls such as dragging by the corners or move it by dragging with the mouse.

When element is selected switch right panel to Properties window. Here you will find many properties you can change.

On top of the Properties window you can find Identifier field. This is name of the element. Rename one of the Textblocks to “HelloWorldBlock” and the other one to “MessageBlock”. We made some preparation and now let’s map some variables from PLC.

Arranged elements and one of the Textblocks renamed to HelloWorldBlock

Bind variable to a button

Variables can be mapped either stright using dialog window when mapping variable to element or in Configuration window (you can open it using that little C in square in that thin strip between editor window and Properties/Toolbox window). We will go the first way this time.

In Properties window you may have noticed like a small dots or squares on the right of the property value. This dot serves the purpose of mapping variables. Select the button element you have placed in the workspace by clicking it and head to the Properites and find StateSymbol in the Common category.

Select button

Click the dot on the right of the field and select Create data binding….

Click Create data binding

Select Server symbols tab and here navigate to the increment variable from PLC. Once you found it hit OK button in the bottom to map it. *You don’t have to click “Map Symbol” button. That is here for when you want to also map other variables to the HMI before you bind this to the element. When you press OK, your selected variable is mapped automatically.

The Server symbols tab is basically ADS symbol browser
You should now see this

You should end up with the variable increment mapped to the StateSymbol of the button. What this is doing is that when you click the button, the mapped variable will be held TRUE as long as you hold the button. It will be reset to FALSE once you release the button. So the standard button function.

Mapping = variable from PLC is made known to the HMI (you can see all mapped variables in Configuration Window)

Binding = variable in HMI (mapped from PLC, internal or whatever) is connected to the element’s property

Bind variable to an input field

Mapping of every property is done completely same way as we did with the StateSymbol property in the button. Mapping of Value properties for input field elements is also the same but with the little twist in the end to allow write to variables.

So click the Numeric Input element and find Value property in the Common category. Click the dot, select to Create data binding… and in the dialog find counter variable. This part was exactly same as with the button. Now the field can only read variable value. To make it able to write the value you have to change Binding mode.

Now you have two meaningless options. You either double click the blue symbol or right click the symbol and select Edit symbol….

Edit symbol in input field elements

The Edit Binding dialog will show up. In the Binding mode select TwoWay option and hit OK. This ensures that element can write into variable. Remember this only applies for values of input field elements. You will probably not find this option anywhere else.

Edit Binding dialog

You should now end up with this binding. See the two arrows on the left of the symbol telling you it is the two way binding.

Two arrows on the left of the symbol represents two way binding

Show a message using formula

So let’s continue with another element. This time we will see how we can use the symbols to write JavaScript formulas stright into the parameter fields.

Select Textblock that we named MessageBox and find Text property in Common category. Click the dot on the right as we did before. But now select Create function binding….

Click Create function binding…

The field border will turn blue. Other way to switch between Data binding, Function binding or constant value is by clicking the symbol on the left side of the field. If you do not see any symbol here, just use the dot on the right side.

Button to switch binding type

Once you have Function binding selected we can continue to add some text and values. When you are switched to the function binding, the content of the field is now JavaScript code. This brings many powerfull posibilities. When you use the binding symbols inside your JS formula, the symbols are resolved first and after that the JS code is executed. We will now write text that contains value of the counter variable.

Because we are writing JS expression you have to write string inside quotation marks. Type in the following:

"counter value is: " +

The “+” character is used to concat strings in JS. Now we want to add a symbol. If we bind the symbol using the dot on the right it will overwrite the whole field and we don’t want that. So because we have variable counter already mapped to the HMI we can start to write “counter” and TwinCAT will give you suggestions of some symbols with similar name as you write. If you for example click outside and the list of suggestions will hide you can bring it back using shortcut Ctrl + Space (the same way you bring up the code suggestions in TwinCAT PLC program editor).

Code hint is invoked automatically or by shortcut Ctrl + Space
It is the same thing you use in PLC editor or anywhere else in programming

Since this is a JS code you can write literally almost any JS code here if you are clever enough (it is best to use just oneliners because if you write multiple lines the editor will place endline characters in the code and screw it up).

Another way to do this is to Create data binding and once you have desired symbol in the field you just write the rest of the code around the symbol. Or you can copy and paste the symbols. The binding type will automatically change to the function binding.

You may have noticed Colorfull letters under the list of hints and one of the letters, the “S”, is the same as in our PLC variable symbols. These letters symbolize the symbol origin. “S” means it is server symbol (i.e. it is mapped from PLC). “I” means internal symbol (you can create variables inside HMI). “C” means controls (controls are called all elements that you place on the HMI. You can access all their parameters).

Change value using events

We came to our last element HelloWorldBlock. Before learning events, let’s set it’s Text property to Hello World! value and desribe logic of what we are going to do!

So our current goal is to change color of this element based on value of counter variable.

Creating events consists of three steps

  • Go to Events page of Properties window
  • Choose event
  • Create program using graphics language

First we have to switch Properties window to Events page. That is done in Properties window in the top right corner by clicking on the icon of bolt. The key icon are properties and the lock icon are user permissions (HMI has it’s own user management and you can have different user with different permission logged in on each screen).

Here you see a list of events you can use. In Custom category you can bind variables that will be checked for value change and if the value has changed the program in the event will be executed. Then there are build-in events like .onAttached (element is attached to the webpage… = is loaded after you change the screen) or .onPressed.

We will bind our counter variable to be watched for change. Click the dot behind empty field in Custom category. Then find our counter variable from PLC and hit Ok same as you did to bind variables before.

You should end up with event binded to counter variable. So we have our event created but it does nothing right now. Let’s add some program – some actions and conditions to it. Click the pen icon on the right.

You will be greeted by an empty Actions and conditions window. Most of the window is workspace (where you build your program). On the left is the list of items you can use to create that program. In General category are building blocks of the program. Then there are 3 categories of controls. Functions are HMI wrapped JavaScript functions (there are some useful built-in functions and you can also create some yourself) and Action Templates are basically functions for this Actions and conditions graphical programing.

So let’s check the variable and do some actions. From the left column in General category drag the Condition item and drop it into the workspace. We will compare if counter variable is greater or equal to 5. Fill the fields as you learned in previous chapters.

When the condition is true we will change the background color of our HelloWorldBlock to some color of your choice else we will change it back to default.

In the left column go to Selected Control category (that is our element) and find it’s BackgroundColor property. Drag that property into the green array of the THEN branch of our condition. This will automatically add WriteToSymbol action for your property. Now click the value and go to Solid color palette. Choose some nice color.

You can now select the Write To Symbol action and copy-paste it into the red area (as well as Ctrl + drag’n’drop) of the ELSE branch.

Here click the value again and change it from color palette to the Theme.

Our program for the event is done. Hit OK and you should see this. You have just created event.

Events are very usefull here. In the Custom events you can bind not just numbers or other primitive types but whole function blocks as well.

On of the most used events is .onPressed which is called after you press the button.

All elements have events. They usually have at least these basic like .onAttached and .onPressed. So you can use almost anything to serve as a button.

Show HMI in Live-View “simulation”

So we have finished our HMI and it’s time to see our result in action. For this purpose we will use something called Live-View. It is a tool for viewing your HMI without loading into PLC. On some other platforms you would use simulator for this purpose. What is special on this is that Live-View literaly is “Live”. You just run the Live-View in the matter of seconds and you can see all the changes you make instantly as you edit.

Running Live-View is as simple as it gets. On the right edge of your workspace there is a thin strip of small and hard to click buttons. One of them is “C” for accessing HMI Configuration as I have mentioned earlier. The other one with letter “L” is for access to Live-View. The top one of these four buttons will show you Document outline window (shows a tree of elements you have placed on the screen). So let’s open Live-View by clicking on the button with “L”.

This window will show up. That’s it. You can try your HMI now.

But hold on! This window is very cumbersome as you can see. You can not hide it (just close it) and it is hard to edit your HMI with this over your screen. You can also place it as a tab in TwinCAT right next to your open files. But since TwinCAT HMI editor is not exactly fast, you do not want to do that either. And there is a great other way to see Live-View.

At the end of the top toolbar in Live-View window you may recognize familiar name and it should be a name of some internet browser. By clicking on the arrow on the right you may choose which browser you want to use as default.

By clicking the big button with the internet browser’s name on it you will open the HMI in your internet browser. Such wow!

You can now fully test the HMI you created as well as you could in the Live-View window. Try to move elements around the screen to see that the update is instant.

Pressing the button will add 1 to the counter variable in PLC. You can also overwrite the variable’s value using the input field we have used. The textblock on the bottom should always show the text with the same value as in the input field. The HelloWorldBlock should change it’s color to green when the counter is 5 or more.

Publish = upload to PLC

Loading the project into PLC is easy too. Beckhoff calls it Publish. –Could it be because you are publishing webpage? We will never know.– We will now Publish our HMI into server that runs on your computer as well as we have loaded PLC program into our local PLC.

In the top toolbar head to TwinCAT HMI -> Publish to TwinCAT HMI Server….

There you will find window asking to name the server for publishing. Type some name.

And now fill your server details. You can use the button on the right of the server field to search for available servers.

Wait….what?? What password? Why does the server search won’t find anything?

That’s because we have fresh install of the server and we have to configure it before we can use it. Head to the next chapter to configure the server and then return here.

So when you have the server configured search for the servers again. It should find two localhosts. One without encryption (port 1010) and one with encryption (port 1020). Choose whichever you want.

Than fill in the same password you set when initializing server.

Let’s test out whether the connection to the server works.

If the connection works you can hit the big Publish button to load the HMI into the server.

In the bottom bar of the TwinCAT you can watch the progress of the upload.

The default setting is that the HMI webpage is automatically opened once the publishing is finished. You can change this setting in the Settings on the Publish screen.

And that is all ladies and gentlemans. We have created simple HMI, connected variables from the PLC and published it to the HMI server.

One more thing – Stuck with the Publishing screen?

If the publishing has finished and you still see a screen like this and it won’t go away you do not have to go to the PLC screen to reload the webpage so the HMI works. Just hit Validate connection and the HMI will refresh.

In the time of writing this has been happening to me for like the past six months or so. Beckhoff pls fix this.

Configure the TF2000 server

We have fresh install of the server so we have to configure it. In the windows notification area find icon of HMI server and click it. You can see two servers here. In my case the upper one running on port 3000 has the same name as my HMI project in TwinCAT XAE and it serves to show you content in editor and Live-View. You will see it will disappear when you close TwinCAT.

Than there is this second one called Service on port 1010. Uncover it’s options and click the Config option. By clicking the Start Page button you can access your HMI once you have Published some.

The HMI config webpage should appear. You will get this horrifying red text instead which tells you to restart server to initialize it. I suppose this is some safety feature.

So head to the same place in the tray and hit Restart this time.

You will be asked by UAC to allow changes in your computer. Confirm it.

Return to you web browser and reload the webpage with the red text.

You should now see a prompt to set admin password. Choose your password (my personal favourite is “1234”) and confirm with Set button. You will be redirected to the HMI server’s config webpage.

This is it. You have just initialized HMI server. You can now return back to publish your HMI or rather see the two following settings.

#1 Optional – turn of authentication for access to HMI

*This applies only for published HMIs. Not for Live-View.

This is very usefull at least when you are developing the HMI. You will not have to type password everytime you open the webpage with HMI. You can also create users in the HMI and give them passwords and rights. Than you can choose one of those users with low privileges (e.g. “Operator”) and set his account to autologin. Other users will have to login.

In the Solution explorer go to Your HMI project -> Server -> TcHmiSrv. In the top of the window make sure you have Publish configuration set to remote as you can not Publish “default” configuration. Then set Authentication required to None and Accept the changes.

When you Publish the HMI you will not have to type password to access it now.

#2 Optional – add PLC endpoint

If you are publishing the project to the server on the PLC it may happen that you will not find the PLC’s server or the connection will be refused. In that case you will have to add endpoint to the server. Creating endpoint is like making the service accessible on the defined address to other devices or services.

On the PLC head to the server config. Than in the Webserver tab find Endpoints and open them.

Add new endpoint and type in the web address of the server accessible to the outside. The address will probably consist of your PLC’s IP and port you want to use (be aware of the different protocol for the ports – for encryption you have to use “https” and port 1020).

Add, Accept and you should be able to find the server now. You may also restart the server.

Endpoint WARNING! In the current version 1.12.758.8 there is an ERROR

If you add the endpoint it can happen that the endpoint will be added twice. In this case the endpoint will not work. You will have to fix this situation somehow on your own as I have not came to reliable way to fix it yet.

Beckhoff pls add less bugs to this wholesome thing🙏Pls

– Me –

Final tips

It is more pragmatic to create project for PLC and project for HMI in two separate solutions. First beacause of performance of TwinCAT when switching or opening HMI files and second because of git.

Debugging tip: If you are not sure whether the symbol is read properly you can put any symbol into Textblock and it will show you the whole JSON object of the symbol. Then you can see whole object at once.

Great help when debugging HMI

If you want to use button to just set a bit instead of set and reset after releasing the button, just use the .onPressed event to write into variable.

Final word

Bekchoff’s TwinCAT HMI is modern web based tool to control PLCs. The web based nature and the framework which is actually taking advantage of it allows for unseen possibilities. You can change and bind variables to almost any property of the elements. Elements can be made scalable or responsive as well as whole HMI. And what can not be done standard way can be done using powerful JavaScript or CSS styles.

Beckhoff is often releasing new versions of the HMI with fixed bugs and introducing new functionalities but also introducing new bugs which is a pity.

I would suggest anyone to try this framework. The possibilities it brings are worth it.

Example file

9 MB


3 responses to “TwinCAT HMI – Your first project (project, upload, server config)”

  1. Jakub Avatar
    Why I don’t see any varriables Server Symbols?
    1. admin Avatar

      Is the PLC running on your PC?

  2. Bernd Dreyer Avatar
    Bernd Dreyer
    I have reprogrammed the example exactly according the instructions now.

    I seemend to work properly now.

    However, after the most recent NuGet update, I get an error message as follows:

    Build Option ‘suppressImplicitAnyIndexErrors’ is deprecated and will stop functioning in TypeScript 5.5.

    Specify compilerOption ‘”ignoreDeprecations”: “5.0”‘ to silence this error.

Leave a Reply

Your email address will not be published. Required fields are marked *

Optionally add an image (JPEG only)