//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2010, 2026 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
//
// This program and the accompanying materials are made available
// under the terms of the MIT License which is available at
// https://opensource.org/licenses/MIT
//
// SPDX-License-Identifier: MIT
//////////////////////////////////////////////////////////////////////////////

include::../_part_attributes.asciidoc[]

:leveloffset: -2

[[tools-plcgen-chapter-twincat]]
== TwinCAT PLC output

indexterm:[TwinCAT]
indexterm:[see: CIF PLC code generator,TwinCAT]
link:https://www.beckhoff.com/english/twincat[TwinCAT] is a complete link:https://en.wikipedia.org/wiki/Integrated_development_environment[IDE] for the development and testing of PLC controllers.
Using the TwinCAT <<tools-plcgen-target-type,PLC target type>>, the generated PLC code can be written to the native file formats of the TwinCAT IDE.

indexterm:[TwinCAT,system modes]
indexterm:[TwinCAT,config mode]
indexterm:[TwinCAT,run mode]

[[tools-plcgen-twincat-modes]]
=== TwinCAT system modes

The TwinCAT software IDE is built on Microsoft Visual Studio.
TwinCAT also supplies a utility to monitor and control the TwinCAT System Service, via an icon in the system tray, part in the Windows taskbar.
The icon shows the mode (or status) of the TwinCAT system:

* image:{tools-imgsdir}/plcgen/mode_inactive.png[]
Inactive Mode

* image:{tools-imgsdir}/plcgen/mode_stop.png[]
Stop Mode

* image:{tools-imgsdir}/plcgen/mode_config.png[]
Config Mode

* image:{tools-imgsdir}/plcgen/mode_run.png[]
Run Mode

* image:{tools-imgsdir}/plcgen/mode_ex.png[]
Exception Mode

In the _Inactive Mode_, the TwinCAT System Service is not running.
Restart Windows or manually activate the TwinCAT System Service and related services.

The _Stop Mode_ is of little use, so <<tools-plcgen-twincat-modes-change,switch>> to the _Config Mode_ instead.
In the _Config Mode_, the system (the PLC) can be configured.
In the _Run Mode_, the system (the PLC) can be used to control the hardware.
If a runtime exception occurs in _Run Mode_, the _Exception Mode_ becomes active.

Within Visual Studio, the mode is also shown as an icon in the bottom right corner of the IDE:

* image:{tools-imgsdir}/plcgen/mode_stop.png[]
Stop Mode

* image:{tools-imgsdir}/plcgen/mode_config.png[]
Config Mode

* image:{tools-imgsdir}/plcgen/mode_run.png[]
Run Mode

* image:{tools-imgsdir}/plcgen/mode_run.png[] / image:{tools-imgsdir}/plcgen/mode_free_run.png[]
Free Run Mode (alternating icons)

* image:{tools-imgsdir}/plcgen/mode_ex.png[]
Exception Mode

If the system is only equipped with a _soft PLC_, and the TwinCAT environment is set up to target the local system, both icons should indicate a consistent status.
This page assumes this situation.

indexterm:[TwinCAT,change mode]

[[tools-plcgen-twincat-modes-change]]
=== Changing modes

To change to _Config Mode_ or restart _Config Mode_ from the system tray:

* Right click the system tray icon and choose menu:System[Config].

To change to _Config Mode_ or restart _Config Mode_ from Visual Studio:

* Click menu:TwinCAT[Restart TwinCAT (Config Mode)].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/restart_config.png[]).

* A dialog pops up with the question _Restart TwinCAT System in Config Mode_.
Click btn:[OK] or press kbd:[Enter].

* A dialog pops up with the question _Load I/O Devices_.
Click btn:[Yes] or press kbd:[Enter].

* A dialog pops up with the question _Activate Free Run_.
Click btn:[Yes] or press kbd:[Enter].

To change to _Run Mode_ or restart _Run Mode_ from the system tray:

* Make sure the hardware is powered up.

* Right click the system tray icon and choose menu:System[Start/Restart].

To change to _Run Mode_ or restart _Run Mode_ from Visual Studio:

* Make sure the hardware is powered up.

* Click menu:TwinCAT[Restart TwinCAT System].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/restart_run.png[]).

* A dialog pops up with the question _Restart TwinCAT System in Run Mode_.
Click btn:[OK] or press kbd:[Enter].

In general it is recommended to switch modes via Visual Studio instead of via the system tray icon.

indexterm:[TwinCAT,generated output]
indexterm:[TwinCAT,PlcTask]
indexterm:[TwinCAT,POU]
indexterm:[TwinCAT,DUT]
indexterm:[TwinCAT,GVL]

=== Generated output

The CIF PLC code generator can generate code into an existing TwinCAT Visual Studio solution, with a TwinCAT XAE project that contains a TwinCAT Standard PLC project.
The directory that contains the solution must have the same name (except for the file extension) as the solution file (`.sln` file).
The TwinCAT XAE project (both the directory and the `.tsproj` file) in the solution should have the same name as well.
The TwinCAT XAE project should contain a TwinCAT Standard PLC project.
This project may be given any name, and this name can be configured using the _PLC project name_ option (_Generator_ category).
However, in order to be able to import I/O mappings it is highly recommended to always use the default name suggested by TwinCAT (`Untitled1`) for TwinCAT Default PLC projects.

The project should already contain a task.
This task can be given any name, and this name can be configured using the _PLC task name_ option (_Generator_ category).
By default, TwinCAT Default PLC projects have a task named `PlcTask`.
This name is the default for the _PLC task name_ option as well.
The cycle time and priority of the task are automatically updated by the PLC code generator, depending on the values provided for the options of the generator.
TwinCAT code generation does not support disabling periodic task scheduling.
The code generator also ensures that the `MAIN` program is instantiated/scheduled on the task.

All `POU` (functions, programs, etc), `DUT` (data types), and `GVL` (global variable lists) code files that are present in the TwinCAT Default PLC project are removed, from both the project and from disk, by the PLC code generator.
The newly generated code files are (over)written, and the project is updated to include and compile only the newly generated files.

The _PLC configuration name_ and _PLC resource name_ options have no effect on the TwinCAT output.

indexterm:[CIF PLC code generator,TwinCAT standard compliance]

[[tools-plcgen-twincat-standard-compliance]]
=== Standard compliance

In general, the CIF PLC code generator follows the IEC 61131-3 PLC standard and does not use vendor-specific extensions.
For the TwinCAT target however, the `STRUCT` data type declarations have no `;` character after the `STRUCT` data types, to work around a bug in the TwinCAT parser.
In that case the output is not compliant with the IEC 61131-3 standard.

indexterm:[TwinCAT,usage]

[[tools-plcgen-twincat-usage]]
=== TwinCAT usage

Follow these steps to create a solution and project in TwinCAT, generate PLC code in it, and use the PLC code to control the hardware:

* Start TwinCAT (Visual Studio) by right clicking on the TwinCAT system tray icon and choosing menu:TwinCAT XAE (VS 2010)[].

* Create a new TwinCAT XAE project:

** Click menu:File[New > Project...].

** In the _New Project_ window, _TwinCAT XAE Project (XML format)_ should already be selected.
If not, first select _TwinCAT Project_ on the left (from the list of _Installed Templates_), and then select _TwinCAT XAE Project (XML format)_.

** Choose a project name and enter it in the _Name_ box at the bottom of the dialog.

** Make sure the _Solution name_ is exactly the same, and that the _Create directory for solution_ option is enabled.

** For _Location_, select the directory in which the directory for the solution should be created.
This is usually the directory that contains the script and/or source files you will be using to generate the PLC code.

*** To figure out the directory that contains the ToolDef script, make sure that the _Properties_ view is visible in Eclipse.
Select the ToolDef script in the _Project Explorer_ tab or _Package Explorer_ tab, and look for the _Location_ property.

** Click btn:[OK] to create the project.

* Scan the available hardware:

** Make sure the hardware is powered up.

** Make sure the <<tools-plcgen-twincat-modes,Config Mode>> is enabled, by <<tools-plcgen-twincat-modes-change,switching>> to it if it is not the current mode.

** In the project, under _I/O_, right click the _Devices_ item and choose menu:Scan[].
Alternatively, select the _I/O_ item and click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/scan_devices.png[]).

** A dialog pops up with the warning _HINT: Not all types of devices can be found automatically_.
Click btn:[OK] or press kbd:[Enter].

** A dialog pops up where you have to choose the I/O device to scan.
Normally, if you have only one I/O device, it should already be selected.
Click btn:[OK] or press kbd:[Enter].

** A dialog pops up with the question _Scan for boxes_.
Click btn:[Yes] or press kbd:[Enter].

** A dialog pops up with the question _Activate Free Run_.
Click btn:[Yes] or press kbd:[Enter].

* Create a new TwinCAT PLC project:

** Right click the _PLC_ item in the project, and choose menu:Add New Item...[].

** In the _Add New Item_ dialog, _Standard PLC project_ should already be selected.

** Keep the name `Untitled1` in the _Name_ box at the bottom of the dialog.

** Also don't change the _Location_ of the project.

** Click btn:[Add] to add the PLC project.

* Save the entire solution by clicking menu:File[Save All].

* Generate PLC code.
If using a script, wait for the execution of the script to finish (the status indicated as part of the title of the console should change from `running` to `FINISHED`).

* Switch back to TwinCAT (Microsoft Visual Studio).

* When a _File Modification Detected_ window pops up for the project, click btn:[Reload] to reload the updated project that was written by the CIF tooling.

* Build the project by clicking menu:Build[Rebuild Solution].

* Load the I/O mappings:

** In the project, under _I/O_, right click _Mappings_, and choose menu:Import Mapping Infos...[].

** Select the mappings file for your hardware, and click btn:[Open].

** If the import succeeds, you should see an _Untitled1 Instance - ..._ item under the _Mappings_ item.

* Activate the configuration:

** Click menu:TwinCAT[Activate Configuration].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/activate_cfg.png[]).

** A dialog pops up with the question _Activate Configuration (Old Configurations will be overwritten!)_.
Click btn:[OK] or press kbd:[Enter].

** A dialog pops up with the question _Restart TwinCAT System in Run Mode_.
Click btn:[OK] or press kbd:[Enter].

* Start the PLC:

** Click menu:PLC[Login].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/login.png[]).

** A dialog pops up with the question _Application Port_851 does not exist on the device.
Do you want to create it and proceed with download?_.
Click btn:[Yes] or press kbd:[Enter].

** Click menu:PLC[Start].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/start.png[]).

* The PLC is now running, and you can use the system.

[[tools-plcgen-twincat-usage-stop]]
To stop the PLC:

* Click menu:PLC[Stop].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/stop.png[]).

* Click menu:PLC[Logout].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/logout.png[]).
This step is optional, and can usually be skipped.

[[tools-plcgen-twincat-usage-reset]]
To reset the PLC and start the execution from the beginning, with the same code and the same configuration:

* Make sure the hardware is powered up.

* Load the I/O mappings, if the _Untitled1 Instance - ..._ item under the _Mappings_ item is no longer present:

** In the project, under _I/O_, right click _Mappings_, and choose menu:Import Mapping Infos...[].

** Select the mappings file for your hardware, and click btn:[Open].

** If the import succeeds, you should see an _Untitled1 Instance - ..._ item under the _Mappings_ item.

* Reactivate the configuration:

** Click menu:TwinCAT[Activate Configuration].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/activate_cfg.png[]).

** A dialog pops up with the question _Activate Configuration (Old Configurations will be overwritten!)_.
Click btn:[OK] or press kbd:[Enter].

** A dialog pops up with the question _Restart TwinCAT System in Run Mode_.
Click btn:[OK] or press kbd:[Enter].

* Start the PLC:

** Click menu:PLC[Login].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/login.png[]).

** A dialog pops up with the question _Application Port_851 does not exist on the device.
Do you want to create it and proceed with download?_.
Click btn:[Yes] or press kbd:[Enter].

** Click menu:PLC[Start].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/start.png[]).

* The PLC is now running, and you can use the system.

[[tools-plcgen-twincat-usage-regen]]
Whenever you change a CIF source file, regenerate a supervisor, change a hardware mapping, etc, you need to regenerate the PLC code as well.
Follow these steps:

* Make sure the <<tools-plcgen-twincat-modes,Config Mode>> is enabled, by <<tools-plcgen-twincat-modes-change,switching>> to it if it is not the current mode.

* Save the entire solution in TwinCAT by clicking menu:File[Save All].

* Regenerate PLC code from Eclipse.
If using a script, wait for the execution of the script to finish (the status indicated as part of the title of the console should change from `running` to `FINISHED`).

* Switch back to TwinCAT (Microsoft Visual Studio).

* For all _File has been changed outside the environment.
Reload the new file?_ questions, click btn:[Yes] or press kbd:[Enter].
See the <<tools-plcgen-twincat-faq>> for instructions on how to disable some of these questions.

* When a _File Modification Detected_ window pops up for the project, click btn:[Reload] to reload the updated project that was written by the CIF tooling.

* Clean the project by clicking menu:Build[Clean Solution].

* Rebuild the project by clicking menu:Build[Rebuild Solution].

* Make sure the hardware is powered up.

* Reload the I/O mappings:

** In the project, under _I/O_, right click _Mappings_, and choose menu:Import Mapping Infos...[].

** Select the mappings file for your hardware, and click btn:[Open].

** If the import succeeds, you should see an _Untitled1 Instance - ..._ item under the _Mappings_ item.

* Activate the configuration:

** Click menu:TwinCAT[Activate Configuration].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/activate_cfg.png[]).

** A dialog pops up with the question _Activate Configuration (Old Configurations will be overwritten!)_.
Click btn:[OK] or press kbd:[Enter].

** A dialog pops up with the question _Restart TwinCAT System in Run Mode_.
Click btn:[OK] or press kbd:[Enter].

* Start the PLC:

** Click menu:PLC[Login].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/login.png[]).

** A dialog pops up with the question _Application Port_851 does not exist on the device.
Do you want to create it and proceed with download?_.
Click btn:[Yes] or press kbd:[Enter].

** Click menu:PLC[Start].
Alternatively, click the appropriate toolbar item (image:{tools-imgsdir}/plcgen/start.png[]).

* The PLC is now running, and you can use the system.

indexterm:[TwinCAT,FAQ]

[[tools-plcgen-twincat-faq]]
=== Frequently Asked Questions (FAQ)

* *Question*: Is there something that can be done about the large number of _File has been changed outside the environment..._ prompts?
+
*Answer*: Yes.
Click menu:Tools[Options...] to show the _Options_ dialog.
On the left, select menu:Environment[Documents].
Then, on the right, enable the _Detect when file is changed outside the environment_ and _Auto-load changes, if saved_ options.

* *Question*: Why doesn't importing the I/O mappings have any effect?
+
*Answer*: Make sure the TwinCAT Standard PLC project is named `Untitled1`, and try again.
Also, make sure you've built the solution before you try to import the I/O mappings.

* *Question*: I get a dialog with the warning _Device '...' needs a sync master (at least one variable linked to a task variable)_.
What should I do?
+
*Answer*: You probably forgot to load an I/O mapping.

[[tools-plcgen-twincat-faq-inlinemon]]
* *Question*: Why does opening the MAIN program take so long in Run Mode?
+
*Answer*: As the generated code becomes larger, it can take a long time for TwinCAT to set up the environment for inline monitoring of the MAIN program.
To disable inline monitoring, click menu:Tools[Options...] to show the _Options_ dialog.
On the left, select menu:TwinCAT[PLC Environment > Text Editor].
Then, on the right, switch to the _Monitoring_ tab.
Disable the _Enable inline monitoring option_.

* *Question*: TwinCAT hangs for long periods of time, before crashing and automatically being restarted by Windows.
What should I do?
+
*Answer*: If the generated code is too large, TwinCAT may not be able to handle it.
In such cases, reduce the size of the generated code, by reducing the size of the CIF model for which you are generating the code.

* *Question*: I get an error stating _Reading file failed.
[...]_.
What should I do?
+
*Answer*: The generated code is too large for TwinCAT to handle.
See also the answer to the previous question.
