Skip to main content

ADS Overview

The ADS route enables communication with Beckhoff TwinCAT PLCs and systems using the ADS (Automation Device Specification) protocol. It supports automatic symbol discovery, bidirectional communication, and complex data types including arrays and structures.
ADS provides direct, high-performance access to TwinCAT variables. The AutoDiscovery feature can automatically find and expose all PLC symbols as MQTT topics.

Basic Syntax

DEFINE ROUTE BeckhoffPLC WITH TYPE ADS
    ADD ADS_CONFIG
        WITH LOCAL_NET_ID "192.168.1.10.1.1"
        WITH LOCAL_ROUTE_TO_TARGET "CX_12345"
        WITH TARGET_NET_ID "192.168.1.100.1.1"
        WITH TARGET_IP "192.168.1.100"
        WITH TARGET_PORT '851'
        WITH TARGET_ROUTE_TO_LOCAL "MQTTBridge"
    ADD MAPPING ProcessData
        WITH EVERY 500 MILLISECONDS
        ADD TAG Temperature
            WITH ADDRESS "GVL_Process.rTemperature"
            WITH DATA_TYPE "REAL"
            WITH SOURCE_TOPIC "plc/temperature"

AMS Net ID Basics

ADS communication requires AMS Net IDs for both local and target systems. The AMS Net ID is typically the IP address followed by .1.1.
ComponentFormatExample
AMS Net IDx.x.x.x.y.y192.168.1.100.1.1
IP portionFirst 4 octets192.168.1.100
Node portionLast 2 octets.1.1 (usually)
You can find your TwinCAT system’s AMS Net ID in TwinCAT XAE under SYSTEMRoutes or by running adsInfo on the target.

Connection Configuration

ADS_CONFIG Parameters

LOCAL_NET_ID
string
required
Local AMS Net ID (format: x.x.x.x.x.x). This is typically your machine’s IP + .1.1.
LOCAL_ROUTE_TO_TARGET
string
required
Route name on local machine to reach the target PLC.
LOCAL_HOST_NAME
string
Local host name (optional).
TARGET_NET_ID
string
required
Target PLC’s AMS Net ID (format: x.x.x.x.x.x).
TARGET_IP
string
required
Target PLC’s IP address.
TARGET_PORT
integer
ADS port. Typically 851 for TwinCAT 3, 801 for TwinCAT 2.
TARGET_ROUTE_TO_LOCAL
string
required
Route name on target PLC to reach the local machine.
TARGET_USER
string
Username for route creation (typically Administrator).
TARGET_PASSWORD
string
Password for route creation.
TIMEOUT
integer
Connection timeout in milliseconds. Default: 5000.

Connection Example

ADD ADS_CONFIG
    WITH LOCAL_NET_ID "192.168.1.10.1.1"
    WITH LOCAL_ROUTE_TO_TARGET "PlcRoute"
    WITH TARGET_NET_ID "192.168.1.100.1.1"
    WITH TARGET_IP "192.168.1.100"
    WITH TARGET_PORT '851'
    WITH TARGET_ROUTE_TO_LOCAL "MQTTServer"
    WITH TARGET_USER "Administrator"
    WITH TARGET_PASSWORD "1"
    WITH TIMEOUT '5000'

AutoDiscovery

AutoDiscovery automatically finds all PLC symbols and exposes them as MQTT topics.

AutoDiscovery Parameters

AUTO_DISCOVERY
boolean
Enable automatic symbol discovery. Default: false.
DISCOVERY_BASE_TOPIC
string
Base MQTT topic for discovered symbols. Default: ads/discovery.
DISCOVERY_DEFAULT_QOS
integer
Default QoS for discovered symbols (0-2). Default: 0.
DISCOVERY_DEFAULT_RETAIN
boolean
Default retain flag for discovered symbols. Default: false.
DISCOVERY_DEFAULT_TRIGGER
integer
Default trigger mode:
  • 0 - OnStart (read once at connection)
  • 1 - OnChange (publish on value change)
  • 2 - Cyclic (poll at interval)
Default: 2.
DISCOVERY_DEFAULT_CYCLE
integer
Default polling cycle in milliseconds. Default: 1000.
DISCOVERY_FILTER_INCLUDES
string
Include patterns (comma-separated, * wildcard). Default: * (all symbols).
DISCOVERY_FILTER_EXCLUDES
string
Exclude patterns (comma-separated, * wildcard).
DISCOVERY_MAX_DEPTH
integer
Structure expansion depth. Default: 3.
DISCOVERY_PARALLEL_READING
boolean
Enable parallel reading for large projects. Default: false.
DISCOVERY_BATCH_SIZE
integer
Batch size for parallel reading. Default: 50.

AutoDiscovery Example

DEFINE ROUTE BeckhoffAutoDiscover WITH TYPE ADS
    ADD ADS_CONFIG
        WITH LOCAL_NET_ID "192.168.1.10.1.1"
        WITH LOCAL_ROUTE_TO_TARGET "CX_Route"
        WITH TARGET_NET_ID "192.168.1.100.1.1"
        WITH TARGET_IP "192.168.1.100"
        WITH TARGET_PORT '851'
        WITH TARGET_ROUTE_TO_LOCAL "MQTTBridge"
        WITH AUTO_DISCOVERY "true"
        WITH DISCOVERY_BASE_TOPIC "beckhoff/plc"
        WITH DISCOVERY_FILTER_INCLUDES "GVL_*"
        WITH DISCOVERY_FILTER_EXCLUDES "*_Internal*"
        WITH DISCOVERY_DEFAULT_CYCLE '500'
        WITH DISCOVERY_MAX_DEPTH '3'

TwinCAT Data Types

Data TypeTwinCAT TypeSizeDescription
BOOLBOOL1 bitBoolean value
BYTEBYTE8 bitsUnsigned 8-bit
SINTSINT8 bitsSigned 8-bit integer
USINTUSINT8 bitsUnsigned 8-bit integer
WORDWORD16 bitsUnsigned 16-bit
INTINT16 bitsSigned 16-bit integer
UINTUINT16 bitsUnsigned 16-bit integer
DWORDDWORD32 bitsUnsigned 32-bit
DINTDINT32 bitsSigned 32-bit integer
UDINTUDINT32 bitsUnsigned 32-bit integer
LWORDLWORD64 bitsUnsigned 64-bit
LINTLINT64 bitsSigned 64-bit integer
ULINTULINT64 bitsUnsigned 64-bit integer
REALREAL32 bits32-bit floating point
LREALLREAL64 bits64-bit floating point
STRINGSTRINGVariableASCII string
ARRAYARRAYVariableArray of elements
STRUCTSTRUCTVariableUser-defined structure

TAG Configuration

Symbol-Based Addressing

ADD TAG Temperature
    WITH ADDRESS "GVL_Process.rTemperature"
    WITH ADDRESS_TYPE "SYMBOL"
    WITH DATA_TYPE "REAL"
    WITH SOURCE_TOPIC "plc/temperature"

Index-Based Addressing

For direct memory access using index group and offset:
ADD TAG DirectValue
    WITH ADDRESS "16448.0"
    WITH ADDRESS_TYPE "INDEX"
    WITH DATA_TYPE "DINT"
    WITH SOURCE_TOPIC "plc/direct"

Array Handling

ARRAY_ELEMENT_TYPE
string
Array element type (required for ARRAY): BOOL, INT, REAL, STRING, STRUCT, etc.
ARRAY_SIZE
integer
Number of elements in the array.
ARRAY_ELEMENT_LENGTH
integer
Length of each element in bytes (for STRING/STRUCT arrays).
ARRAY_START_OFFSET
integer
Offset in bytes to skip before array data. Default: 0.
ARRAY_ELEMENT_HEADER_SIZE
integer
Header bytes to skip per element. Default: 0.

Structure Handling

STRUCT_FIELD_DEFINITIONS
string
Structure field definitions in format: name:offset:type:size (comma-separated).

Complete Examples

Read PLC variables using symbol names:
DEFINE ROUTE TwinCATBasic WITH TYPE ADS
    ADD ADS_CONFIG
        WITH LOCAL_NET_ID "192.168.1.10.1.1"
        WITH LOCAL_ROUTE_TO_TARGET "CX_Route"
        WITH TARGET_NET_ID "192.168.1.100.1.1"
        WITH TARGET_IP "192.168.1.100"
        WITH TARGET_PORT '851'
        WITH TARGET_ROUTE_TO_LOCAL "MQTTBridge"
    ADD MAPPING ProcessVariables
        WITH EVERY 500 MILLISECONDS
        ADD TAG Temperature
            WITH ADDRESS "GVL_Process.rTemperature"
            WITH ADDRESS_TYPE "SYMBOL"
            WITH DATA_TYPE "REAL"
            WITH SOURCE_TOPIC "plc/process/temperature"
            WITH UNIT "°C"
        ADD TAG Pressure
            WITH ADDRESS "GVL_Process.rPressure"
            WITH ADDRESS_TYPE "SYMBOL"
            WITH DATA_TYPE "REAL"
            WITH SOURCE_TOPIC "plc/process/pressure"
            WITH UNIT "bar"
        ADD TAG RunningState
            WITH ADDRESS "GVL_Process.bRunning"
            WITH ADDRESS_TYPE "SYMBOL"
            WITH DATA_TYPE "BOOL"
            WITH SOURCE_TOPIC "plc/process/running"

Route Setup Process

To establish ADS communication, routes must be configured on both sides:

1. On TwinCAT System

  1. Open TwinCAT XAE
  2. Go to SYSTEMRoutes
  3. Add a static route:
    • Route Name: Match TARGET_ROUTE_TO_LOCAL parameter
    • AMS Net ID: Your Coreflux machine’s AMS Net ID
    • Transport Type: TCP/IP
    • Address: Your Coreflux machine’s IP

2. In Coreflux Configuration

The route automatically creates a corresponding route on the local machine using the configured parameters.
Both route names (LOCAL_ROUTE_TO_TARGET and TARGET_ROUTE_TO_LOCAL) must match the actual route names configured on each system.

Troubleshooting

  • Verify AMS Net IDs are correct on both sides
  • Check routes are properly configured in TwinCAT
  • Ensure TARGET_PORT is correct (851 for TC3, 801 for TC2)
  • Verify firewall allows ADS port (typically 48898)
  • Check TARGET_USER/PASSWORD for route creation
  • Verify symbol path matches exactly (case-sensitive)
  • Check symbol exists in PLC project
  • Ensure PLC is in RUN mode
  • Use AutoDiscovery to find correct symbol names
  • Check DISCOVERY_FILTER_INCLUDES patterns
  • Verify DISCOVERY_MAX_DEPTH is sufficient
  • For large projects, enable DISCOVERY_PARALLEL_READING
  • Check PLC project is compiled and deployed
  • Ensure WRITABLE is set to “true”
  • Verify PLC variable is not constant
  • Check value is within MIN_VALUE/MAX_VALUE
  • Verify PLC is in RUN mode
  • Increase TIMEOUT value
  • Check network connectivity
  • Verify TwinCAT runtime is running
  • Reduce DISCOVERY_BATCH_SIZE if using AutoDiscovery

Next Steps