<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TwinCAT 3 Archives | DMC, Inc.</title>
	<atom:link href="https://static.dmcinfo.com/blog/tag/twincat-3/feed/index.xml" rel="self" type="application/rss+xml" />
	<link></link>
	<description></description>
	<lastBuildDate>Tue, 21 Jul 2026 20:29:16 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>

<image>
	<url>https://static.dmcinfo.com/wp-content/uploads/2025/04/site-icon-150x150.png</url>
	<title>TwinCAT 3 Archives | DMC, Inc.</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Getting Started with Beckhoff TwinCAT Package Manager</title>
		<link>https://static.dmcinfo.com/blog/45335/beckhoff-twincat-package-manager-guide/</link>
		
		<dc:creator><![CDATA[Carter Silvey]]></dc:creator>
		<pubDate>Wed, 10 Jun 2026 14:45:49 +0000</pubDate>
				<category><![CDATA[Beckhoff PLC]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[Beckhoff and TwinCAT]]></category>
		<category><![CDATA[TwinCAT 3]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=45335</guid>

					<description><![CDATA[<p>Table of Contents TwinCAT Package Manager is Beckhoff’s new innovative way of managing packages within the TwinCAT environment. Released with their latest build 4026, Package Manager allows for quick and easy downloads of TwinCAT versions and workloads (collections of one or more packages), as well as individual packages. Let’s get started with some of the [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/45335/beckhoff-twincat-package-manager-guide/">Getting Started with Beckhoff TwinCAT Package Manager</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-bcadade0 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:0;margin-bottom:0;padding-top:var(--wp--preset--spacing--50);padding-right:var(--wp--preset--spacing--50);padding-bottom:var(--wp--preset--spacing--50);padding-left:var(--wp--preset--spacing--50)">
<h4 id="h-table-of-contents" class="wp-block-heading">Table of Contents</h4>



<ol class="wp-block-list">
<li><strong><a href="#twincat-installation">Installation</a></strong></li>



<li><strong><a href="#twincat-configuration">Configuration</a></strong></li>



<li><strong><a href="#twincat-workloads-and-packages">Workloads and Packages</a></strong></li>



<li><strong><a href="#conclusion">Conclusion</a></strong></li>
</ol>
</div>



<p class="wp-block-paragraph">TwinCAT Package Manager is Beckhoff’s new innovative way of managing packages within the TwinCAT environment. Released with their latest build 4026, Package Manager allows for quick and easy downloads of TwinCAT versions and workloads (collections of one or more packages), as well as individual packages. Let’s get started with some of the key features of the TwinCAT Package Manager.</p>



<h2 id="twincat-installation" class="wp-block-heading">Installation</h2>



<p class="wp-block-paragraph">Download the latest version of the TwinCAT Package Manager from the <a href="https://www.beckhoff.com/en-us/support/download-finder/search-result/?download_group=725136885" target="_blank" rel="noreferrer noopener">Beckhoff website</a>. This blog will use the full installation, which includes the UI. If you would prefer the command-line-only install, some common commands are available on <a href="https://infosys.beckhoff.com/content/1033/tc3_installation/15698626059.html?id=5147078465983576506" target="_blank" rel="noreferrer noopener">Beckhoff Infosys</a>.</p>



<figure class="wp-block-image size-full is-resized"><img fetchpriority="high" decoding="async" width="1160" height="299" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-1.png" alt="Screen displaying the TwinCAT Package Manager for version 3.1 Build 4026" class="wp-image-45362" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-1.png 1160w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-1-300x77.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-1-1024x264.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-1-768x198.png 768w" sizes="(max-width: 1160px) 100vw, 1160px" /></figure>



<p class="wp-block-paragraph">Follow the installation procedure to install TwinCAT Package Manager. &nbsp;</p>



<h2 id="twincat-configuration" class="wp-block-heading">Configuration</h2>



<p class="wp-block-paragraph">Once TwinCAT Package Manager is installed successfully, open it. If this is your first time launching Package Manager, you should be greeted with the Introduction screen. If you have previously launched Package Manager, but want to follow along, you can access this screen with the Settings button (gear icon) in the bottom left.</p>



<h3 id="h-introduction" class="wp-block-heading">Introduction</h3>



<p class="wp-block-paragraph">If you’re installing Package Manager on a system with a previous build of TwinCAT already installed, there will be a migration tab instead of a location tab. We will deal with that in a later section. Click Next.</p>



<figure class="wp-block-image size-full is-resized has-custom-border"><img decoding="async" width="1428" height="773" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-2.png" alt="Window displaying the TwinCAT Package Manager setup wizard, used to install, update, and manage Beckhoff software components." class="wp-image-45363" style="border-top-left-radius:0px;border-top-right-radius:0px;border-bottom-left-radius:0px;border-bottom-right-radius:0px;aspect-ratio:1.8473528492050129;object-fit:cover;width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-2.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-2-300x162.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-2-1024x554.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-2-768x416.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<h3 id="h-feeds" class="wp-block-heading">Feeds</h3>



<p class="wp-block-paragraph">The next section is for configuring the feeds for Package Manager. Click the &#8220;Add new feed&#8221; button to add one of these feeds.</p>



<figure class="wp-block-image size-full is-resized has-custom-border"><img decoding="async" width="1428" height="773" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-3.png" alt="Image showing the TwinCAT Package Manager setup wizard, a tool used to manage software packages for Beckhoff automation systems." class="wp-image-45364" style="border-top-left-radius:0px;border-top-right-radius:0px;border-bottom-left-radius:0px;border-bottom-right-radius:0px;aspect-ratio:1.8473528492050129;object-fit:cover;width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-3.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-3-300x162.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-3-1024x554.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-3-768x416.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<figure class="wp-block-image size-full is-resized has-custom-border"><img decoding="async" width="856" height="593" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-4.png" alt="Beckhoff TwinCAT Package Manager dialog window used to add new software feeds for installation." class="wp-image-45365" style="border-top-left-radius:0px;border-top-right-radius:0px;border-bottom-left-radius:0px;border-bottom-right-radius:0px;aspect-ratio:1.4435149171030617;object-fit:cover;width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-4.png 856w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-4-300x208.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-4-768x532.png 768w" sizes="(max-width: 856px) 100vw, 856px" /></figure>



<p class="wp-block-paragraph">By default, Beckhoff provides three feeds: the stable feed, the outdated feed, and the testing feed. The stable feed contains officially released Beckhoff products and is typically the main feed for most workloads and packages. Select the URL that ends with “/stable” to add the stable feed. The feed name should auto-populate, but can be changed. Enter your valid myBeckhoff account credentials and click Save to add the feed. You can <a href="https://www.beckhoff.com/en-en/mybeckhoff-registration/index.aspx" type="link" id="https://www.beckhoff.com/en-en/mybeckhoff-registration/index.aspx" target="_blank" rel="noreferrer noopener">create your own myBeckhoff account</a> if you don’t already one.</p>



<p class="wp-block-paragraph">You’re also able to create your own feed, which you can access here. This would allow you to easily share custom libraries with other developers on your team. We won’t go in depth on how to do that in this blog, but the <a href="https://github.com/Beckhoff-USA-Community/AAG_Custom-TcPkg-And-Workload" target="_blank" rel="noreferrer noopener">Beckhoff community GitHub repo</a> has an example structure.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="856" height="593" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-5.png" alt="TwinCAT Package Manager interface used for configuring software feeds." class="wp-image-45366" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-5.png 856w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-5-300x208.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-5-768x532.png 768w" sizes="(max-width: 856px) 100vw, 856px" /></figure>



<p class="wp-block-paragraph">You should now see the feed added. You’re able to disable, edit, or delete the feed from this view if needed.</p>



<p class="wp-block-paragraph">The outdated feed contains previous TwinCAT builds. If you used TwinCAT prior to build 4026, this is essentially the new version of Remote Manager. The testing feed contains test versions of workloads and packages. It’s most commonly used if you need access to an unreleased feature or are testing packages with Beckhoff engineers.</p>



<p class="wp-block-paragraph">Follow the steps above for the stable feed to add the outdated and testing feeds, making sure to use their respective URLs.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1150" height="679" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-6.png" alt="TwinCAT Package Manager interface used to configure software repositories for Beckhoff products." class="wp-image-45367" style="aspect-ratio:1.6925843647519305;width:1000px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-6.png 1150w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-6-300x177.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-6-1024x605.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-6-768x453.png 768w" sizes="(max-width: 1150px) 100vw, 1150px" /></figure>



<p class="wp-block-paragraph">Once you add the outdated and testing feeds, your Feeds tab should look like the one above. You can reorder the feed priorities using the up and down arrows on the right side. It’s recommended to keep the stable feed as priority 1 since it contains the officially released packages. If you reordered the feeds, click the save button in the top right. If you click next with unsaved changes, you will get this warning.</p>



<figure class="wp-block-image size-full has-custom-border"><img decoding="async" width="760" height="190" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-7.png" alt="Screenshot of a browser alert dialog box informing you that there are unsaved changes to your feed options." class="has-border-color has-custom-black-border-color wp-image-45368" style="border-width:1px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-7.png 760w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-7-300x75.png 300w" sizes="(max-width: 760px) 100vw, 760px" /></figure>



<p class="wp-block-paragraph">If you see this warning, click “Yes” to save changes. Click “Next.”</p>



<h3 class="wp-block-heading">Integration</h3>



<p class="wp-block-paragraph">The next screen asks which versions of TwinCAT XAE to install. Since TwinCAT XAE is built on Visual Studio, it requires the same Visual Studio version (32-bit or 64-bit) to be installed. If you’re working on a project in build 4026 or newer, it’s recommended to use the 64-bit version when possible. If you’re working on a project in a build prior to 4026 or on a 32-bit computer system, the 32-bit version of TwinCAT XAE is the only option. You can always add or remove these XAE versions later, so for now, let’s install both. Click &#8220;Next.&#8221;</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1150" height="679" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-8.png" alt="TwinCAT Package Manager facilitates the integration of TwinCAT Engineering into Visual Studio or a standalone TcXaeShell." class="wp-image-45369" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-8.png 1150w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-8-300x177.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-8-1024x605.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-8-768x453.png 768w" sizes="(max-width: 1150px) 100vw, 1150px" /></figure>



<h3 class="wp-block-heading">Migration</h3>



<p class="wp-block-paragraph">If you had a previous build of TwinCAT, you will be prompted to complete a Migration screen. If you did not have a previous build of TwinCAT, feel free to skip to the <a href="#location">Location </a>section.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="920" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-9.png" alt="TwinCAT Package Manager is prompting you to migrate your current TwinCAT installation to Build 4026." class="wp-image-45370" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-9.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-9-300x193.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-9-1024x660.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-9-768x495.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">The migration tool will attempt to capture existing user settings on previous versions of TwinCAT, uninstall previous versions, install the latest versions, and reapply the user settings. Let’s click &#8220;Start Migration&#8221; to get started.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="920" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-10.png" alt="Screenshot of a prompt from the TwinCAT Package Manager asking to install the TwinCAT.XAE.MigrateCli package." class="wp-image-45373" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-10.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-10-300x193.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-10-1024x660.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-10-768x495.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">When getting to step 2 of the preparation screen, you may see a notification that you need to install the MigrateCli package. Click &#8220;Yes&#8221; to continue.</p>



<figure class="wp-block-image size-large is-resized"><img decoding="async" width="1024" height="637" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-11-1024x637.png" alt="Screenshot of TwinCAT Package Manager by Beckhoff Automation, currently displaying the Migration tab." class="wp-image-45375" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-11-1024x637.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-11-300x187.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-11-768x478.png 768w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-11.png 1478w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Once the migration tool is installed, click &#8220;Start Simulation.&#8221;</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1511" height="920" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-12.png" alt="Screen displaying the TwinCAT Package Manager migration tool from Beckhoff, which lists specific software workloads to be upgraded." class="wp-image-45376" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-12.png 1511w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-12-300x183.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-12-1024x623.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-12-768x468.png 768w" sizes="(max-width: 1511px) 100vw, 1511px" /></figure>



<p class="wp-block-paragraph">Once the migration simulation runs, you should see a list of all existing products in the system and how TwinCAT Package Manager plans to upgrade them to packages and workloads.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1511" height="920" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-13.png" alt="Screenshot of Beckhoff TwinCAT Package Manager software, specifically the migration screen for upgrading existing automation systems." class="wp-image-45377" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-13.png 1511w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-13-300x183.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-13-1024x623.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-13-768x468.png 768w" sizes="(max-width: 1511px) 100vw, 1511px" /></figure>



<p class="wp-block-paragraph">Assuming all the products can be upgraded to packages and workloads, we are ready to start the migration. Click Start Migration.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1548" height="920" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-14.png" alt="Image showing a &quot;Reboot required&quot; dialog box from the Beckhoff TwinCAT Package Manager." class="wp-image-45378" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-14.png 1548w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-14-300x178.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-14-1024x609.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-14-768x456.png 768w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-14-1536x913.png 1536w" sizes="(max-width: 1548px) 100vw, 1548px" /></figure>



<p class="wp-block-paragraph">Depending on the products you have installed, you may need to reboot your system. Press Ok and the TwinCAT Package Manager should automatically start up after rebooting and continue the migration.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1548" height="920" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-15.png" alt="Screen displaying the Beckhoff TwinCAT Package Manager migrating a system by uninstalling old setups and installing new workloads." class="wp-image-45379" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-15.png 1548w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-15-300x178.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-15-1024x609.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-15-768x456.png 768w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-15-1536x913.png 1536w" sizes="(max-width: 1548px) 100vw, 1548px" /></figure>



<p class="wp-block-paragraph">Once the migration is complete, click Finish. You should see all the latest versions of the products you had previously installed on the system.</p>



<h3 id="location" class="wp-block-heading">Location</h3>



<p class="wp-block-paragraph">If you did not have a previous version of TwinCAT installed, the final screen asks where to install TwinCAT. The default location is fine unless you have a reason to install it elsewhere. Click Finish.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1150" height="679" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-16.png" alt="Image of a screen that is part of the TwinCAT Package Manager installation wizard for Beckhoff software." class="wp-image-45380" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-16.png 1150w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-16-300x177.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-16-1024x605.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-16-768x453.png 768w" sizes="(max-width: 1150px) 100vw, 1150px" /></figure>



<h2 id="twincat-workloads-and-packages" class="wp-block-heading">Workloads and Packages</h2>



<p class="wp-block-paragraph">The workload view should be the default view when opening Package Manager for the first time. It can be navigated to by hovering over the package icon with a W in the bottom right and selecting workloads.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="773" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-17.png" alt="Image of a screen showing the TwinCAT Package Manager interface for managing software packages and workloads." class="wp-image-45381" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-17.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-17-300x162.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-17-1024x554.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-17-768x416.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<h3 class="wp-block-heading">Workloads</h3>



<p class="wp-block-paragraph">Workloads are groupings of packages that closely align with Beckhoff&#8217;s licensing structure. For example, if you’re planning on using Beckhoff XTS in your solution, you can search for “XTS” to find the TF5850 | TwinCAT 3 XTS workload. This will install the necessary packages to work with XTS. If you are using XTS in your solution, check out our <a href="https://static.dmcinfo.com/blog/15666/beckhoff-xts-part-1-downloads-and-starter-project/">blog series on XTS</a> to help get started!</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="773" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-18.png" alt="Image shows the Beckhoff TwinCAT Package Manager, which is used for installing, updating, and managing modular TwinCAT 3 software packages." class="wp-image-45382" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-18.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-18-300x162.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-18-1024x554.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-18-768x416.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">The workloads in the general section are the ones we should install first. Let’s start by installing the latest version of TwinCAT Standard Engineering and the latest versions of TwinCAT XAE Shell 32-bit and 64-bit. If you’re installing the latest version, simply click on the blue download button associated with that workload.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="773" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-19.png" alt="Screenshot of TwinCAT Package Manager." class="wp-image-45383" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-19.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-19-300x162.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-19-1024x554.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-19-768x416.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">You’ll see the planned installations added to the right side of Package Manager under selected products. Click Apply Modifications to start the installation.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="856" height="593" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-20.png" alt="Image showing an installation wizard for TwinCAT 3.1, indicating a required update for version 3.16.3 of the TwinCAT.XAR.Base component." class="wp-image-45384" style="width:800px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-20.png 856w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-20-300x208.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-20-768x532.png 768w" sizes="(max-width: 856px) 100vw, 856px" /></figure>



<p class="wp-block-paragraph">Some workloads will require a restart. The TwinCAT Standard installation is one of them. Click Accept to continue.</p>



<p class="wp-block-paragraph">If a pop-up appears asking you to allow the TwinCAT Package Manager to make changes to your device, click “Yes.”</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="856" height="592" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-21.png" alt="Image showing a Beckhoff TwinCAT installer interface managing multiple software packages." class="wp-image-45385" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-21.png 856w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-21-300x207.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-21-768x531.png 768w" sizes="(max-width: 856px) 100vw, 856px" /></figure>



<p class="wp-block-paragraph">The installation may take a few minutes, but Package Manager will give you a download and installation status.</p>



<p class="wp-block-paragraph">Once the installation completes, Package Manager will show a check mark next to the workloads that were successfully installed.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="822" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-22.png" alt="Screenshot of TwinCAT Package Manager." class="wp-image-45386" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-22.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-22-300x173.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-22-1024x589.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-22-768x442.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">We didn’t explicitly install TwinCAT Standard Remote Manager or TE9000 | TwinCAT 3 Safety Editor. Why are they showing as installed? TwinCAT Package Manager will install all dependencies needed to install the selected workloads! These workloads are dependencies for TwinCAT Standard and are automatically installed for us.</p>



<h3 class="wp-block-heading">Workloads (Other Versions)</h3>



<p class="wp-block-paragraph">One of the nice things about TwinCAT Package Managers is the ability to access prior versions of all the workloads. Each workload has an ellipsis on the right side. Clicking on this provides the option to select other versions.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="775" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-23.png" alt="Screenshot of a menu in TwinCAT Package manager allowing users to browse, install, and update different workloads and packages, such as the TwinCAT Standard engineering and runtime environments" class="wp-image-45387" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-23.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-23-300x163.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-23-1024x556.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-23-768x417.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">Click on the other versions option for TwinCAT Standard.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="775" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-24.png" alt="Screenshot of TwinCAT Package Manager with TwinCAT Standard selected." class="wp-image-45388" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-24.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-24-300x163.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-24-1024x556.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-24-768x417.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">We can see that the latest version is currently installed and can be uninstalled here if needed. If we wanted to install a previous version, say 4026.21.2, we could click the icon next to that version. That icon is the downgrade icon. This would uninstall 4026.22.0 and downgrade TwinCAT Standard to 4026.21.2. &nbsp;However, TwinCAT Standard Remote Manager can be used when working on multiple solutions across different versions.</p>



<p class="wp-block-paragraph">Click the triple-dot icon next to TwinCAT Standard Remote Manager, then select other versions.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="775" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-25.png" alt="Screenshot of TwinCAT Package Manager with TwinCAT Standard Remote Manager selected." class="wp-image-45389" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-25.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-25-300x163.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-25-1024x556.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-25-768x417.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">The icons here are install icons instead of downgrade icons, even though we already have the latest version installed. This is because the TwinCAT Standard Remote Manager supports multiple versions, as indicated by the AllowMultiple attribute in the top left. Installing from here will allow both versions to coexist on the same system. To illustrate this, I’ll install version 4026.21.2.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="937" height="86" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-26.png" alt="Image of TwinCAT Standard Remote Manager, allowing users to manage and switch between multiple versions of the TwinCAT 3 development environment (Engineering) on a single PC." class="wp-image-45390" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-26.png 937w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-26-300x28.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-26-768x70.png 768w" sizes="(max-width: 937px) 100vw, 937px" /></figure>



<p class="wp-block-paragraph">The Package Manager workload for TwinCAT Standard Remote Manager now shows a [ + 1 ] to indicate multiple builds are installed.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="175" height="80" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-27.png" alt="Image of a dropdown menu in TwinCAT Package Manager allowing users to select between different versions of TwinCAT software, specifically Build 4026.22 and Build 4026.21." class="wp-image-45391"/></figure>



<p class="wp-block-paragraph">When opening TwinCAT XAE, we now have multiple builds to select from!</p>



<h3 class="wp-block-heading">Installing Pre-4026 Builds</h3>



<p class="wp-block-paragraph">If you haven’t already, make sure you’re connected to the Beckhoff outdated feed. You can configure your feeds by clicking on the settings icon in the bottom left.</p>



<p class="wp-block-paragraph">Once you have the outdated feed configured, hover over the package icon with the database in the bottom right. Select the &#8220;Beckhoff Outdated Feed.&#8221;</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="775" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-28.png" alt="Screenshot of an interface allowing users to select from different feeds, including Stable, Testing, and Outdated feeds, to install, upgrade, or downgrade products." class="wp-image-45392" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-28.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-28-300x163.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-28-1024x556.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-28-768x417.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">The only workload associated with the Beckhoff Outdated Feed is the TwinCAT Standard Remote Manager. From the outdated feed, we can install pre-4026 builds of TwinCAT.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="872" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-29.png" alt="Screenshot of an interface showing TwinCAT Standard Remote Manager with multiple versions available for installation, upgrading, or downgrading." class="wp-image-45393" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-29.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-29-300x183.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-29-1024x625.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-29-768x469.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">I’ll install build 4024.75.4 to illustrate.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="176" height="98" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-30.png" alt="Screenshot of a dropdown menu part of the TwinCAT XAE Remote Manager Toolbar, which allows users to select specific TwinCAT 3 versions for loading" class="wp-image-45394"/></figure>



<p class="wp-block-paragraph">After installing build 4024.75.4 on TwinCAT Package Manager, it is now selectable in the build dropdown.</p>



<p class="has-custom-primary-blue-color has-custom-light-blue-background-color has-text-color has-background has-link-color wp-elements-2 wp-block-paragraph" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:var(--wp--preset--spacing--30)"><strong>*NOTE: This is only available in the 32-bit XAE. The 64-bit version of XAE only supports builds 4026 and newer.</strong></p>



<h3 class="wp-block-heading">Packages</h3>



<p class="wp-block-paragraph">So far, we’ve been dealing with Workloads. Workloads are groupings of packages that TwinCAT organizes primarily according to Beckhoff&#8217;s licensing structure. TwinCAT projects reference packages directly. Let’s open a new TwinCAT XAE project to see this.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="143" height="76" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-31.png" alt="Image shows the References section in a Beckhoff TwinCAT 3 engineering environment." class="wp-image-45395"/></figure>



<p class="wp-block-paragraph">In the References folder of a brand new TwinCAT project, there are the Tc2_Standard, Tc2_System, and Tc3_Module packages.</p>



<p class="wp-block-paragraph">Let’s switch back to the package manager. On the left, you should be able to go to the package view menu and select Packages.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="872" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-32.png" alt="Screenshot showing a list of various Packages with different version numbers (e.g., v4.2.0, v22.22.0) available for installation or update." class="wp-image-45396" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-32.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-32-300x183.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-32-1024x625.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-32-768x469.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">This will show the individual packages that are available and installed on the system. Let’s search for Tc2_Standard.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="872" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-33.png" alt="Screenshot of TwinCAT Package Manager interface showing &quot;Selected Products&quot; panel on the right displaying actions like Install, Upgrade, or Remove for the packages chosen from the main list." class="wp-image-45397" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-33.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-33-300x183.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-33-1024x625.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-33-768x469.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">We can see that Tc2_Standard is installed.</p>



<h3 class="wp-block-heading">How To Deal with a Missing Package</h3>



<p class="wp-block-paragraph">If you have a missing package on a TwinCAT project, you will be greeted with a warning sign that looks something like this:</p>



<figure class="wp-block-image size-full"><img decoding="async" width="145" height="73" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-34.png" alt="Screenshot of a file tree in TwinCAT Package Manager with yellow alert symbols next to folder items." class="wp-image-45398"/></figure>



<p class="wp-block-paragraph">The package with the warning symbol next to it is missing from the project. Double-clicking on the package shows that the library is not available and does not have an effective version listed.</p>



<figure class="wp-block-image size-full is-resized has-custom-border"><img decoding="async" width="635" height="101" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-35-1.png" alt="Image showing a library manager view within TwinCAT 3." class="wp-image-45400" style="border-width:1px;width:700px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-35-1.png 635w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-35-1-300x48.png 300w" sizes="(max-width: 635px) 100vw, 635px" /></figure>



<p class="wp-block-paragraph">Right-click on the missing package and open the properties window. The resolution will show the version of the package that the TwinCAT PLC project is expecting.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="601" height="301" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-36.png" alt="Image displaying the Properties window for a Beckhoff Automation GmbH library, identified as Tc2_System and a resolution version of 3.9.1.0." class="wp-image-45401" style="width:700px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-36.png 601w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-36-300x150.png 300w" sizes="(max-width: 601px) 100vw, 601px" /></figure>



<p class="wp-block-paragraph">If we go back to Package Manager and search for the Tc2_System package, we can see that although it is installed, it is not the same version the PLC project expects.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="962" height="41" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-37.png" alt="Image of a library item for Beckhoff Automation's TwinCAT 3 software suite." class="wp-image-45402" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-37.png 962w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-37-300x13.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-37-768x33.png 768w" sizes="(max-width: 962px) 100vw, 962px" /></figure>



<p class="wp-block-paragraph">Click the ellipses next to the package, then select other versions.</p>



<p class="wp-block-paragraph">Similar to Workloads, Packages have multiple versions that can be installed onto the same system. In this scenario, we have Tc2_System v3.10.1 installed already, but do not have v3.9.1. Tc2_System allows for multiple versions to be installed, indicated by the AllowMultiple tag. Let’s install v3.9.1 and see if that resolves our issue. Click the download button next to v3.9.1 and click &#8220;Apply modifications.&#8221;</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1428" height="872" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-38.png" alt="TwinCAT 3 interface displaying multiple versions." class="wp-image-45403" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-38.png 1428w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-38-300x183.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-38-1024x625.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-38-768x469.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></figure>



<p class="wp-block-paragraph">If you see a message about “TwinCAT XAE / Visual Studio stop required,” be sure to close all open XAE windows before clicking Accept. Once the package is installed successfully, we can check the previously missing package.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="856" height="672" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-39.png" alt="Screenshot of an installer window indicating that the TwinCAT XAE / Visual Studio application must be stopped before the installation can continue." class="wp-image-45404" style="width:1000px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-39.png 856w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-39-300x236.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-39-768x603.png 768w" sizes="(max-width: 856px) 100vw, 856px" /></figure>



<p class="wp-block-paragraph">The library is now available and has an effective version of v3.9.1. We have installed our missing package through Package Manager!</p>



<figure class="wp-block-image size-full is-resized has-custom-border"><img decoding="async" width="643" height="97" src="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-40-1.png" alt="Image displaying a list of libraries within the Beckhoff TwinCAT 3 engineering environment, specifically showing library names, namespaces, and effective versions." class="has-border-color has-custom-black-border-color wp-image-45406" style="border-width:1px;width:700px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-40-1.png 643w, https://static.dmcinfo.com/wp-content/uploads/2026/06/twincat-package-manager-40-1-300x45.png 300w" sizes="(max-width: 643px) 100vw, 643px" /></figure>



<h2 id="conclusion" class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph" style="padding-bottom:var(--wp--preset--spacing--50)">The TwinCAT Package Manager is a huge improvement in how engineers can manage the various Packages and Workloads that make up a TwinCAT solution. TwinCAT Package Manager is just the start of the improvements that TwinCAT build 4026 brings to development. A complete list of changes is offered on the <a href="https://www.beckhoff.com/en-us/products/automation/twincat/twincat-3-build-4026/" target="_blank" rel="noreferrer noopener">Beckhoff website</a>. If you’re starting a project in 4026 or upgrading an existing solution to 4026, reach out to DMC and see how we can help! We have extensive experience with upgrading and developing across all TwinCAT builds.</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step">Starting a TwintCAT 3 project or upgrading an existing system?</h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">DMC&#8217;s <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/">Automation</a> team can help you migrate environments, manage dependencies, and streamline <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/plc-programming/beckhoff-and-twincat-3-programming/">Beckhoff TwinCAT development</a>. Contact DMC to get started.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/45335/beckhoff-twincat-package-manager-guide/">Getting Started with Beckhoff TwinCAT Package Manager</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Link Hardware / IO in Beckhoff TwinCAT 3</title>
		<link>https://static.dmcinfo.com/blog/18463/how-to-link-hardware-io-in-beckhoff-twincat-3/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Tue, 07 Jun 2022 20:41:10 +0000</pubDate>
				<category><![CDATA[Beckhoff PLC]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[PLC]]></category>
		<category><![CDATA[Beckhoff]]></category>
		<category><![CDATA[TwinCAT 3]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/18463/how-to-link-hardware-io-in-beckhoff-twincat-3/</guid>

					<description><![CDATA[<p>One of the most essential tasks on any PLC platform is linking software variables to physical hardware inputs and outputs. Without the ability to do this, our software would&#160;be meaningless code executing on a processor, unable to affect&#160;the physical realm. As a mechanical engineer, I like to move things, so this is no good.&#160; Beckhoff [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/18463/how-to-link-hardware-io-in-beckhoff-twincat-3/">How to Link Hardware / IO in Beckhoff TwinCAT 3</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">One of the most essential tasks on any PLC platform is linking software variables to physical hardware inputs and outputs. Without the ability to do this, our software would&nbsp;be meaningless code executing on a processor, unable to affect&nbsp;the physical realm. As a mechanical engineer, I like to move things, so this is no good.&nbsp;</p>



<p class="wp-block-paragraph">Beckhoff TwinCAT 3 gives us a couple of options for&nbsp;performing this task. This blog will introduce both methods&nbsp;and, at the end, discuss some pros and cons of each method. I’ve also included basics on linking motion hardware —&nbsp;if you’re only interested in linking standard inputs/outputs, feel free to skip the “Motion” sections.</p>



<h2 id="h-table-of-contents" class="wp-block-heading">Table of Contents</h2>



<ol class="wp-block-list">
<li><a href="#h-hardware-linking-basics">Hardware Linking Basics</a>
<ul class="wp-block-list">
<li><a href="#h-motion">Motion</a></li>
</ul>
</li>



<li><a href="#h-method-1-manual-linking">Method 1: Manual Linking</a>
<ul class="wp-block-list">
<li><a href="#h-motion-0">Motion</a></li>
</ul>
</li>



<li><a href="#h-method-2-attribute-linking">Method 2: Attribute Linking</a>
<ul class="wp-block-list">
<li><a href="#h-single-variables">Single Variables</a></li>



<li><a href="#h-nested-variables">Nested Variables</a></li>



<li><a href="#h-mismatched-variables-size-types">Mismatched variable sizes/types</a></li>



<li><a href="#h-motion-1">Motion</a></li>
</ul>
</li>



<li><a href="#h-comparisons">Comparisons</a></li>



<li><a href="#h-project-variants">Project Variants</a></li>



<li><a href="#h-further-reference">Further Reference</a></li>
</ol>



<h2 id="h-hardware-linking-basics" class="wp-block-heading">Hardware Linking Basics</h2>



<p class="wp-block-paragraph"><a href="#h-table-of-contents">Back to Table of Contents</a></p>



<p class="wp-block-paragraph">Before we get into the two hardware linking methods, let’s discuss some basics that we’ll need for either method.&nbsp;</p>



<p class="wp-block-paragraph">In order to link a variable to hardware, we need to declare that variable as an input or output. A variable can be declared as an input by placing&nbsp;<strong><code>AT%I*</code></strong>&nbsp;before the type. Likewise, an output is declared by placing&nbsp;<strong><code>AT%Q*</code></strong>&nbsp;before the type.&nbsp;</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>VAR
    boolInput1  AT %I* : BOOL;
    boolOutput1 AT %Q* : BOOL;

    intInput1   AT %I* : INT;
    intOutput1  AT %Q* : INT;
END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"><span style="color: #D4D4D4">    boolInput1  AT %I* : BOOL;</span></span>
<span class="line"><span style="color: #D4D4D4">    boolOutput1 AT %Q* : BOOL;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    intInput1   AT %I* : INT;</span></span>
<span class="line"><span style="color: #D4D4D4">    intOutput1  AT %Q* : INT;</span></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<p class="wp-block-paragraph">We can declare IO of any type, including structures and function blocks. If we declare a structure or function block as IO, all memory within that item will be included as IO —&nbsp;so this probably makes more sense for structures than it does for function blocks. Also, all variables within that structure will either be an input or an output —&nbsp;both cannot&nbsp;be included when declaring this way.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// Type definition
TYPE ST_Inputs :
STRUCT
    boolInput : BOOL;
    intInput  : INT;
END_STRUCT
END_TYPE


// Declaration
VAR
    structAsInput AT %I* : ST_Inputs;
END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">// Type definition</span></span>
<span class="line"><span style="color: #D4D4D4">TYPE ST_Inputs :</span></span>
<span class="line"><span style="color: #D4D4D4">STRUCT</span></span>
<span class="line"><span style="color: #D4D4D4">    boolInput : BOOL;</span></span>
<span class="line"><span style="color: #D4D4D4">    intInput  : INT;</span></span>
<span class="line"><span style="color: #D4D4D4">END_STRUCT</span></span>
<span class="line"><span style="color: #D4D4D4">END_TYPE</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">// Declaration</span></span>
<span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"><span style="color: #D4D4D4">    structAsInput AT %I* : ST_Inputs;</span></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<p class="wp-block-paragraph">We can also declare IO within structures/function blocks, which allows us to include both inputs and outputs, as well as variables that are neither inputs nor outputs.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// Type definition
TYPE ST_IncludingIO :
STRUCT
    boolInput  AT %I* : BOOL;
    boolOutput AT %Q* : BOOL;

    intInput   AT %I* : INT;
    intOutput  AT %Q* : INT;

    notIOBool  : BOOL;
    notIOInt   : INT;
    notIOReal  : REAL;
END_STRUCT
END_TYPE


// Declaration
VAR
    structWithIO : ST_IncludingIO;
END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">// Type definition</span></span>
<span class="line"><span style="color: #D4D4D4">TYPE ST_IncludingIO :</span></span>
<span class="line"><span style="color: #D4D4D4">STRUCT</span></span>
<span class="line"><span style="color: #D4D4D4">    boolInput  AT %I* : BOOL;</span></span>
<span class="line"><span style="color: #D4D4D4">    boolOutput AT %Q* : BOOL;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    intInput   AT %I* : INT;</span></span>
<span class="line"><span style="color: #D4D4D4">    intOutput  AT %Q* : INT;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    notIOBool  : BOOL;</span></span>
<span class="line"><span style="color: #D4D4D4">    notIOInt   : INT;</span></span>
<span class="line"><span style="color: #D4D4D4">    notIOReal  : REAL;</span></span>
<span class="line"><span style="color: #D4D4D4">END_STRUCT</span></span>
<span class="line"><span style="color: #D4D4D4">END_TYPE</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">// Declaration</span></span>
<span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"><span style="color: #D4D4D4">    structWithIO : ST_IncludingIO;</span></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<p class="wp-block-paragraph">Inputs/outputs can be declared like this pretty much anywhere in the program, with a few exceptions: methods and functions. This gives us the flexibility to architect our program however we like. For example, we could put all of the IO in a GVL for the convenience of having it all in once place, or we could nest our IO within the function block structure of our software for good organization.</p>



<p class="wp-block-paragraph">Once the program is compiled, all the IO variables that have been declared will appear under the PLC instance inputs and outputs. In this example, all our IO variables are declared in the&nbsp;<code><strong>VAR</strong></code>&nbsp;memory of the&nbsp;<code><strong>MAIN</strong></code>&nbsp;program, which is indicated in the path of each IO variable.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="410" height="585" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/DeclaredIO.png" alt="DeclaredIO" class="wp-image-18439" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/DeclaredIO.png 410w, https://static.dmcinfo.com/wp-content/uploads/2025/05/DeclaredIO-210x300.png 210w" sizes="(max-width: 410px) 100vw, 410px" /></figure>



<p class="wp-block-paragraph">Once our IO variables are declared and the project is compiled, we are ready to start linking standard IO.</p>



<h2 id="h-motion" class="wp-block-heading">Motion</h2>



<p class="wp-block-paragraph"><a href="#h-table-of-contents">Back to Table of Contents</a></p>



<p class="wp-block-paragraph">Basic motion axis linking is a little different than standard IO.&nbsp;</p>



<p class="wp-block-paragraph">Standard IO variables can still be directly linked to PDOs to/from drive hardware, which is often done for more advanced motion&nbsp;functionality or certain functionality with third-party (i.e., non-Beckhoff) drives; however, most NC axis control is done through the NC task, a separate task on the Beckhoff PLC used specifically for motion control. Basically, the PLC communicates with the NC task, and the NC task directly communicates with the drive hardware. The NC task takes care of low-level motion control functionality, so we can abstract out to high-level, simple, PLCopen-style control within the PLC program.</p>



<p class="wp-block-paragraph">This means we need to link the PLC task to the NC task. Everything we need for this is included in the&nbsp;<a href="https://infosys.beckhoff.com/content/1033/tcplclib_tc2_mc2/70132363.html?id=467387231256035047" target="_blank" rel="noreferrer noopener"><code><strong>AXIS_REF</strong></code>&nbsp;type</a>&nbsp;from Beckhoff’s&nbsp;<a href="https://infosys.beckhoff.com/content/1033/tcplclib_tc2_mc2/index.html?id=4786081293094367280" target="_blank" rel="noreferrer noopener"><code><strong>Tc2_MC2</strong></code>&nbsp;library</a>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>VAR
    axis1 : AXIS_REF;
END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"><span style="color: #D4D4D4">    axis1 : AXIS_REF;</span></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<figure class="wp-block-image size-full"><img decoding="async" width="275" height="252" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/DeclaredAxis.png" alt="DeclaredAxis" class="wp-image-18440"/></figure>



<p class="wp-block-paragraph">We’ll talk about how to link this&nbsp;<code><strong>AXIS_REF</strong></code>&nbsp;structure in the linking methods sections later, but one more thing must be done, regardless of which linking method is used. As mentioned previously, the NC task&nbsp;needs to be directly linked to the hardware. To do this, we’ll first need to create the NC task and axis. This may have been done already if an axis had been added to the hardware configuration previously.&nbsp;If it hasn’t, use the following steps:</p>



<ol class="wp-block-list">
<li><strong>[Solution] &gt; MOTION &gt; Right Click &gt; Add New Item…</strong></li>



<li>Select&nbsp;<strong>NC/PTP NCI Configuration</strong>&nbsp;and click&nbsp;<strong>Ok.</strong></li>



<li><strong>[Solution] &gt; MOTION &gt; [NC Task] &gt; Axes &gt; Right Click &gt; Add New Item…</strong></li>



<li>Enter the Axis name and click&nbsp;<strong>Ok</strong>.</li>
</ol>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img decoding="async" width="478" height="198" data-id="18441" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/CreateNCTask.png" alt="CreateNCTask" class="wp-image-18441" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/CreateNCTask.png 478w, https://static.dmcinfo.com/wp-content/uploads/2025/05/CreateNCTask-300x124.png 300w" sizes="(max-width: 478px) 100vw, 478px" /></figure>



<figure class="wp-block-image size-large"><img decoding="async" width="471" height="180" data-id="18442" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/CreateNCTaskPopup.png" alt="CreateNCTaskPopup" class="wp-image-18442" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/CreateNCTaskPopup.png 471w, https://static.dmcinfo.com/wp-content/uploads/2025/05/CreateNCTaskPopup-300x115.png 300w" sizes="(max-width: 471px) 100vw, 471px" /></figure>
</figure>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-full"><img decoding="async" width="478" height="332" data-id="18443" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/CreateAxis.png" alt="CreateAxis" class="wp-image-18443" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/CreateAxis.png 478w, https://static.dmcinfo.com/wp-content/uploads/2025/05/CreateAxis-300x208.png 300w" sizes="(max-width: 478px) 100vw, 478px" /></figure>



<figure class="wp-block-image size-full"><img decoding="async" width="460" height="237" data-id="18444" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/CreateAxisPopup.png" alt="CreateAxisPopup" class="wp-image-18444" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/CreateAxisPopup.png 460w, https://static.dmcinfo.com/wp-content/uploads/2025/05/CreateAxisPopup-300x155.png 300w" sizes="(max-width: 460px) 100vw, 460px" /></figure>
</figure>



<p class="wp-block-paragraph">Once the NC task/axis has been created, click on the axis and go to the&nbsp;<strong>Settings</strong>&nbsp;tab. The&nbsp;<strong>Link To I/O</strong>&nbsp;button will allow us to link the axis item in the NC task to an actual drive in the hardware configuration. Click on this button and select the desired hardware to link the NC axis to that hardware.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="885" height="284" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkNcAxis.png" alt="LinkNcAxis" class="wp-image-18445" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkNcAxis.png 885w, https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkNcAxis-300x96.png 300w, https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkNcAxis-768x246.png 768w" sizes="(max-width: 885px) 100vw, 885px" /></figure>



<figure class="wp-block-image size-full"><img decoding="async" width="659" height="344" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/SelectHardwareAxis.png" alt="SelectHardwareAxis" class="wp-image-18446" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/SelectHardwareAxis.png 659w, https://static.dmcinfo.com/wp-content/uploads/2025/05/SelectHardwareAxis-300x157.png 300w" sizes="(max-width: 659px) 100vw, 659px" /></figure>



<p class="wp-block-paragraph">The linked hardware will appear in the field, and the Axis Type will change appropriately.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="472" height="126" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkedNcHardwareAxis_1.png" alt="LinkedNcHardwareAxis 1" class="wp-image-18447" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkedNcHardwareAxis_1.png 472w, https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkedNcHardwareAxis_1-300x80.png 300w" sizes="(max-width: 472px) 100vw, 472px" /></figure>



<p class="wp-block-paragraph">At this point, the NC axis is properly configured and ready to be linked to the PLC code using one of the methods in the following sections! Alternatively, if we wanted to create a&nbsp;<a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tf50x0_tc3_nc_ptp/2834717323.html&amp;id=8250271195349757571">simulation on the axis</a>, we could leave this unlinked and make sure the Axis Type is&nbsp;<strong>Standard (Mapping via Encoder and Drive).</strong></p>



<h2 id="h-method-1-manual-linking" class="wp-block-heading">Method 1: Manual Linking</h2>



<p class="wp-block-paragraph"><a href="#h-table-of-contents">Back to Table of Contents</a></p>



<p class="wp-block-paragraph">The first method for hardware linking is manual linking, which is a fairly straightforward process. First, expand the task inputs/outputs and select the desired variable.&nbsp;Right-click on it and select Change Link, or double-click and select the <strong>Linked to</strong> button on the <strong>Variable</strong> tab. This will open the link selection dialog box.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="879" height="365" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/ChangeVariableLink_1.png" alt="ChangeVariableLink 1" class="wp-image-18448" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/ChangeVariableLink_1.png 879w, https://static.dmcinfo.com/wp-content/uploads/2025/05/ChangeVariableLink_1-300x125.png 300w, https://static.dmcinfo.com/wp-content/uploads/2025/05/ChangeVariableLink_1-768x319.png 768w" sizes="(max-width: 879px) 100vw, 879px" /></figure>



<p class="wp-block-paragraph">From this dialog box, we can select the hardware card and specific channel to which the selected IO variable will be linked. The search bar and filters at the side of the dialog box like&nbsp;<strong>Only Unused</strong>&nbsp;and&nbsp;<strong>Matching Type/Size</strong>&nbsp;can be helpful in finding the proper/available hardware quickly. Select the proper channel and click&nbsp;<strong>Ok</strong>&nbsp;to link the variable.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="583" height="473" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkVariable.png" alt="LinkVariable" class="wp-image-18449" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkVariable.png 583w, https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkVariable-300x243.png 300w" sizes="(max-width: 583px) 100vw, 583px" /></figure>



<p class="wp-block-paragraph">We can also do this from the other direction – if we want to start from the hardware configuration, we can select a certain channel and open a similar dialog box to select the IO variable to which it should be linked.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="883" height="527" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/ChangeHardwareLink.png" alt="ChangeHardwareLink" class="wp-image-18450" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/ChangeHardwareLink.png 883w, https://static.dmcinfo.com/wp-content/uploads/2025/05/ChangeHardwareLink-300x179.png 300w, https://static.dmcinfo.com/wp-content/uploads/2025/05/ChangeHardwareLink-768x458.png 768w" sizes="(max-width: 883px) 100vw, 883px" /></figure>



<figure class="wp-block-image size-full"><img decoding="async" width="583" height="470" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkHardware_1.png" alt="LinkHardware 1" class="wp-image-18451" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkHardware_1.png 583w, https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkHardware_1-300x242.png 300w" sizes="(max-width: 583px) 100vw, 583px" /></figure>



<p class="wp-block-paragraph">Once a variable or hardware channel is linked, a small square icon with an arrow will appear at the corner of the icon in the solution explorer. When variables are linked manually, this icon is gray.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="292" height="235" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/ManuallyLinkedVariables.png" alt="ManuallyLinkedVariables" class="wp-image-18452"/></figure>



<p class="wp-block-paragraph">Helpfully, we can easily navigate between the now-linked items by right-clicking and selecting&nbsp;<strong>Go To Link Variable</strong>.&nbsp;</p>



<figure class="wp-block-image size-full"><img decoding="async" width="346" height="137" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/GoToLinkFromPLC_1.png" alt="GoToLinkFromPLC 1" class="wp-image-18453" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/GoToLinkFromPLC_1.png 346w, https://static.dmcinfo.com/wp-content/uploads/2025/05/GoToLinkFromPLC_1-300x119.png 300w" sizes="(max-width: 346px) 100vw, 346px" /></figure>



<h2 id="h-motion-0" class="wp-block-heading">Motion</h2>



<p class="wp-block-paragraph"><a href="#h-table-of-contents">Back to Table of Contents</a></p>



<p class="wp-block-paragraph">For&nbsp;<code><strong>AXIS_REF</strong></code>&nbsp;structures, linking to the PLC is done from the NC task. Return to&nbsp;<strong>[Solution] &gt; MOTION &gt; [NC Task] &gt; Axes &gt; [Axis] &gt; Settings</strong>&nbsp;and use the&nbsp;<strong>Link To PLC</strong>&nbsp;button to select the desired&nbsp;<code><strong>AXIS_REF</strong></code>&nbsp;structure.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="873" height="297" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/AxisLinkToPlcButton.png" alt="AxisLinkToPlcButton" class="wp-image-18455" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/AxisLinkToPlcButton.png 873w, https://static.dmcinfo.com/wp-content/uploads/2025/05/AxisLinkToPlcButton-300x102.png 300w, https://static.dmcinfo.com/wp-content/uploads/2025/05/AxisLinkToPlcButton-768x261.png 768w" sizes="(max-width: 873px) 100vw, 873px" /></figure>



<figure class="wp-block-image size-full"><img decoding="async" width="462" height="216" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkAxisToPlc.png" alt="LinkAxisToPlc" class="wp-image-18456" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkAxisToPlc.png 462w, https://static.dmcinfo.com/wp-content/uploads/2025/05/LinkAxisToPlc-300x140.png 300w" sizes="(max-width: 462px) 100vw, 462px" /></figure>



<p class="wp-block-paragraph">Once linked, the&nbsp;<code><strong>AXIS_REF</strong></code>&nbsp;variable will appear in the field, and the&nbsp;<code><strong>NcToPlc</strong></code>&nbsp;and&nbsp;<code><strong>PlcToNc</strong></code>&nbsp;members of the&nbsp;<code><strong>AXIS_REF</strong></code>&nbsp;structure will show gray boxed arrows in the PLC Instance inputs and outputs, indicating they are properly linked.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="885" height="473" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/ManuallyLinkedAxis.png" alt="ManuallyLinkedAxis" class="wp-image-18457" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/ManuallyLinkedAxis.png 885w, https://static.dmcinfo.com/wp-content/uploads/2025/05/ManuallyLinkedAxis-300x160.png 300w, https://static.dmcinfo.com/wp-content/uploads/2025/05/ManuallyLinkedAxis-768x410.png 768w" sizes="(max-width: 885px) 100vw, 885px" /></figure>



<h2 id="h-method-2-attribute-linking" class="wp-block-heading">Method 2: Attribute Linking</h2>



<p class="wp-block-paragraph"><a href="#h-table-of-contents">Back to Table of Contents</a></p>



<p class="wp-block-paragraph">The second method for hardware linking is attribute linking using the&nbsp;<a href="https://infosys.beckhoff.com/content/1033/tc3_plc_intro/3107974923.html?id=3796864311828577666" target="_blank" rel="noreferrer noopener"><code><strong>TcLinkTo</strong></code></a>,&nbsp;<a href="https://infosys.beckhoff.com/content/1033/tc3_plc_intro/3107974923.html?id=3796864311828577666" target="_blank" rel="noreferrer noopener"><code><strong>TcLinkToOSO</strong></code></a>, and&nbsp;<a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/3107990667.html&amp;id=7493071042325947826" target="_blank" rel="noreferrer noopener"><code><strong>TcNcAxis</strong></code></a>&nbsp;attributes. This isn’t as straightforward as manual linking, but it has its advantages —&nbsp;especially when using&nbsp;<a href="https://static.dmcinfo.com/blog/18615/version-control-and-multi-user-development-with-beckhoff-twincat-3/">version control</a>.</p>



<h3 id="h-single-variables" class="wp-block-heading">Single Variables</h3>



<p class="wp-block-paragraph">For most linking, we can just use the basic&nbsp;<a href="https://infosys.beckhoff.com/content/1033/tc3_plc_intro/3107974923.html?id=3796864311828577666" target="_blank" rel="noreferrer noopener"><code><strong>TcLinkTo</strong></code></a>&nbsp;attribute. Here are a few examples.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>VAR
    {attribute 'TcLinkTo' :=
        'TIID^Master_EtherCAT^Coupler_EK1100^Term1_EL1008^Channel 4^Input'}
    boolInput2 AT %I* : BOOL;

    {attribute 'TcLinkTo' :=
        'TIID^Master_EtherCAT^Coupler_EK1100^Term2_EL2008^Channel 4^Output'}
    boolOutput2 AT %Q* : BOOL;

    {attribute 'TcLinkTo' :=
        'TIID^Master_EtherCAT^Coupler_EK1100^Term3_EL3008^AI Standard Channel 4^Value'}
    intInput2 AT %I* : INT;

    {attribute 'TcLinkTo' :=
        'TIID^Master_EtherCAT^Coupler_EK1100^Term4_EL4008^AO Outputs Channel 4^Analog output'}
    intOutput2 AT %Q* : INT;
END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcLinkTo&apos; :=</span></span>
<span class="line"><span style="color: #D4D4D4">        &apos;TIID^Master_EtherCAT^Coupler_EK1100^Term1_EL1008^Channel 4^Input&apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    boolInput2 AT %I* : BOOL;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcLinkTo&apos; :=</span></span>
<span class="line"><span style="color: #D4D4D4">        &apos;TIID^Master_EtherCAT^Coupler_EK1100^Term2_EL2008^Channel 4^Output&apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    boolOutput2 AT %Q* : BOOL;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcLinkTo&apos; :=</span></span>
<span class="line"><span style="color: #D4D4D4">        &apos;TIID^Master_EtherCAT^Coupler_EK1100^Term3_EL3008^AI Standard Channel 4^Value&apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    intInput2 AT %I* : INT;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcLinkTo&apos; :=</span></span>
<span class="line"><span style="color: #D4D4D4">        &apos;TIID^Master_EtherCAT^Coupler_EK1100^Term4_EL4008^AO Outputs Channel 4^Analog output&apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    intOutput2 AT %Q* : INT;</span></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<p class="wp-block-paragraph">By placing the attribute line above the declaration, we are telling the compiler the hardware item to which we want the variable to be linked.&nbsp;<strong>The path to that hardware item must be exact and have the correct syntax.</strong>&nbsp;The easiest way to get the&nbsp;syntax for this path is to navigate to the hardware item in the solution explorer and&nbsp;copy the syntax from the&nbsp;<strong>Full Name</strong>&nbsp;field.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="883" height="569" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/HardwareFullName.png" alt="HardwareFullName" class="wp-image-18458" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/HardwareFullName.png 883w, https://static.dmcinfo.com/wp-content/uploads/2025/05/HardwareFullName-300x193.png 300w, https://static.dmcinfo.com/wp-content/uploads/2025/05/HardwareFullName-768x495.png 768w" sizes="(max-width: 883px) 100vw, 883px" /></figure>



<p class="wp-block-paragraph">After properly setting up the attribute, compiling the project should link the variables to their respective hardware. This can be confirmed by examining the instance&nbsp;inputs/outputs in the Solution Explorer. Again, we should see a small square icon with an arrow on linked variables, but this time it will be&nbsp;blue. We can still use the&nbsp;<strong>Go To Link Variable</strong>&nbsp;context menu option to jump to linked hardware item.&nbsp;</p>



<figure class="wp-block-image size-full"><img decoding="async" width="297" height="328" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/AttributeLinkedSingleVariables.png" alt="AttributeLinkedSingleVariables" class="wp-image-18459" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/AttributeLinkedSingleVariables.png 297w, https://static.dmcinfo.com/wp-content/uploads/2025/05/AttributeLinkedSingleVariables-272x300.png 272w" sizes="(max-width: 297px) 100vw, 297px" /></figure>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img decoding="async" width="292" height="118" data-id="18460" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/GoToLinkFromPLCAttribute.png" alt="GoToLinkFromPLCAttribute" class="wp-image-18460"/></figure>



<figure class="wp-block-image size-large"><img decoding="async" width="340" height="123" data-id="18461" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/GoToLinkFromHardwareAttribute.png" alt="GoToLinkFromHardwareAttribute" class="wp-image-18461" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/GoToLinkFromHardwareAttribute.png 340w, https://static.dmcinfo.com/wp-content/uploads/2025/05/GoToLinkFromHardwareAttribute-300x109.png 300w" sizes="(max-width: 340px) 100vw, 340px" /></figure>
</figure>



<h3 id="h-nested-variables" class="wp-block-heading">Nested Variables</h3>



<p class="wp-block-paragraph"><a href="#h-table-of-contents">Back to Table of Contents</a></p>



<p class="wp-block-paragraph">IO variables nested within one or many layers of structures/function blocks can also be linked, with some extra syntax added to the&nbsp;<code><strong>TcLinkTo</strong></code>&nbsp;attribute. This is very powerful because it means that, even if we have IO variables declared within structures or function blocks, we can still link every instance of those reusable items individually.</p>



<p class="wp-block-paragraph">To link nested variables, we just need to add the path to the variables within the structure or function block to our attribute. Here is an&nbsp;example using the same structure definition as above:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>VAR
    {attribute 'TcLinkTo' := '
        .boolInput  := TIID^Master_EtherCAT^Coupler_EK1100^Term1_EL1008^Channel 5^Input;
        .boolOutput := TIID^Master_EtherCAT^Coupler_EK1100^Term2_EL2008^Channel 5^Output;
        .intInput   := TIID^Master_EtherCAT^Coupler_EK1100^Term3_EL3008^AI Standard Channel 5^Value;
        .intOutput  := TIID^Master_EtherCAT^Coupler_EK1100^Term4_EL4008^AO Outputs Channel 5^Analog output;
    '}
    structLinkedByAttribute : ST_IncludingIO;
END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcLinkTo&apos; := &apos;</span></span>
<span class="line"><span style="color: #D4D4D4">        .boolInput  := TIID^Master_EtherCAT^Coupler_EK1100^Term1_EL1008^Channel 5^Input;</span></span>
<span class="line"><span style="color: #D4D4D4">        .boolOutput := TIID^Master_EtherCAT^Coupler_EK1100^Term2_EL2008^Channel 5^Output;</span></span>
<span class="line"><span style="color: #D4D4D4">        .intInput   := TIID^Master_EtherCAT^Coupler_EK1100^Term3_EL3008^AI Standard Channel 5^Value;</span></span>
<span class="line"><span style="color: #D4D4D4">        .intOutput  := TIID^Master_EtherCAT^Coupler_EK1100^Term4_EL4008^AO Outputs Channel 5^Analog output;</span></span>
<span class="line"><span style="color: #D4D4D4">    &apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    structLinkedByAttribute : ST_IncludingIO;</span></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<h3 id="h-mismatched-variables-size-types" class="wp-block-heading">Mismatched Variables Size/Types</h3>



<p class="wp-block-paragraph"><a href="#h-table-of-contents">Back to Table of Contents</a></p>



<p class="wp-block-paragraph">In certain cases, our IO variables may not have the same size as the hardware variable to which we want to link them; for example,&nbsp;accessing bits in a byte&nbsp;or combining separate bytes into a word. It may be simpler/more readable to just make sure the IO variable does match the type of the hardware variable and handle any interpretation within the PLC. But, in the event that this isn’t possible, there is a solution.&nbsp;</p>



<p class="wp-block-paragraph">The&nbsp;<a href="https://infosys.beckhoff.com/content/1033/tc3_plc_intro/3107974923.html?id=3796864311828577666" target="_blank" rel="noreferrer noopener"><code><strong>TcLinkToOSO</strong></code></a>&nbsp;attribute allows us to select exactly which bit range from our hardware will be mapped to our IO variables in the PLC program. “OSO” stands for “Offset, Size, Offset,”&nbsp;which is the extra information we will have to supply. The syntax is&nbsp;<strong><code>&lt;x,y,z&gt;</code></strong>, where:&nbsp;</p>



<p class="wp-block-paragraph"><strong><code>x</code></strong>&nbsp;= Bit-offset of the PLC variable&nbsp;</p>



<p class="wp-block-paragraph"><strong><code>y</code></strong>&nbsp;= Number of bits to map&nbsp;</p>



<p class="wp-block-paragraph"><strong><code>z</code></strong>&nbsp;= Bit-offset of the hardware variable&nbsp;</p>



<p class="wp-block-paragraph">For example:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>VAR
    {attribute 'TcLinkToOSO' := '
        &lt;0,16,0>TIID^Master_EtherCAT^Coupler_EK1100^Term4_EL4008^AO Outputs Channel 6^Analog output;
        &lt;16,16,0>TIID^Master_EtherCAT^Coupler_EK1100^Term4_EL4008^AO Outputs Channel 7^Analog output;
    '}
    dintLinkedTo2Ints AT %Q* : DINT;
END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcLinkToOSO&apos; := &apos;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #808080">&lt;</span><span style="color: #F44747">0,16,0</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">TIID^Master_EtherCAT^Coupler_EK1100^Term4_EL4008^AO Outputs Channel 6^Analog output;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #808080">&lt;</span><span style="color: #F44747">16,16,0</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">TIID^Master_EtherCAT^Coupler_EK1100^Term4_EL4008^AO Outputs Channel 7^Analog output;</span></span>
<span class="line"><span style="color: #D4D4D4">    &apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    dintLinkedTo2Ints AT %Q* : DINT;</span></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<p class="wp-block-paragraph">Here&nbsp;we are linking a larger PLC variable to two&nbsp;smaller hardware variables. We specify that the first 16 bits of the PLC&nbsp;<code><strong>DINT</strong></code>&nbsp;(<strong><code>x</code></strong>=0,&nbsp;<strong><code>y</code></strong>=16) should be linked to the first 16 bits of the specified 16-bit&nbsp;integer input channel (<strong><code>y</code></strong>=16,&nbsp;<code><strong>z</strong></code>=0). The result is the prefix of the first line, with&nbsp;<strong><code>&lt;0,16,0&gt;</code></strong>.&nbsp;</p>



<p class="wp-block-paragraph">Then, starting at bit 16 in the PLC&nbsp;<code><strong>DINT</strong></code>&nbsp;(<code><strong>x</strong></code>=16), we link the next 16 bits (<code><strong>y</strong></code>=16) to the first 16 bits of a separate 16-bit&nbsp;integer input channel (<code><strong>y</strong></code>=16,&nbsp;<code><strong>z</strong></code>=0). The result is the prefix of the second line, with&nbsp;<code><strong>&lt;16,16,0&gt;</strong></code>.</p>



<p class="wp-block-paragraph">Another example, this time linking 2 smaller PLC variables to a larger hardware variable:&nbsp;</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>VAR
    {attribute 'TcLinkToOSO' :=
        '&lt;0,8,0>TIID^Master_EtherCAT^Coupler_EK1100^Term4_EL4008^AO Outputs Channel 8^Analog output'}
    byte0LinkedToInt AT %Q* : BYTE;

    {attribute 'TcLinkToOSO' :=
        '&lt;0,8,8>TIID^Master_EtherCAT^Coupler_EK1100^Term4_EL4008^AO Outputs Channel 8^Analog output'}
    byte1LinkedToInt AT %Q* : BYTE;
END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcLinkToOSO&apos; :=</span></span>
<span class="line"><span style="color: #D4D4D4">        &apos;</span><span style="color: #808080">&lt;</span><span style="color: #F44747">0,8,0</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">TIID^Master_EtherCAT^Coupler_EK1100^Term4_EL4008^AO Outputs Channel 8^Analog output&apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    byte0LinkedToInt AT %Q* : BYTE;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcLinkToOSO&apos; :=</span></span>
<span class="line"><span style="color: #D4D4D4">        &apos;</span><span style="color: #808080">&lt;</span><span style="color: #F44747">0,8,8</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">TIID^Master_EtherCAT^Coupler_EK1100^Term4_EL4008^AO Outputs Channel 8^Analog output&apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    byte1LinkedToInt AT %Q* : BYTE;</span></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<p class="wp-block-paragraph">Here, we link the first 8 bits of the first PLC byte (<code><strong>x</strong></code>=0,&nbsp;<code><strong>y</strong></code>=8) to the first 8 bits of the specified 16-bit integer input channel (<code><strong>y</strong></code>=8,&nbsp;<strong><code>z</code></strong>=0). The result is the attribute for the first variable,&nbsp;<code><strong>&lt;0,8,0&gt;</strong></code>.</p>



<p class="wp-block-paragraph">Then, we link the first 8 bits of the second PLC byte (<strong><code>x</code></strong>=0,&nbsp;<strong><code>y</code></strong>=8) to the second 8 bits of the same specified 16-bit integer input channel (<strong><code>y</code></strong>=8,&nbsp;<strong><code>z</code></strong>=8). The result is the attribute for the second variable,&nbsp;<code><strong>&lt;0,8,8&gt;</strong></code>.</p>



<p class="wp-block-paragraph">Variables linked with&nbsp;<code><strong>TcLinkToOSO</strong></code>&nbsp;can also be placed within structures/function blocks.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// Type definition
TYPE ST_IntSplitToBytes :
STRUCT
    byteArr : ARRAY&#91;0..1&#93; OF BYTE;
END_STRUCT
END_TYPE


// Declaration
VAR
    {attribute 'TcLinkToOSO' := '
        .byteArr&#91;0&#93; := &lt;0,8,0>TIID^Master_EtherCAT^Coupler_EK1100^Term3_EL3008^AI Standard Channel 6^Value;
        .byteArr&#91;1&#93; := &lt;0,8,8>TIID^Master_EtherCAT^Coupler_EK1100^Term3_EL3008^AI Standard Channel 6^Value
    '}
    structOSOLinking AT %I* : ST_IntSplitToBytes;
END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">// Type definition</span></span>
<span class="line"><span style="color: #D4D4D4">TYPE ST_IntSplitToBytes :</span></span>
<span class="line"><span style="color: #D4D4D4">STRUCT</span></span>
<span class="line"><span style="color: #D4D4D4">    byteArr : ARRAY&#91;0..1&#93; OF BYTE;</span></span>
<span class="line"><span style="color: #D4D4D4">END_STRUCT</span></span>
<span class="line"><span style="color: #D4D4D4">END_TYPE</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">// Declaration</span></span>
<span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcLinkToOSO&apos; := &apos;</span></span>
<span class="line"><span style="color: #D4D4D4">        .byteArr&#91;0&#93; := </span><span style="color: #808080">&lt;</span><span style="color: #F44747">0,8,0</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">TIID^Master_EtherCAT^Coupler_EK1100^Term3_EL3008^AI Standard Channel 6^Value;</span></span>
<span class="line"><span style="color: #D4D4D4">        .byteArr&#91;1&#93; := </span><span style="color: #808080">&lt;</span><span style="color: #F44747">0,8,8</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">TIID^Master_EtherCAT^Coupler_EK1100^Term3_EL3008^AI Standard Channel 6^Value</span></span>
<span class="line"><span style="color: #D4D4D4">    &apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    structOSOLinking AT %I* : ST_IntSplitToBytes;</span></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<h3 id="h-motion-1" class="wp-block-heading">Motion</h3>



<p class="wp-block-paragraph"><a href="#h-table-of-contents">Back to Table of Contents</a></p>



<p class="wp-block-paragraph">Linking&nbsp;<code><strong>AXIS_REF</strong></code>&nbsp;structures uses a different attribute,&nbsp;<a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/3107990667.html&amp;id=7493071042325947826" target="_blank" rel="noreferrer noopener"><code><strong>TcNcAxis</strong></code></a>. All that is needed in this case is the axis name from the MOTION NC task setup, instead of the hardware path.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>VAR
    {attribute 'TcNcAxis' := 'Axis2'}
    axis2 : AXIS_REF;
END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcNcAxis&apos; := &apos;Axis2&apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    axis2 : AXIS_REF;</span></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<figure class="wp-block-image size-full"><img decoding="async" width="225" height="343" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/AttributeLinkedAxis.png" alt="AttributeLinkedAxis" class="wp-image-18462" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/AttributeLinkedAxis.png 225w, https://static.dmcinfo.com/wp-content/uploads/2025/05/AttributeLinkedAxis-197x300.png 197w" sizes="(max-width: 225px) 100vw, 225px" /></figure>



<p class="wp-block-paragraph"><code><strong>AXIS_REF</strong></code>&nbsp;structures can also be linked from within structures/function blocks.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// Type definition
TYPE ST_Axis :
STRUCT
    axis : AXIS_REF;

    some      AT %I* : BOOL;
    other     AT %I* : INT;
    variables AT %I* : INT;

    included  : REAL;
END_STRUCT
END_TYPE


// Declaration
VAR
    {attribute 'TcNcAxis' := '
        .axis := Axis3;
    '}
    structAxis : ST_Axis;
END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">// Type definition</span></span>
<span class="line"><span style="color: #D4D4D4">TYPE ST_Axis :</span></span>
<span class="line"><span style="color: #D4D4D4">STRUCT</span></span>
<span class="line"><span style="color: #D4D4D4">    axis : AXIS_REF;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    some      AT %I* : BOOL;</span></span>
<span class="line"><span style="color: #D4D4D4">    other     AT %I* : INT;</span></span>
<span class="line"><span style="color: #D4D4D4">    variables AT %I* : INT;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    included  : REAL;</span></span>
<span class="line"><span style="color: #D4D4D4">END_STRUCT</span></span>
<span class="line"><span style="color: #D4D4D4">END_TYPE</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">// Declaration</span></span>
<span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcNcAxis&apos; := &apos;</span></span>
<span class="line"><span style="color: #D4D4D4">        .axis := Axis3;</span></span>
<span class="line"><span style="color: #D4D4D4">    &apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    structAxis : ST_Axis;</span></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<p class="wp-block-paragraph"><strong>Combining Linking Attributes</strong></p>



<p class="wp-block-paragraph"><a href="#h-table-of-contents">Back to Table of Contents</a></p>



<p class="wp-block-paragraph">We can mix and match the different linking attributes&nbsp;as we like; however, we can only use each attribute once —&nbsp;all subsequent uses of that attribute will be ignored. Of course, within a single use of an attribute, we can link multiple variables.</p>



<p class="wp-block-paragraph">For example, to link the rest of the variables in the above structure:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>VAR
    {attribute 'TcNcAxis' := '
        .axis := Axis3;
    '}

    {attribute 'TcLinkTo' := '
        .some  := TIID^Master_EtherCAT^Coupler_EK1100^Term1_EL1008^Channel 8^Input;
        .other := TIID^Master_EtherCAT^Coupler_EK1100^Term3_EL3008^AI Standard Channel 7^Value;
    '}

    {attribute 'TcLinkToOSO' := '
        .variables := &lt;0,4,0>TIID^Master_EtherCAT^Coupler_EK1100^Term3_EL3008^AI Standard Channel 8^Value;
    '}

    structAxis : ST_Axis;
END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcNcAxis&apos; := &apos;</span></span>
<span class="line"><span style="color: #D4D4D4">        .axis := Axis3;</span></span>
<span class="line"><span style="color: #D4D4D4">    &apos;}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcLinkTo&apos; := &apos;</span></span>
<span class="line"><span style="color: #D4D4D4">        .some  := TIID^Master_EtherCAT^Coupler_EK1100^Term1_EL1008^Channel 8^Input;</span></span>
<span class="line"><span style="color: #D4D4D4">        .other := TIID^Master_EtherCAT^Coupler_EK1100^Term3_EL3008^AI Standard Channel 7^Value;</span></span>
<span class="line"><span style="color: #D4D4D4">    &apos;}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    {attribute &apos;TcLinkToOSO&apos; := &apos;</span></span>
<span class="line"><span style="color: #D4D4D4">        .variables := </span><span style="color: #808080">&lt;</span><span style="color: #F44747">0,4,0</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">TIID^Master_EtherCAT^Coupler_EK1100^Term3_EL3008^AI Standard Channel 8^Value;</span></span>
<span class="line"><span style="color: #D4D4D4">    &apos;}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    structAxis : ST_Axis;</span></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<h2 id="h-comparisons" class="wp-block-heading">Comparisons</h2>



<p class="wp-block-paragraph"><a href="#h-table-of-contents">Back to Table of Contents</a></p>



<p class="wp-block-paragraph">Now that we have multiple methods for linking PLC variables to hardware, why might we choose one over the others? Here are some pros/cons for each method —&nbsp;if you have other thoughts, please leave them in the comment section below!&nbsp;</p>



<p class="wp-block-paragraph"><strong>Manual</strong></p>



<p class="wp-block-paragraph"><em>Pros</em></p>



<ul class="wp-block-list">
<li>When variables are manually linked,&nbsp;the link will automatically update if the name of a hardware card/channel changes. With attribute linking, such a name change will break the hardware link until the attribute hardware path is updated in the PLC declaration code.</li>



<li>As mentioned above, when linking variables, we can start from either direction —&nbsp;PLC to hardware or hardware to PLC. Since attribute linking must be done within the PLC source code, it can only be done from PLC to hardware. The flexibility of manual linking might come in handy when reading from large IO sheets that are organized for electrical cabinet wiring.&nbsp;</li>
</ul>



<p class="wp-block-paragraph"><em>Cons</em></p>



<ul class="wp-block-list">
<li>Manual hardware links are stored in an XML format in&nbsp;<code><strong>.tsproj</strong></code>&nbsp;or&nbsp;<code><strong>.xti</strong></code>&nbsp;files (depending on a project&#8217;s&nbsp;<a href="https://static.dmcinfo.com/blog/18615/version-control-and-multi-user-development-with-beckhoff-twincat-3/">independent project files</a>&nbsp;settings). These files may change often and contain plenty of other information not related to hardware linking. Also, the XML that defines the hardware mapping is not as directly readable as the hardware paths used for attribute linking. For these reasons, changes in hardware linking are less visible in version control —&nbsp;it may be harder to look through commit histories and find where these changes were made and what they mean.</li>



<li>Because manual hardware links are stored in XML format, manual hardware linking is more easily lost during merges. This can cause headaches, especially when working with a multi-developer team.</li>
</ul>



<p class="wp-block-paragraph"><strong>Attribute </strong></p>



<p class="wp-block-paragraph"><em>Pros</em></p>



<ul class="wp-block-list">
<li>Perhaps the biggest positive of using attribute linking is its compatibility with version control. Attribute linking exists within source code rather than being stuck in the XML of project files;&nbsp;therefore, it merges as easily as source code does and is much more visible for tracking/finding changes.&nbsp;</li>



<li>Manual linking is, well, manual, and must be set up one variable at a time. Attribute linking exists within code, with a predictable syntax. For this reason, depending on the architecture of our program, it may be very easy to write a simple program (in Python, for example) to automate our hardware linking for us.&nbsp;The program could&nbsp;take&nbsp;in a CSV of hardware points/IO variable names and output the attribute linking syntax required. Then updating IO linking is a breeze – just make updates to the CSV, run the Python program, and copy and paste the resulting attribute/declaration code into the project.&nbsp;</li>
</ul>



<p class="wp-block-paragraph"><em>Cons</em></p>



<ul class="wp-block-list">
<li>Attribute linking requires precise syntax, which can be tedious to get right.&nbsp;</li>



<li>If the name of a hardware card/channel changes, the link will not automatically update. The attribute linking source code must be updated to reflect this change. If this is a higher-level component, like an EtherCAT Master, this could mean editing a lot of code – or automating the update using find and replace or a custom program like mentioned above.</li>
</ul>



<h2 id="h-project-variants" class="wp-block-heading"><a id="Project Variants" name="Project Variants"></a>Project Variants</h2>



<p class="wp-block-paragraph"><a href="#h-table-of-contents">Back to Table of Contents</a></p>



<p class="wp-block-paragraph">One of TwinCAT’s unique and powerful features is the concept of <a href="https://static.dmcinfo.com/blog/18781/twincat-project-variants/">project variants</a>, and one of their uses is to allow modification of hardware mapping depending on the selected variant. This can be used&nbsp;regardless of which linking method is used. For manual mapping, follow <a href="https://static.dmcinfo.com/blog/18463/how-to-link-hardware-io-in-beckhoff-twincat-3/">these instructions</a>. For attribute mapping, we can use <a href="https://static.dmcinfo.com/blog/18781/twincat-project-variants/">conditional pragmas</a>. Here is an example of how one might use these pragmas to change hardware linking based on the selected project variant. Keep in mind that we will have to build the project with a certain variant selected for that variant’s hardware linking to appear in the solution explorer.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">HTML</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>VAR

    {IF defined(Variant1)}
        {attribute 'TcLinkTo' := '
            .boolInput  := TIID^Master_EtherCAT^Coupler_EK1100^Term1_EL1008^Channel 6^Input;
            .boolOutput := TIID^Master_EtherCAT^Coupler_EK1100^Term2_EL2008^Channel 6^Output;
        '}
    {END_IF}

    {IF defined(Variant2)}
        {attribute 'TcLinkTo' := '
            .boolInput  := TIID^Master_EtherCAT^Coupler_EK1100^Term1_EL1008^Channel 7^Input;
            .boolOutput := TIID^Master_EtherCAT^Coupler_EK1100^Term2_EL2008^Channel 6^Output;
        '}
    {END_IF}

    variantsExample : ST_IncludingIO;

END_VAR</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">VAR</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    {IF defined(Variant1)}</span></span>
<span class="line"><span style="color: #D4D4D4">        {attribute &apos;TcLinkTo&apos; := &apos;</span></span>
<span class="line"><span style="color: #D4D4D4">            .boolInput  := TIID^Master_EtherCAT^Coupler_EK1100^Term1_EL1008^Channel 6^Input;</span></span>
<span class="line"><span style="color: #D4D4D4">            .boolOutput := TIID^Master_EtherCAT^Coupler_EK1100^Term2_EL2008^Channel 6^Output;</span></span>
<span class="line"><span style="color: #D4D4D4">        &apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    {END_IF}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    {IF defined(Variant2)}</span></span>
<span class="line"><span style="color: #D4D4D4">        {attribute &apos;TcLinkTo&apos; := &apos;</span></span>
<span class="line"><span style="color: #D4D4D4">            .boolInput  := TIID^Master_EtherCAT^Coupler_EK1100^Term1_EL1008^Channel 7^Input;</span></span>
<span class="line"><span style="color: #D4D4D4">            .boolOutput := TIID^Master_EtherCAT^Coupler_EK1100^Term2_EL2008^Channel 6^Output;</span></span>
<span class="line"><span style="color: #D4D4D4">        &apos;}</span></span>
<span class="line"><span style="color: #D4D4D4">    {END_IF}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    variantsExample : ST_IncludingIO;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">END_VAR</span></span></code></pre></div>



<p class="wp-block-paragraph">Unfortunately, since each linking attribute can only be used once, every single&nbsp;variable link for a structure&nbsp;must be included in the conditional statement&nbsp;for every variant —&nbsp;regardless of whether a particular variable link changes depending on the project variant. This can be more tedious than manual linking while using project variants, but it&#8217;s a lot more explicit —&nbsp;since the two link lists are explicitly in code, rather than hidden away in the solution explorer menus.</p>



<p class="wp-block-paragraph">&nbsp;</p>



<h2 id="h-further-reference" class="wp-block-heading"><a id="Further Reference" name="Further Reference"></a>Further Reference</h2>



<p class="wp-block-paragraph"><a href="#h-table-of-contents">Back to Table of Contents</a></p>



<p class="wp-block-paragraph">For more information on the topics discussed in this blog, please see the following:</p>



<ul class="wp-block-list">
<li><a href="https://infosys.beckhoff.com/content/1033/tc3_plc_intro/3107974923.html?id=3796864311828577666" target="_blank"><code><strong>TcLinkTo</strong></code> / <code><strong>TcLinkToOSO</strong></code> Infosys Page</a></li>



<li><a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/3107990667.html&amp;id=7493071042325947826" target="_blank"><code><strong>TcNcAxis</strong></code> Infosys Page</a></li>



<li><a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tcplclib_tc2_mc2/70132363.html&amp;id=467387231256035047" target="_blank"><code><strong>AXIS_REF</strong></code> Infosys Page</a></li>



<li><a href="https://infosys.beckhoff.com/content/1033/tcplclib_tc2_mc2/index.html?id=4786081293094367280" target="_blank"><strong><code>Tc2_MC2</code></strong> Infosys Section</a></li>



<li><a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tf50x0_tc3_nc_ptp/2834717323.html&amp;id=8250271195349757571" target="_blank">Simulation Axis Infosys Page</a></li>



<li><a href="https://static.dmcinfo.com/blog/18615/version-control-and-multi-user-development-with-beckhoff-twincat-3/">TwinCAT with Version Control Blog</a></li>



<li><a href="https://static.dmcinfo.com/blog/18781/twincat-project-variants/">TwinCAT Project Variants Blog</a></li>
</ul>



<p class="wp-block-paragraph">That’s about all you need to know to get started with hardware linking in your TwinCAT projects! If you’ve got any further tips and tricks regarding this topic, please share them in the comments below!</p>



<p class="wp-block-paragraph"><strong>Learn more about <a href="/services/manufacturing-automation-and-intelligence/plc-programming/beckhoff-and-twincat-3-programming">DMC&#8217;s Beckhoff and TwinCAT 3 Programming expertise</a>&nbsp;and <a href="/contact">contact us</a> today for your next project.</strong></p>
<p>The post <a href="https://static.dmcinfo.com/blog/18463/how-to-link-hardware-io-in-beckhoff-twincat-3/">How to Link Hardware / IO in Beckhoff TwinCAT 3</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Version Control and Multi-user Development with Beckhoff TwinCAT 3</title>
		<link>https://static.dmcinfo.com/blog/18615/version-control-and-multi-user-development-with-beckhoff-twincat-3/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Wed, 30 Mar 2022 14:05:50 +0000</pubDate>
				<category><![CDATA[Beckhoff PLC]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[PLC]]></category>
		<category><![CDATA[Beckhoff]]></category>
		<category><![CDATA[TwinCAT 3]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/18615/version-control-and-multi-user-development-with-beckhoff-twincat-3/</guid>

					<description><![CDATA[<p>Why Version Control? If you&#8217;ve ever gone through a project archive, found something that looks like the following: &#8230;and been confused about what the most recent version of the project is, then you&#8217;ve experienced one of the many reasons to use version control systems!&#160; From backing up code to tracking changes to concurrent multi-user development, [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/18615/version-control-and-multi-user-development-with-beckhoff-twincat-3/">Version Control and Multi-user Development with Beckhoff TwinCAT 3</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2 class="wp-block-heading">Why Version Control?</h2>

<p class="wp-block-paragraph">If you&rsquo;ve ever gone through a project archive, found something that looks like the following:</p>

<ul class="wp-block-list">
 <li>Project_20180807</li>
 <li>Project_20180813</li>
 <li>Project_20180813_Final</li>
 <li>Project_20180813_FinalB</li>
 <li>Project_20180813_FinalFinal</li>
 <li>Project_20180813_Newest_I_SWEAR</li>
</ul>

<p class="wp-block-paragraph">&hellip;and been confused about what the most recent version of the project is, then you&rsquo;ve experienced one of the many reasons to use version control systems!&nbsp;</p>

<p class="wp-block-paragraph">From backing up code to tracking changes to concurrent multi-user development, <a href="https://towardsdatascience.com/version-control-101-definition-and-benefits-6fd7ad49e5f1" target="_blank">version control systems</a>&nbsp;(VCS) offer so many advantages that they should be an essential tool for any software engineer.&nbsp;Yet&nbsp;the automation industry has struggled to effectively use all the advantages that VCS offer.&nbsp;</p>

<p class="wp-block-paragraph">Proprietary and binary file formats that are common in the automation industry prevent the full use of many VCS, which generally provide the most benefit when tracking text-based files.</p>

<p class="wp-block-paragraph">Luckily, <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/plc-programming/beckhoff-and-twincat-3-programming">Beckhoff TwinCAT 3 </a>stores project files and code in text-based file formats, making it a great candidate for&nbsp;<a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_sourcecontrol/index.html&amp;id=6468228250695776754" target="_blank">use with version control software</a>. This blog will discuss tips and tricks for optimizing the use of TwinCAT with version control and for development with multiple users.&nbsp;</p>

<p class="wp-block-paragraph">I&rsquo;ve also written a <a href="https://static.dmcinfo.com/latest-thinking/blog/id/10318/setting-up-a-twincat-3-project-for-version-control-a-step-by-step-guide">companion blog</a>&nbsp;with an easy, step-by-step guide to setting up a TwinCAT project for use with version control, so be sure to check that out!</p>

<p class="wp-block-paragraph"><strong>A couple quick disclaimers:</strong></p>

<p class="wp-block-paragraph">DMC leverages Git (specifically Gitlab) as a VCS to use with TwinCAT, but much of the information discussed in this blog will be applicable across many VCS.</p>

<p class="wp-block-paragraph">This blog will discuss many of the things&nbsp;DMC has learned through the years that have made our lives easier. By no means is our workflow the only workflow; one of the many beauties of version control is that it is flexible &ndash; use it however&nbsp;works best for you, and take or leave as many of our tips as you like!</p>

<p class="wp-block-paragraph">Alright, let&rsquo;s get started.</p>

<p class="wp-block-paragraph"><u><a id="Table of Contents" name="Table of Contents"></a>Table of Contents:</u></p>

<ol class="wp-block-list">
 <li><a href="#TwinCAT Project Settings">TwinCAT Project Settings</a>

 <ol class="wp-block-list">
  <li><a href="#Separating Project Components into Individual Files">Separating Project Components into Individual Files</a></li>
  <li><a href="#Keep Unrestored Links">Keep Unrestored Links</a></li>
 </ol>
 </li>
 <li><a href="#TwinCAT Version Management">TwinCAT Version Management</a>
 <ol class="wp-block-list">
  <li><a href="#Pinning Library Effective Versions">Pinning Library Effective Versions</a></li>
  <li><a href="#Standardizing Versions of TwinCAT and Add-On Modules">Standardizing Versions of TwinCAT and Add-On Modules</a></li>
 </ol>
 </li>
 <li><a href="#Tips for using Git with TwinCAT">Tips for using Git with TwinCAT</a>
 <ol class="wp-block-list">
  <li><a href="#Gitignore">Gitignore</a></li>
  <li><a href="#Merging">Merging</a>
  <ol class="wp-block-list">
   <li><a href="#General Workflow">General Workflow</a></li>
   <li><a href="#Conflicts">Conflicts</a></li>
   <li><a href="#Separating LineIDs">Separating LineIDs</a></li>
  </ol>
  </li>
 </ol>
 </li>
 <li><a href="#Other Tips">Other Tips</a></li>
 <li><a href="#Further Reference">Further Reference</a></li>
</ol>

<h2 class="wp-block-heading"><u><a id="TwinCAT Project Settings" name="TwinCAT Project Settings"></a>TwinCAT Project Settings</u></h2>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">There are some settings you can configure when setting up your TwinCAT solution that will optimize your project for use with version control. Instructions for this setup are&nbsp;detailed in my companion blog <a href="https://static.dmcinfo.com/latest-thinking/blog/id/10318/setting-up-a-twincat-3-project-for-version-control-a-step-by-step-guide">Setting up a TwinCAT 3 Project for Version Control</a>; however, I&rsquo;ve included additional details here to give background on why these settings are helpful.</p>

<p class="wp-block-paragraph"><u><a id="Separating Project Components into Individual Files" name="Separating Project Components into Individual Files"></a><strong>Separating Project Components into Individual Files</strong></u></p>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">Many TwinCAT project components, such as hardware configuration or variable mapping, default to being grouped together into project files. In the context of version control, this means changes to these files will happen often.&nbsp;</p>

<p class="wp-block-paragraph">The version control software will still track these changes, but it may be harder to follow the thread of changes to a specific component in the bulk project file. Furthermore, if every developer is making constant changes to the bulk project file, it increases the chances of merge conflicts and the headaches that may arise because of them.</p>

<p class="wp-block-paragraph">Many of these elements can be separated out into their own individual files. Much like the creation of this article, it is DMC&rsquo;s best practice to save as many elements as possible in separate files to better track and merge changes with them. Instructions for doing so can be found in <a href="https://static.dmcinfo.com/latest-thinking/blog/id/10318/setting-up-a-twincat-3-project-for-version-control-a-step-by-step-guide#Separate%20Project%20Components%20into%20Individual%20Files">Step 1 of the companion blog.</a></p>

<p class="wp-block-paragraph"><u><a id="Keep Unrestored Links" name="Keep Unrestored Links"></a><strong>Keep Unrestored Links</strong></u></p>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">TwinCAT automatically deletes variable links that are found to be invalid in the process image. This can cause problems when merging branches.</p>

<p class="wp-block-paragraph">The process image is only updated when code is recompiled after a merge, not during the merge itself; therefore, although links might be valid after compilation occurs, they can be considered invalid just after a merge and then&nbsp;get deleted.</p>

<p class="wp-block-paragraph">Instructions to prevent this from happening can be found in <a href="https://static.dmcinfo.com/latest-thinking/blog/id/10318/setting-up-a-twincat-3-project-for-version-control-a-step-by-step-guide#2.%20Keep%20Unrestored%20Links">Step 2 of the Setup Blog</a>. This step also includes a method of exporting variable mappings so that they can later be reimported if they are lost.</p>

<h2 class="wp-block-heading"><u><a id="TwinCAT Version Management" name="TwinCAT Version Management"></a>TwinCAT Version Management</u></h2>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">Beckhoff often releases new versions of TwinCAT along with various additional modules. Sometimes this causes problems when developing on a team with multiple engineers.</p>

<ul class="wp-block-list">
 <li><strong>&nbsp;Accidental Project/Component Upgrades</strong></li>
</ul>

<p class="wp-block-paragraph" style="margin-left: 40px;">Developers might work across several projects simultaneously, many of which could be on different TwinCAT versions. <a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_remote_manager/index.html&amp;id=1584127271344589360">TwinCAT Remote Manager</a> can be a great help in this situation &ndash; at least for PLC development &ndash;&nbsp; but developers with newer TwinCAT versions installed might inadvertently upgrade projects &ndash; causing problems for other developers.</p>

<ul class="wp-block-list">
 <li><strong>Library Mismatches</strong></li>
</ul>

<p class="wp-block-paragraph" style="margin-left: 40px;">Sometimes, new TwinCAT versions come with improvements to Beckhoff&rsquo;s standard libraries. Generally, projects are configured to use the most recent library version by default; however, if two engineers have different most recent versions, it can prevent one of them from going online even with otherwise identical code.</p>

<ul class="wp-block-list">
 <li><strong>Supporting Legacy Machines</strong></li>
</ul>

<p class="wp-block-paragraph" style="margin-left: 40px;">Legacy machines might use older versions of TwinCAT. In machine-down events or even less critical troubleshooting, dealing with project versioning/upgrades might eat up critical time. Some hardware may not even be compatible with upgraded versions. All around, it&rsquo;s less of a headache to just have the proper versions available to get online and solve problems with these machines quickly.</p>

<p class="wp-block-paragraph">The following are some actions you can take to ensure smooth support of many projects with varied TwinCAT versions by a team of multiple engineers.</p>

<p class="wp-block-paragraph"><u><a id="Pinning Project Version" name="Pinning Project Version"></a><strong>Pinning Project Version</strong></u></p>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">TwinCAT XAE Projects can be pinned to a certain version of TwinCAT. By doing this, you ensure that&nbsp;the Remote Manager will automatically load the proper TwinCAT build&nbsp;&nbsp;whenever you open the project (so long as that build is installed on your system).</p>

<p class="wp-block-paragraph">This will prevent you from accidentally upgrading the project because you forgot to manually select the proper build in Remote Manager. Again, very helpful for a team of multiple engineers that might have many different TwinCAT versions installed on their computers.</p>

<p class="wp-block-paragraph">Instructions for pinning project versions can be found in <a href="https://static.dmcinfo.com/latest-thinking/blog/id/10318/setting-up-a-twincat-3-project-for-version-control-a-step-by-step-guide#3.%20Pin%20the%20Project%20Version">Step 3 of the Setup Blog</a>.</p>

<p class="wp-block-paragraph"><u><a id="Pinning Library Effective Versions" name="Pinning Library Effective Versions"></a><strong>Pinning Library Effective Versions</strong></u></p>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">Libraries in TwinCAT projects are set to use the newest version available on a developer&rsquo;s computer by default. This can be a problem, however,&nbsp;if one developer downloads to a PLC with one library version but another developer has a different library as their newest library version.&nbsp;The latter developer will not be able to log into the PLC without changes. At DMC we&rsquo;ve encountered this problem several times when multiple developers are onsite supporting a line.</p>

<p class="wp-block-paragraph">The solution to this is to pin the libraries&rsquo; versions. It generally doesn&rsquo;t matter which library version is picked for each library (unless newer versions have bugfixes that are necessary), so we usually just pick the newest library version available at the time of project creation or deployment.</p>

<p class="wp-block-paragraph">This can create a new problem (especially when supporting legacy machines) if some developers do not have the proper library versions available on their computers. These versions will need to be obtained and installed.</p>

<p class="wp-block-paragraph">Instructions for obtaining, installing, and pinning library versions can be found in <a href="https://static.dmcinfo.com/latest-thinking/blog/id/10318/setting-up-a-twincat-3-project-for-version-control-a-step-by-step-guide#4.%20Pin%20Library%20Effective%20Versions">Step 4 of the Setup Blog</a>.</p>

<p class="wp-block-paragraph"><u><a id="Standardizing Versions of TwinCAT and Add-On Modules" name="Standardizing Versions of TwinCAT and Add-On Modules"></a><strong>Standardizing Versions of TwinCAT and Add-On Modules</strong></u></p>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">Each of the above recommendations for keeping items in the project pinned rely on you having the proper TwinCAT/add-on module versions available on your computer in the first place.</p>

<p class="wp-block-paragraph">You can generally determine the project version before opening it by opening the project file in a text editor. For example, the <strong>.tsproj</strong> file for the XAE project shows the project version at the top of the XML.</p>

<figure class="wp-block-image"><img decoding="async" alt="Version control and multi user development with Twincat 3" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/TwinCAT_Version_Control_Guide_1.png"  /></figure>

<p class="wp-block-paragraph">&nbsp;TE2000 TCHMI projects should also have version info in the <strong>.hmiproj</strong> file.</p>

<figure class="wp-block-image"><img decoding="async" alt="Version control and multi user development with Twincat" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/TwinCAT_Version_Control_Guide_2.png"  /></figure>

<p class="wp-block-paragraph">&nbsp;You can also determine what version of TwinCAT/add-on modules are installed through your control panel&rsquo;s apps &amp; features list.</p>

<p class="wp-block-paragraph">&nbsp;<figure class="wp-block-image"><img decoding="async" alt="Version control and multi user development with Twincat" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/TwinCAT_Version_Control_Guide_3.png"  /></figure></p>

<p class="wp-block-paragraph"><figure class="wp-block-image"><img decoding="async" alt="Version control and multi user development with Twincat" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/TwinCAT_Version_Control_Guide_4.png"  /></figure><br />
&nbsp;I would definitely recommend downloading and using the most recent version of these tools from <a href="https://www.beckhoff.com/" target="_blank">Beckhoff&rsquo;s website</a> when starting a project.</p>

<p class="wp-block-paragraph">For TwinCAT, it&rsquo;s generally not harmful to upgrade to the most recent minor revision of a build (ex: 4018.33 &#8211;&gt; 4018.58) &ndash; though there are exceptions. It is <em><strong>not</strong></em> necessarily possible to upgrade between major revisions of builds (ex: 4018.33 &#8211;&gt; 4024.22).&nbsp;</p>

<p class="wp-block-paragraph">Beckhoff offers downloads for the <a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_remote_manager/index.html&amp;id=1584127271344589360" target="_blank">TwinCAT Remote Manager</a> of the most recent versions of major revisions for exactly this use, which is very handy.</p>

<p class="wp-block-paragraph">The Remote Manager is not available for additional modules including:&nbsp;</p>

<ul class="wp-block-list">
 <li>TE2000 TCHMI Engineering</li>
 <li>TF2000 TCHMI Runtime</li>
 <li>TF6100 OPC UA</li>
 <li>TE9000 Safety Editor</li>
</ul>

<p class="wp-block-paragraph">Upgrading usually works fairly well, so long as all developers install the same engineering version of each module (if applicable) on their development computers, but there may be situations (like legacy machines or multi-user projects) where upgrading is not practical or possible. For these situations, I recommend hanging onto the installers for the different components of a project and storing them in a central server or repository the whole team can access. This way developers can grab them and install them when necessary.&nbsp;</p>

<p class="wp-block-paragraph">However, <strong>BE WARNED!</strong> You cannot install an older version of TwinCAT on a machine where a newer version is installed. If Remote Manager does not satisfy your needs, you will need to set up a new development environment with the proper build or uninstall the newer builds before you install the old one.</p>

<p class="wp-block-paragraph">It is important to enforce that all developers have the same versions of the project components installed in their development environment. This will ensure the smoothest collaboration between multiple developers.</p>

<p class="wp-block-paragraph">If you&rsquo;d like to learn more about library/TwinCAT versioning, I&rsquo;d recommend reading <a href="https://alltwincat.com/2020/11/02/handling-different-versions-of-twincat/" target="_blank">this excellent blog</a>.</p>

<h2 class="wp-block-heading"><u><a id="Tips for using Git with TwinCAT" name="Tips for using Git with TwinCAT"></a>Tips for using Git with TwinCAT</u></h2>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">DMC commonly uses <a href="https://gitforwindows.org/" target="_blank">Git</a> as a VCS with TwinCAT for the many benefits Git offers for text-based version control. The following topics are by no means a thorough discussion of using Git (there are plenty of resources you can Google for that), but I&rsquo;ve included some tips DMC has discovered along the way that might help you to use Git with TwinCAT.</p>

<p class="wp-block-paragraph">Again, I&rsquo;ll state the disclaimer: by no means are these tips the only or the best way to use Git with TwinCAT! Not even everyone here at DMC uses Git in the same way &ndash; if you&rsquo;ve got suggestions or a workflow that works very well for you, we&rsquo;d love to hear down in the comments!</p>

<p class="wp-block-paragraph"><u><a id="Gitignore" name="Gitignore"></a><strong>Gitignore</strong></u></p>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">The <a href="https://www.atlassian.com/git/tutorials/saving-changes/gitignore" target="_blank">.gitignore</a> file is used to tell Git which files it can ignore to prevent the repository from becoming bloated by tracking unnecessary changes. This can be very helpful with TwinCAT project folders which contain items like user-specific Visual Studio configuration files and builds that can be recompiled at will from the source code in the repository.</p>

<p class="wp-block-paragraph">A basic <a href="https://github.com/github/gitignore/blob/main/TwinCAT3.gitignore" target="_blank">TwinCAT 3 gitignore template</a> created by <a href="https://alltwincat.com/2019/12/02/gitignore-for-twincat/" target="_blank">Jakob Sagatowsk</a>i has been added to Github&rsquo;s <a href="https://github.com/github/gitignore" target="_blank">gitignore collection</a>. Of course, this is a basic template and may not cover everything you need to ignore in your project. Another good example, with more items included, is the gitignore for <a href="https://github.com/tcunit/TcUnit/blob/master/.gitignore" target="_blank">TcUnit</a>, by the same creator.</p>

<p class="wp-block-paragraph">The above gitignore examples include the <strong>*.tclrs</strong> file type, which holds license information. Oftentimes at DMC we store these license files in our repositories as a backup for our clients, so we opt not to include this in our gitignores. You can also remove any file types you&rsquo;d like to track as you see fit&nbsp;from your gitignore.</p>

<p class="wp-block-paragraph">After setting up a gitignore in your repository, you may still find that some temporary, user-specific, or unnecessary files are still tracked and not included in the gitignore. Feel free to add them to the gitignore file, but do so with caution. <strong>Make sure, if you&rsquo;re going to add something to the gitignore, you have a good reason for doing so and know that a file doesn&rsquo;t need to be tracked!&nbsp;</strong></p>

<p class="wp-block-paragraph">Some files in TwinCAT projects, like <strong>.xti</strong> files, might update often, even when it seems like you&rsquo;ve made no changes to the project. However, some of these files also include crucial information that you don&rsquo;t want to get lost (for example, IO links), so don&rsquo;t ignore them unless you know you can do so without losing information.</p>

<p class="wp-block-paragraph">In the event you do add a rule to your gitignore, you may find that files are still being tracked that match that rule. This is probably because these files were tracked before the change to the gitignore and need to be manually removed from tracking. Follow the instructions <a href="https://www.atlassian.com/git/tutorials/saving-changes/gitignore#ignoring-a-previously-committed" target="_blank">here</a> to do so.</p>

<p class="wp-block-paragraph"><u><a id="Merging" name="Merging"></a><strong>Merging</strong></u></p>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">The ability to merge changes from different development branches into one project is one of the greatest strengths of using a VCS with TwinCAT. Other automation platforms may or may not have their own merge tools, but TwinCAT has an advantage with its plaintext file formats. This means we can leverage Git&rsquo;s built-in merging functionalities to make our lives much easier.</p>

<p class="wp-block-paragraph">Again, this&nbsp;is not an in-depth explanation of merging (which would require a much longer article), but it is just some tips and tricks DMC has found along the way.</p>

<p class="wp-block-paragraph"><u><a id="General Workflow" name="General Workflow"></a>General Workflow</u></p>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">Beckhoff recommends <a href="https://infosys.beckhoff.com/content/1033/tc3_sourcecontrol/409513611.html?id=7562613490256544816" target="_blank">configuring TcProjectCompare</a>, TwinCAT&rsquo;s merge tool, to merge projects and deactivating automatic merging.</p>

<p class="wp-block-paragraph">In general, DMC has not found this to be necessary. Although problems can occur, we often find that most merges done directly through Git are successful, especially when splitting the project into individual files.&nbsp;</p>

<p class="wp-block-paragraph">Merges involving hardware linking or multiple developers making changes to the same aspects of project configuration can sometimes be more suspect. They might require a closer eye on the merge result. In general, it is good practice to ensure the project compiles properly after a merge and that changes to project configuration are preserved. But for typical changes to POUs, DUTs, and other code objects, the merging process is generally quite smooth.</p>

<p class="wp-block-paragraph">If you&rsquo;ve run into situations where you often find items are lost in merges or have configured TcProjectCompare as a merge tool and have some thoughts, please leave a comment below!</p>

<p class="wp-block-paragraph"><u><a id="Conflicts" name="Conflicts"></a>Conflicts</u></p>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">Inevitably&nbsp;during multi-user development, you will run into conflicts when two developers have edited the same piece of code. To manually resolve them, a mergetool is needed. Mergetools allow you to manually indicate which portions of conflicting code you&rsquo;d like to keep.&nbsp;</p>

<p class="wp-block-paragraph">DMC often uses <a href="https://code.visualstudio.com/" target="_blank">VS Code</a> as a mergetool for TwinCAT development. To configure VS Code as a mergetool, see&nbsp;<a href="https://www.roboleary.net/vscode/2020/09/15/vscode-git.html" target="_blank">these instructions</a>. Of course, you can use whichever mergetool you prefer.</p>

<p class="wp-block-paragraph">One common merge conflict that is specific to TwinCAT is conflicts in the &ldquo;LineID&rdquo; XML elements at the end of code files. POUs, DUTs, and other code objects are stored in an XML format. Sometimes, if extensive changes have been made in two separate branches to that code object, conflicts occur in these elements. Using VS Code as a mergetool, these conflicts look like this:</p>

<p class="wp-block-paragraph"><br />
<figure class="wp-block-image"><img decoding="async" alt="Version control and multi user development with Twincat" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/TwinCAT_Version_Control_Guide_5.png"  /></figure></p>

<p class="wp-block-paragraph">In this scenario, it generally doesn&rsquo;t matter which change is accepted. Accept one of the two changes, then make sure to open the project/code object in TwinCAT and compile before committing the in-progress merge.&nbsp;</p>

<p class="wp-block-paragraph">When opening the code object, TwinCAT should handle properly correcting the format of these XML elements. If there aren&rsquo;t problems in the compilation, you should be good to go.</p>

<p class="wp-block-paragraph"><u><a id="Separating LineIDs" name="Separating LineIDs"></a>Separating LineIDs</u></p>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">Alternatively, to avoid these conflicts and LineIDs appearing in source control altogether, you can activate the <a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_userinterface/4692665483.html&amp;id=">Separate LineIDs</a> option in your TwinCAT XAE environment.</p>

<p class="wp-block-paragraph">LineIDs are required for breakpoint handling and to ensure code lines can be assigned to machine code instructions. But instead of storing them with the source code (as is done by default), this option separates them into a file called&nbsp;<strong>LineIDs.dbg</strong>&nbsp;&#8211; a binary file which is rebuilt when the project is modified/saved.</p>

<figure class="wp-block-image"><img decoding="async" alt="" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/SeparateLineIDs_1-1.png"  /></figure>

<p class="wp-block-paragraph">If you paid close attention to the aforementioned gitignore templates, you might have noticed that <strong>LineIDs.dbg</strong>&nbsp;can be safely ignored by source control since it is constantly being rebuilt. Comparing the same source code file generated with this setting deactivated and with it activated, we can see that the only difference is the removal of the LineIDs section &#8211; which should prevent us from tracking changes and running into merge conflicts in this section.</p>

<figure class="wp-block-image"><img decoding="async" alt="" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/SeparateLineIDFileDifferences_1-1.png"  /></figure>

<p class="wp-block-paragraph"><strong>A word of caution</strong>&nbsp;&#8211; if you plan to use this setting with a multi-developer team, you&apos;ll need to make sure&nbsp;<strong><em>all</em></strong>&nbsp;developers have the same value for this setting in their development environments. Otherwise you may wreak havoc on your source control, with some developers constantly saving their files with separate LineIDs and others constantly saving their files with included LineIDs.</p>

<p class="wp-block-paragraph">Instructions for setting the <strong>Separate LineIDs</strong>&nbsp;setting can be found in <a href="https://static.dmcinfo.com/latest-thinking/blog/id/10318/setting-up-a-twincat-3-project-for-version-control-a-step-by-step-guide#5.%20Separating%20LineIDs">Step 5 of the Setup Blog</a>.</p>

<h2 class="wp-block-heading"><u><a id="Other Tips" name="Other Tips"></a>Other Tips</u></h2>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">It&rsquo;s generally a good idea to close the project before switching branches/performing merges. TCXAE will sometimes detect if the project has been externally modified (ex: by Git), but sometimes it won&rsquo;t. To make sure you&rsquo;re not accidentally editing the wrong project version, close the project and re-open after you&rsquo;re done performing Git operations.</p>

<h2 class="wp-block-heading"><u><a id="Further Reference" name="Further Reference"></a>Further Reference</u></h2>

<p class="wp-block-paragraph"><em><a href="#Table of Contents">Back to Table of Contents</a></em></p>

<p class="wp-block-paragraph">For more information on version control in general and with TwinCAT, please see the following links:</p>

<ul class="wp-block-list">
 <li style="margin-left: 40px;"><a href="https://static.dmcinfo.com/latest-thinking/blog/id/10318/setting-up-a-twincat-3-project-for-version-control-a-step-by-step-guide">Setting up a TwinCAT 3 Project for Version Control: A Step-by-Step Guide</a></li>
 <li style="margin-left: 40px;"><a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_sourcecontrol/index.html&amp;id=6468228250695776754" target="_blank">TwinCAT Source Control Infosys Section</a></li>
 <li style="margin-left: 40px;"><a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_remote_manager/index.html&amp;id=1584127271344589360" target="_blank">TwinCAT Remote Manager Infosys Section</a></li>
 <li style="margin-left: 40px;"><a href="https://alltwincat.com/2020/11/02/handling-different-versions-of-twincat/" target="_blank">TwinCAT Versioning Blog</a></li>
 <li style="margin-left: 40px;"><a href="https://towardsdatascience.com/version-control-101-definition-and-benefits-6fd7ad49e5f1" target="_blank">Version Control Introduction</a></li>
 <li style="margin-left: 40px;"><a href="https://gitforwindows.org/" target="_blank">Git For Windows</a></li>
 <li style="margin-left: 40px;"><a href="https://code.visualstudio.com/" target="_blank">VS Code</a></li>
 <li style="margin-left: 40px;"><a href="https://www.roboleary.net/vscode/2020/09/15/vscode-git.html" target="_blank">Configuring VS Code as a Mergetool</a></li>
 <li style="margin-left: 40px;"><a href="https://www.atlassian.com/git/tutorials/saving-changes/gitignore" target="_blank">Atlassian&rsquo;s Gitignore Tutorial</a></li>
 <li style="margin-left: 40px;"><a href="https://alltwincat.com/2019/12/02/gitignore-for-twincat/" target="_blank">TwinCAT Gitignore Blog</a></li>
 <li style="margin-left: 40px;"><a href="https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_userinterface/4692665483.html&amp;id=">TwinCAT LineIDs Infosys Page</a></li>
</ul>

<p class="wp-block-paragraph">If you&rsquo;ve got any other suggestions for tips and tricks to use TwinCAT with version control and/or multiple users, please leave them in the comments below! DMC is always committed to improving our workflow, so we&rsquo;d love to hear your thoughts.</p>

<p class="wp-block-paragraph"><strong>Learn more about DMC&apos;s <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/plc-programming/beckhoff-and-twincat-3-programming">Beckhoff and TwinCAT 3 programming </a>expertise and <a href="https://static.dmcinfo.com/contact">contact us</a> for your next project.&nbsp;</strong></p>
<p>The post <a href="https://static.dmcinfo.com/blog/18615/version-control-and-multi-user-development-with-beckhoff-twincat-3/">Version Control and Multi-user Development with Beckhoff TwinCAT 3</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
