> For the complete documentation index, see [llms.txt](https://docs.cybus.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cybus.io/2-4-2/guides/machine-connectivity/plcs-industrial-controllers/connecting-a-beckhoff-twincat-system.md).

# Connecting a Beckhoff TwinCAT System

This guide shows you how to read data from a Beckhoff TwinCAT 3 PLC with the Connectware [OPC UA connector](/2-4-2/connectors/shop-floor-connectors/opc-ua/opc-ua-client.md) and map it into an ISA-95 style MQTT topic hierarchy. The connection runs through the TwinCAT OPC UA Server (TF6100), which exposes selected PLC variables as OPC UA nodes directly on the Beckhoff controller. The data collected here (a production counter, a machine running flag, and a process temperature) is the typical input for machine monitoring, OEE dashboards, and process data acquisition. In more detail, the following topics are covered:

* Understanding how the TwinCAT OPC UA Server exposes PLC symbols
* Enabling PLC symbols for OPC UA with the `OPC.UA.DA` attribute
* Activating the TwinCAT configuration and preparing security and authentication
* Identifying the NodeIds of the PLC symbols
* Creating the [service commissioning file](/2-4-2/data-flows/service-commissioning-files.md)
* Mapping the data into an ISA-95 style MQTT topic hierarchy
* Writing a setpoint back to the PLC
* Verifying data in the [Data Explorer](/2-4-2/monitoring/data-explorer.md)

This guide focuses on the TwinCAT-specific setup. For general OPC UA client topics, such as browsing the address space of a server with an OPC UA browser and identifying datapoints, see [Using Connectware as an OPC UA Client](/2-4-2/guides/system-connectivity/industry-standards-interoperability/using-connectware-as-an-opc-ua-client.md).

{% hint style="info" %}
Connectware can also communicate with Beckhoff controllers over the Automation Device Specification (ADS) protocol, which does not require a TF6100 license. See the [ADS connector](/2-4-2/connectors/shop-floor-connectors/ads.md). This guide uses OPC UA because it is the standard, vendor-neutral interface with built-in security.
{% endhint %}

A complete example file is available at the end of this guide.

## Prerequisites

To follow this guide, you will need the following:

* A running instance of Cybus Connectware.
* A Beckhoff industrial PC or embedded PC running the TwinCAT 3 runtime that is reachable over Ethernet from Connectware.
* The TwinCAT OPC UA Server (TF6100) installed and licensed on the controller. TF6100 is a separately licensed TwinCAT 3 function. The order number depends on the performance level of the controller (TF6100-0v20 up to TF6100-0v94), and a 7-day trial license can be activated in TwinCAT XAE for evaluation. For details, see the [Beckhoff TF6100 product page](https://www.beckhoff.com/en-en/products/automation/twincat/tfxxxx-twincat-3-functions/tf6xxx-connectivity/tf6100.html).
* Access to the PLC project in TwinCAT XAE, because enabling symbols for OPC UA requires changing the PLC program and activating the configuration.
* The username and password of a user that the TwinCAT OPC UA Server accepts. After the one-time initialization of the server, anonymous access is disabled and the server authenticates clients against the operating system users of the controller.
* Access to the [Admin UI](/2-4-2/access/admin-ui.md) with sufficient [user permissions](/2-4-2/access/user-management.md).
* Basic knowledge of MQTT and the Connectware [services](/2-4-2/data-flows/services.md) concept (for example, [service commissioning files](/2-4-2/data-flows/service-commissioning-files.md), [connections](/2-4-2/data-flows/service-commissioning-files/resources/cybus-connection.md), and [endpoints](/2-4-2/data-flows/service-commissioning-files/resources/cybus-endpoint.md)).

## How the TwinCAT OPC UA Server Exposes PLC Symbols

The TwinCAT OPC UA Server runs on the Beckhoff controller and makes PLC data available on the default OPC UA port 4840. It does not expose the whole PLC process image. In TwinCAT 3, the server works with a filtered symbol set: only variables that you mark with the `OPC.UA.DA` attribute in the PLC program appear in the OPC UA address space.

Each enabled variable becomes an OPC UA Variable node below the PLC runtime, which is named `PLC1` by default. The string identifier of the node is the full symbol path of the variable, including the program or global variable list name. For example, the variable `nCounter` in the program `MAIN` gets the NodeId `ns=4;s=MAIN.nCounter`, where `ns=4` is the namespace index of the `PLC1` namespace in a default server configuration.

The attribute is inherited: if you set it on a structure or function block instance, all members of that instance are enabled as well. For the full attribute reference, see [Attributes and comments in the Beckhoff Information System](https://infosys.beckhoff.com/content/1033/tf6100_tc3_opcua_server/15563857163.html).

## Preparing the TwinCAT System

### Enabling PLC Symbols for OPC UA

Add the `OPC.UA.DA` attribute to each variable that Connectware should read. The attribute is placed on the line directly before the variable declaration. This guide uses the following example declarations in the program `MAIN`:

{% code title="MAIN (structured text)" lineNumbers="true" %}

```
PROGRAM MAIN
VAR
    {attribute 'OPC.UA.DA' := '1'}
    nCounter : INT;

    {attribute 'OPC.UA.DA' := '1'}
    bMachineRunning : BOOL;

    {attribute 'OPC.UA.DA' := '1'}
    {attribute 'OPC.UA.DA.Access' := '1'}
    fTemperature : REAL;

    {attribute 'OPC.UA.DA' := '1'}
    fTemperatureSetpoint : REAL;
END_VAR
```

{% endcode %}

The attributes have the following meaning:

* `{attribute 'OPC.UA.DA' := '1'}` enables the variable for OPC UA. A value of `0` explicitly blocks a variable, which is useful to exclude single members of an enabled structure.
* `{attribute 'OPC.UA.DA.Access' := '1'}` sets the node to read-only. A value of `2` means write-only and `3` means read/write, which is the default if the attribute is not set. In this example, the temperature is read-only while the setpoint stays writable.

### Activating the TwinCAT Configuration

1. Build the PLC project in TwinCAT XAE.
2. Activate the configuration on the target controller. TwinCAT regenerates the TMC symbol file and the TwinCAT OPC UA Server refreshes its address space from it.
3. If the new symbols do not appear in the address space, restart the TwinCAT OPC UA Server on the controller.

### Configuring Security and Authentication

The TwinCAT OPC UA Server ships with security-first defaults, and the Connectware connection settings must match them:

* **Endpoints:** Since TF6100 setup version 4.3.28, the server only offers encrypted endpoints by default. The unencrypted endpoint (security policy `None`) is disabled. Among the default endpoints, `Basic256Sha256` with message security mode `SignAndEncrypt` is supported by the Connectware OPC UA connector and is used in this guide.
* **Authentication:** Since TF6100 setup version 4.4.0, the server requires a one-time initialization based on the trust-on-first-use principle. During the initialization, an operating system user of the controller is registered as the server administrator, and anonymous access is disabled. Connectware therefore authenticates with a username and password.
* **Client certificate:** When Connectware connects to an encrypted endpoint for the first time, the server rejects the unknown client certificate. Use the TwinCAT OPC UA Configurator to move the Connectware client certificate from the rejected certificates to the trusted certificates, then let Connectware reconnect.

For details on the server initialization and certificate handling, see the [TF6100 TwinCAT 3 OPC UA Server documentation in the Beckhoff Information System](https://infosys.beckhoff.com/content/1033/tf6100_tc3_opcua_server/index.html).

## Identifying the NodeIds of the PLC Symbols

This guide reads the following symbols. The symbol names are specific to the example PLC program in [Enabling PLC Symbols for OPC UA](#enabling-plc-symbols-for-opc-ua). Replace them with the variables of your own PLC project.

| Variable                    | NodeId                             | Data                         | Sampling interval |
| --------------------------- | ---------------------------------- | ---------------------------- | ----------------: |
| `MAIN.nCounter`             | `ns=4;s=MAIN.nCounter`             | Produced parts counter       |           1000 ms |
| `MAIN.bMachineRunning`      | `ns=4;s=MAIN.bMachineRunning`      | Machine running flag         |           1000 ms |
| `MAIN.fTemperature`         | `ns=4;s=MAIN.fTemperature`         | Process temperature          |           2000 ms |
| `MAIN.fTemperatureSetpoint` | `ns=4;s=MAIN.fTemperatureSetpoint` | Temperature setpoint (write) |                 — |

{% hint style="info" %}
The namespace index `ns=4` is the typical index of the `PLC1` namespace in a default TwinCAT OPC UA Server configuration. Namespace indexes are not fixed by the OPC UA specification and can differ, for example when additional namespaces are configured on the server. Verify the NodeIds with an OPC UA browser as described in [Using Connectware as an OPC UA Client](/2-4-2/guides/system-connectivity/industry-standards-interoperability/using-connectware-as-an-opc-ua-client.md) before you write the service commissioning file.
{% endhint %}

Connectware groups all endpoints with the same `publishInterval` into one OPC UA subscription on the connection. For details on how sessions, subscriptions, and monitored items relate, see [OPC UA Subscriptions](/2-4-2/connectors/shop-floor-connectors/opc-ua/opc-ua-client.md#opc-ua-subscriptions).

## Writing the Service Commissioning File

The service commissioning file contains all connection and mapping details. Do not worry about copying the snippets together into one file, the complete example file is available at the end of this guide.

### Description and Metadata

These sections contain general information about the service commissioning file. Only the metadata name is required.

{% code lineNumbers="true" %}

```yaml
description: >
  Service commissioning file that reads counter, machine state, and temperature
  data from a Beckhoff TwinCAT 3 PLC through the TwinCAT OPC UA Server (TF6100)
  and maps it into an ISA-95 style MQTT topic hierarchy (Example)

metadata:
  name: Beckhoff TwinCAT System Example
  provider: cybus
  homepage: https://www.cybus.io
  version: 1.0.0
```

{% endcode %}

### Parameters and Definitions

We define the network address and the credentials of the controller as parameters, so you can set them when you install the service. The default OPC UA port is 4840.

The MQTT topics in this guide follow an ISA-95 style equipment hierarchy (`<enterprise>/<site>/<area>/<line>/<work-cell>`). We define the prefix once in the `definitions` section and reuse it in every mapping with `!sub`.

{% code lineNumbers="true" %}

```yaml
parameters:
  plcHost:
    description: Hostname or IP address of the TwinCAT OPC UA Server
    type: string
    default: 192.168.1.100

  plcPort:
    description: Port of the TwinCAT OPC UA Server
    type: integer
    default: 4840

  opcuaUsername:
    description: Username of an operating system user accepted by the TwinCAT OPC UA Server
    type: string
    default: ''

  opcuaPassword:
    description: Password of the OPC UA user
    type: string
    default: ''

definitions:
  MQTT_TOPIC_PREFIX: enterprise/hamburg/assembly/line-1/plc-01
```

{% endcode %}

### Cybus::Connection

The connection resource establishes the OPC UA session with the TwinCAT OPC UA Server. The security options match the default endpoints of the server: security policy `Basic256Sha256` with message security mode `SignAndEncrypt`. For all connection properties, including certificate options and the `connectionStrategy` retry behavior, see [OPC UA Connection Properties](/2-4-2/connectors/shop-floor-connectors/opc-ua/opc-ua-client/opcuaconnection.md).

{% code lineNumbers="true" %}

```yaml
resources:
  twincatConnection:
    type: Cybus::Connection
    properties:
      protocol: Opcua
      targetState: connected
      connection:
        host: !ref plcHost
        port: !ref plcPort
        username: !ref opcuaUsername
        password: !ref opcuaPassword
        options:
          securityPolicy: Basic256Sha256
          messageSecurityMode: SignAndEncrypt
```

{% endcode %}

{% hint style="warning" %}
The first connection attempt fails until the Connectware client certificate is trusted on the controller. Move the certificate from the rejected certificates to the trusted certificates with the TwinCAT OPC UA Configurator, as described in [Configuring Security and Authentication](#configuring-security-and-authentication).
{% endhint %}

### Cybus::Endpoint

Each endpoint subscribes to one PLC symbol by its NodeId. The `samplingInterval` sets how often the server samples the value, and the `publishInterval` sets how often the server sends changed values to Connectware. The server only sends data when the value changes. For all endpoint properties, see [OPC UA Endpoint Properties](/2-4-2/connectors/shop-floor-connectors/opc-ua/opc-ua-client/opcuaendpoint.md).

{% code lineNumbers="true" %}

```yaml
counter:
  type: Cybus::Endpoint
  properties:
    protocol: Opcua
    connection: !ref twincatConnection
    subscribe:
      nodeId: ns=4;s=MAIN.nCounter
      samplingInterval: 1000
      publishInterval: 1000

machineRunning:
  type: Cybus::Endpoint
  properties:
    protocol: Opcua
    connection: !ref twincatConnection
    subscribe:
      nodeId: ns=4;s=MAIN.bMachineRunning
      samplingInterval: 1000
      publishInterval: 1000

temperature:
  type: Cybus::Endpoint
  properties:
    protocol: Opcua
    connection: !ref twincatConnection
    subscribe:
      nodeId: ns=4;s=MAIN.fTemperature
      samplingInterval: 2000
      publishInterval: 2000
```

{% endcode %}

### Cybus::Mapping

The mapping publishes each endpoint on a topic of the ISA-95 hierarchy.

{% code lineNumbers="true" %}

```yaml
mapping:
  type: Cybus::Mapping
  properties:
    mappings:
      - subscribe:
          endpoint: !ref counter
        publish:
          topic: !sub '${MQTT_TOPIC_PREFIX}/counter'
      - subscribe:
          endpoint: !ref machineRunning
        publish:
          topic: !sub '${MQTT_TOPIC_PREFIX}/machine/running'
      - subscribe:
          endpoint: !ref temperature
        publish:
          topic: !sub '${MQTT_TOPIC_PREFIX}/temperature'
```

{% endcode %}

With this mapping, the counter value is published on the topic `enterprise/hamburg/assembly/line-1/plc-01/counter`, and every other symbol follows the same pattern.

## Writing a Setpoint to the PLC

To write a value to the PLC, add an endpoint with the `write` operation and map an MQTT topic to it. The target variable must allow write access on the server, which is the case for `fTemperatureSetpoint` because its `OPC.UA.DA.Access` attribute is not restricted.

{% code lineNumbers="true" %}

```yaml
temperatureSetpoint:
  type: Cybus::Endpoint
  properties:
    protocol: Opcua
    connection: !ref twincatConnection
    write:
      nodeId: ns=4;s=MAIN.fTemperatureSetpoint
```

{% endcode %}

The corresponding mapping entry routes messages from the topic to the endpoint:

{% code lineNumbers="true" %}

```yaml
- subscribe:
    topic: !sub '${MQTT_TOPIC_PREFIX}/temperature/setpoint'
  publish:
    endpoint: !ref temperatureSetpoint
```

{% endcode %}

To set the temperature setpoint to 21.5, publish the following payload on the `enterprise/hamburg/assembly/line-1/plc-01/temperature/setpoint` topic:

{% code lineNumbers="true" %}

```json
{ "value": 21.5 }
```

{% endcode %}

Connectware acknowledges every write operation on the `res` topic of the endpoint. For the payload formats of write operations and method calls, see [Output Format on Writing](/2-4-2/connectors/shop-floor-connectors/opc-ua/opc-ua-client.md#output-format-on-writing).

## Installing the Service Commissioning File

1. Install the service commissioning file. See [Installing Services](/2-4-2/data-flows/services/managing/installing.md).
2. Enable the service. See [Enabling Services](/2-4-2/data-flows/services/managing/enabling.md).

**Result:** The service is enabled. Connectware connects to the TwinCAT OPC UA Server and subscribes to the configured symbols.

## Verifying the Data

Open the [Data Explorer](/2-4-2/monitoring/data-explorer.md) and subscribe to `enterprise/hamburg/assembly/line-1/plc-01/#`. Each topic carries a JSON object with the keys `timestamp` and `value`. For example, the counter:

{% code lineNumbers="true" %}

```json
{
  "timestamp": 1784194200354,
  "value": 1337
}
```

{% endcode %}

A few plausibility checks for the first readings:

* The `value` on the `counter` topic matches the counter in the online view of the PLC program in TwinCAT XAE and only increases over time.
* The `value` on the `machine/running` topic is `true` or `false` and matches the actual machine state.
* The `value` on the `temperature` topic changes when the process temperature changes. Because OPC UA only reports changed values, a perfectly constant temperature produces only the initial message.

If the connection does not reach the **Connected** state, verify the following:

* The controller is reachable from Connectware on port 4840.
* The `securityPolicy` and `messageSecurityMode` of the connection match an endpoint that is enabled on the server.
* The Connectware client certificate is trusted on the controller.
* The username and password belong to a user that the server accepts, because anonymous access is disabled after the server initialization.

If the connection is established but an endpoint stays in a failed state with a `BadNodeIdUnknown` error, the NodeId does not exist on the server. Check that the variable carries the `OPC.UA.DA` attribute, that the configuration was activated after adding the attribute, and that the namespace index matches your server configuration. An OPC UA browser shows the actual NodeId of every symbol.

## Service Commissioning File Example

{% file src="/files/2AklBMuCijw18KsMBr6O" %}

{% code title="beckhoff-twincat-example.yml" lineNumbers="true" expandable="true" %}

```yaml
---
# ----------------------------------------------------------------------------
# Service Commissioning File
# ----------------------------------------------------------------------------
# Copyright: Cybus GmbH
# Contact: support@cybus.io
# ----------------------------------------------------------------------------
# Connecting a Beckhoff TwinCAT System (Example)
# ----------------------------------------------------------------------------

description: >
  Service commissioning file that reads counter, machine state, and temperature
  data from a Beckhoff TwinCAT 3 PLC through the TwinCAT OPC UA Server (TF6100)
  and maps it into an ISA-95 style MQTT topic hierarchy (Example)

metadata:
  name: Beckhoff TwinCAT System Example
  provider: cybus
  homepage: https://www.cybus.io
  version: 1.0.0

parameters:
  plcHost:
    description: Hostname or IP address of the TwinCAT OPC UA Server
    type: string
    default: 192.168.1.100

  plcPort:
    description: Port of the TwinCAT OPC UA Server
    type: integer
    default: 4840

  opcuaUsername:
    description: Username of an operating system user accepted by the TwinCAT OPC UA Server
    type: string
    default: ''

  opcuaPassword:
    description: Password of the OPC UA user
    type: string
    default: ''

definitions:
  # ISA-95 style topic prefix: <enterprise>/<site>/<area>/<line>/<work-cell>
  MQTT_TOPIC_PREFIX: enterprise/hamburg/assembly/line-1/plc-01

resources:
  # Connection to the TwinCAT OPC UA Server (TF6100) on the controller.
  # The security options match the default endpoints of the server.
  twincatConnection:
    type: Cybus::Connection
    properties:
      protocol: Opcua
      targetState: connected
      connection:
        host: !ref plcHost
        port: !ref plcPort
        username: !ref opcuaUsername
        password: !ref opcuaPassword
        options:
          securityPolicy: Basic256Sha256
          messageSecurityMode: SignAndEncrypt

  # The NodeIds below match the example PLC program of the guide.
  # Replace them with the symbols of your own PLC project and verify
  # the namespace index with an OPC UA browser.

  # Produced parts counter (INT)
  counter:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref twincatConnection
      subscribe:
        nodeId: ns=4;s=MAIN.nCounter
        samplingInterval: 1000
        publishInterval: 1000

  # Machine running flag (BOOL)
  machineRunning:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref twincatConnection
      subscribe:
        nodeId: ns=4;s=MAIN.bMachineRunning
        samplingInterval: 1000
        publishInterval: 1000

  # Process temperature (REAL, read-only on the server)
  temperature:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref twincatConnection
      subscribe:
        nodeId: ns=4;s=MAIN.fTemperature
        samplingInterval: 2000
        publishInterval: 2000

  # Temperature setpoint (REAL, written from MQTT)
  temperatureSetpoint:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref twincatConnection
      write:
        nodeId: ns=4;s=MAIN.fTemperatureSetpoint

  mapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            endpoint: !ref counter
          publish:
            topic: !sub '${MQTT_TOPIC_PREFIX}/counter'
        - subscribe:
            endpoint: !ref machineRunning
          publish:
            topic: !sub '${MQTT_TOPIC_PREFIX}/machine/running'
        - subscribe:
            endpoint: !ref temperature
          publish:
            topic: !sub '${MQTT_TOPIC_PREFIX}/temperature'
        - subscribe:
            topic: !sub '${MQTT_TOPIC_PREFIX}/temperature/setpoint'
          publish:
            endpoint: !ref temperatureSetpoint
```

{% endcode %}

{% hint style="info" %}
Disclaimer: Beckhoff, TwinCAT, and ADS are trademarks of Beckhoff Automation GmbH & Co. KG.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.cybus.io/2-4-2/guides/machine-connectivity/plcs-industrial-controllers/connecting-a-beckhoff-twincat-system.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
