Beckhoff ADS

Manual for Beckhoff ADS device and variable configuration for TwinCAT systems in the configuration area.

Updated 14 min read
On this page (8 sections)
  1. Overview
  2. Static Route on the PLC
  3. Device Settings
  4. Variable Settings
  5. Addressing
  6. Data Types
  7. Arrays
  8. Writing Values and Scanning

Beckhoff ADS connects to Beckhoff TwinCAT systems and reads and writes their PLC variables. It supports TwinCAT 2 and TwinCAT 3 runtimes. Variables are addressed either by their symbol path, which is the name declared in the PLC program, or by a raw IndexGroup and IndexOffset pair for areas that publish no symbol.

ADS is a routed protocol. Every request is addressed to an AmsNetId, which identifies a runtime, and the network address only says where to reach it. A device therefore carries both an AmsNetId and an IP Address, and both must be correct. The AmsNetId often looks like the IP address with .1.1 appended, but it is configured independently in TwinCAT and is not always that value. Read it from the target system rather than deriving it.

No TwinCAT installation is required on the EnvisionSCADA server. The ADS router runs inside EnvisionSCADA itself, so a plain Windows or Linux server can communicate with TwinCAT systems directly.

One additional step is required on the PLC side and cannot be performed from EnvisionSCADA: the TwinCAT system needs a static route pointing back at this server. This is described under Static Route on the PLC. Until that route exists, every request to the device fails and the device stays offline.

Each Beckhoff ADS device represents one connection to one TwinCAT runtime. Variables map individual PLC variables into the project variable space. Configure the device first, then add its variables.

Static Route on the PLC

A TwinCAT system only answers ADS requests from systems it has a route to. Add the route on the TwinCAT side before expecting the device to come online.

In TwinCAT, open the tree item SYSTEM and then Routes, and add a static route. Enter the AmsNetId of the EnvisionSCADA server and the IP address or host name it can be reached at. The local AmsNetId of this server is shown on the Beckhoff ADS Devices page and in the device dialog, so it can be read off the screen rather than calculated.

When the route is missing or wrong, the device reports that the target AmsNetId was not found. That message means the request never reached a runtime, so check the route on the PLC before checking the address of an individual variable.

The route is part of the PLC configuration and survives independently of EnvisionSCADA. Changing the IP address of the EnvisionSCADA server changes its local AmsNetId, which means the route on every PLC has to be updated to match.

Device Settings

The device settings define the connection to one TwinCAT runtime.

11 rows
SettingDescriptionExampleUnits / Format
EnableEnables or disables this device.trueBoolean
SimulationRuns the device in simulation mode. The device does not open its real connection; its variables stay available and become read and write in memory like Local variables, with a Good status, so the project can be tested without hardware. Written values are held in memory only and reset when the application restarts.falseBoolean
NameUnique name for this device. Used as the device name prefix in runtime variable references.PLC1Text
IP AddressIP address or host name of the TwinCAT system. Used to reach the target once its AmsNetId has been resolved.192.168.1.10IP Address
AmsNetIdAmsNetId of the target TwinCAT system, written as six numbers separated by dots. Read this from the target system under SYSTEM in TwinCAT. It is configured independently of the IP address.192.168.1.10.1.1Six dot-separated numbers
AmsPortADS port of the runtime to address. 851 is PLC runtime 1 on TwinCAT 3, 852 and 853 are runtimes 2 and 3, and 801 is PLC runtime 1 on TwinCAT 2.851Integer
Scan RateTime between scans of this device's variables.1000Milliseconds
TimeoutTime allowed for each individual request. Applied per request rather than across the whole scan, so a device keeps working as its variable count grows.3000Milliseconds
TemplateName of the device this device takes its variable set from. Leave empty for a device that is not based on a template. Variables created on a template device are also created on its instance devices; start their Name with the {Device} replacer, so that each instance device gets its own variable.Text
DescriptionFree text description of this device.Filling line PLCText
VerboseRaises the amount of detail written to the system log for this device. Leave at 0 for normal operation.0Integer

Variable Settings

Each variable maps one PLC variable into the project. The settings below are specific to Beckhoff ADS; the remaining settings such as scaling, historian, trending, and recipes behave as they do for every other protocol. The Add variable and Edit variable dialogs organize the settings in the tabs General, Scaling, Historian, and Gateway. The Gateway tab settings Modbus Address, OPC UA, Writeable, MQTT Publisher, Kafka Device, Kafka Remap Device, and Kafka Remap Variable are also available as table columns, which are shown with Columns as described in the Configuration Tables article.

34 rows
SettingDescriptionExampleUnits / Format
EnableEnables or disables this variable.trueBoolean
NameName of the variable in the project.Pump1_SpeedText
AssetAsset tag used to group and filter this variable.FillingLineText
TypeData type used to decode the value. TwinCAT uses the IEC 61131-3 types directly, so this matches the type declared in the PLC program.REALData type
AddressSymbol path or raw address of the PLC variable. See Addressing.MAIN.fbPump1.rSpeedText
DescriptionFree text description of this variable.Pump 1 speed feedbackText
User GroupsComma-separated list of user groups that have access to this variable at runtime.Operators,SupervisorsText
Signature RequiredRequires an electronic signature for each write to this variable from a page object, the Live Manager, the Runtime API or MCP while Part 11 compliance mode is enabled and Write variables marked Signature Required is selected under Signature Required Actions on the Parameters page. The write rights of the user and the value range are checked first, so a refused write does not open the Electronic Signature dialog. A variable created while Part 11 compliance mode is enabled starts with Signature Required selected. Writes by alarm, event and schedule actions, Python scripts and the gateways run without a signature. See the Electronic Signatures article.trueBoolean
Recipe Parameter NameExplicit name of the parameter this variable represents inside a recipe. Variables that fill the same role across different targets share the same Recipe Parameter Name, which is how values are matched on Apply and Snapshot. A variable takes part in recipes only when both Recipe Targets and Recipe Parameter Name are set.SetpointText
Recipe TargetsRecipe type name (target) this variable belongs to. Supports the {Device} placeholder, which resolves to the owning device name so one naming rule can spread a set of variables across several devices.Line1Text
Trend GroupsComma-separated list of trend group names this variable belongs to. A variable can be in several groups. The groups are the filter the Trend Analyst offers when picking variables. The names accept the {Device}, {DeviceName} and {VariableName} placeholders, so one UDT definition gives every instance its own group.Pumps,{Device}Text
UnitsEngineering unit label displayed alongside the value.rpmText
FormatDisplay format of the value on screens and in the Trend Analyst: the value of a Label or Input (unless the object uses its own Floating Point and Decimals), the value text of a Knob and a Slider, the Trend tooltip, a Data Grid Variable column, the right-click menu, Quick Trend, the current value in the Recipe Manager, variable tokens in alarm and event messages, and the Trend Analyst tooltip, summary and pen Format. An Input shows the plain value while it is being edited. 0 shows no decimals, 0.00 always shows two decimals, 0.0## shows one to three decimals and #,##0.00 adds a thousands separator, with up to 15 decimals. Values are rounded half away from zero for display only; alarms and expressions keep the full value, and so does the historian unless Round to Format is on. ReadVariable in the runtime API and MCP returns the Format beside the full value. Leave empty to show the value as received.0.00Text
Min RawMinimum raw value from the PLC, used for scaling.0Number
Max RawMaximum raw value from the PLC, used for scaling.32767Number
Min ScaledMinimum engineering value corresponding to Min Raw.0Number
Max ScaledMaximum engineering value corresponding to Max Raw.3000Number
ConverterName of a Converter defined in the Converters configuration to apply a custom read/write expression.RawToPressureText
HistorianEnables logging of this variable's values to the historian database.trueBoolean
Round to FormatStores the historian samples of this variable rounded to the decimals of its Format, as a plain number: with Format 0.00 the value 34.30487 is stored as 34.3. The deadband compares the rounded values, so with Deadband 0 a sample is written only when the rounded value changes. On a variable without scaling the Raw value is stored empty, since it equals the value. The live value, alarms, expressions and all interfaces keep the full value. Applies to new samples only; samples already stored keep their values. Requires a Format.falseBoolean
DeadbandMinimum change in value required before a new historian record is written.0.5Number
Minimum Time (s)Minimum time in seconds between historian records for this variable.0Seconds
Sample GroupName of the Sample Group that controls the historian sampling rate for this variable.Text
History SourceWhere the trends read the history of this variable: Project default (the History Source with Project default enabled on the History Sources page, or the EnvisionSCADA Historian when no source has it), EnvisionSCADA Historian (the samples recorded while Historian is on) or a History Source of the History Sources page (a query on a Database Connection or the fetch() function of a Python Module script). In the table, an empty History Source is Project default and Historian is the EnvisionSCADA Historian. Live values always come from the variable itself. Test reads the last 24 hours with the settings in the dialog. See the History Sources article.Project defaultEnum
History ReferenceWhat the History Source reads for this variable: the reference passed to fetch(), or @Variable of the History Query. When empty, the History Reference of the source is used, by default the full name of the variable; the field shows it in italics. {Name} is replaced by the full name of the variable. Browse lists the references that a Script source offers.CDT158Text
History ParametersShown for a Script source: optional key=value pairs separated by ;, added to the History Parameters of the source. A key set here replaces the same key of the source. The field shows the History Parameters of the source in italics.scale=0.1Text
Array sizeCreates an array of variables from this row. See Arrays.0Integer
Modbus AddressOptional address on the built-in Modbus TCP and Modbus RTU servers where this variable is exposed. The servers are enabled in the Gateways section of the Parameters page. Each instance device keeps its own value.%MW0See Modbus TCP Addressing
OPC UAExposes this variable as an OPC UA node. When Historize is also ticked, the Historian data of the variable is readable through OPC UA Historical Access.trueBoolean
WriteableAllows external systems to write this variable through the gateways: the OPC UA Server, the Modbus TCP and Modbus RTU servers, the MQTT publisher when Subscribe is enabled on the publisher, and Kafka when Consumer is enabled on the Kafka device. Writes from pages, actions, scripts and the API are independent of this setting.trueBoolean
MQTT PublisherName of the MQTT publisher that publishes this variable, typed or chosen with the ... button. A variable is published by one publisher, and the name must match a publisher on the MQTT Publishers page. Leave empty to keep the variable unpublished. Writes from the broker need Subscribe on the publisher and Writeable on the variable. See the MQTT Publishers article.CloudIoTText
Kafka DeviceName of the Kafka device this variable is linked to, typed or chosen with the ... button. Every value change of a linked variable is produced to the Producer Topic of the Kafka device while the device is enabled. Writes from the Consumer Topic need Consumer on the Kafka device and Writeable on the variable. Leave empty to keep the variable unlinked. See the Kafka Devices article.KafkaBroker1Text
Kafka Remap DeviceDevice name used for this variable in Kafka messages instead of the name of the device that owns the variable. Inbound messages from the Consumer Topic are matched on this name as well. Leave empty to use the device name.RemotePLC1Text
Kafka Remap VariableVariable name used for this variable in Kafka messages instead of its own name. Inbound messages from the Consumer Topic are matched on this name as well. Leave empty to use the variable name without the device name, for example Pump1_Speed for PLC1.Pump1_Speed on device PLC1.SpeedText

Addressing

The Address accepts two forms and selects between them automatically. An address containing a colon is read as IndexGroup and IndexOffset; anything else is read as a symbol path. Symbol paths cannot contain a colon, so the two forms never overlap.

A symbol path is the name of the variable as declared in the PLC program, including the program or global variable list it belongs to. This is the form most projects use, because the symbol keeps working after a recompile that moves the variable in memory. The symbol is resolved once when the device connects.

A raw address consists of an IndexGroup and an IndexOffset separated by a colon. Each part is written in decimal or with a 0x prefix for hexadecimal. This form reaches memory areas directly and works for variables that are not published as symbols, such as a PLC compiled without symbol download.

A variable whose symbol does not exist in the PLC is reported individually and the rest of the device keeps scanning, so one incorrect address does not stop the other variables. If the PLC program is later downloaded with the missing symbol added, the variable recovers on the next reconnection without a restart.

AddressFormMeaning
MAIN.fbPump1.rSpeedSymbol pathVariable rSpeed inside function block fbPump1 in program MAIN.
GVL_IO.bAlarmSymbol pathVariable bAlarm in global variable list GVL_IO.
MAIN.aLevels[3]Symbol pathElement 3 of array aLevels in program MAIN.
0x4020:12IndexGroup:IndexOffsetByte 12 of the memory area, equivalent to %MB12.
16416:12IndexGroup:IndexOffsetThe same address written in decimal.
0x4021:100IndexGroup:IndexOffsetMemory bit 100, equivalent to %MX12.4. Requires type BOOL.

Data Types

TwinCAT uses the IEC 61131-3 type system, so the type selected here matches the type declared in the PLC program. ADS transfers these types with the least significant byte first, so no byte order or word order setting is required.

A BOOL occupies a whole byte in TwinCAT and reads as true when any bit in that byte is set. A single memory bit has its own address area, IndexGroup 0x4021, where the IndexOffset is the bit number; that area requires type BOOL.

A STRING is read as text terminated by a zero byte. A PLC string declared shorter than the default length still reads correctly, because decoding stops at the terminator.

13 rows
TypeSizeRange
BOOL1 bytetrue or false
BYTE1 byte0 to 255
INT2 bytes-32768 to 32767
UINT2 bytes0 to 65535
WORD2 bytes0 to 65535
DINT4 bytes-2147483648 to 2147483647
UDINT4 bytes0 to 4294967295
DWORD4 bytes0 to 4294967295
LINT8 bytes64-bit signed integer
ULINT8 bytes64-bit unsigned integer
REAL4 bytes32-bit floating point
LREAL8 bytes64-bit floating point
STRING81 bytesText terminated by a zero byte

Arrays

Setting Array size on a variable creates that many variables from one row. The first row is the parent and the remaining rows are created automatically. The element rows are maintained through the parent: renaming, retyping, re-addressing, or resizing the parent applies to every element immediately.

How the address advances depends on which address form the parent uses. A symbol path must end in a bracket index, and each element advances that index, which matches how the array is declared in the PLC. A raw address advances the IndexOffset by the size of the data type for each element.

A STRING at a raw address cannot be turned into an array, because its declared width in the PLC is not known to the driver. Use a symbol path with a bracket index for arrays of strings.

Parent AddressTypeArray sizeElement Addresses
MAIN.aLevels[0]REAL3MAIN.aLevels[0], MAIN.aLevels[1], MAIN.aLevels[2]
0x4020:100REAL30x4020:100, 0x4020:104, 0x4020:108
0x4020:10INT40x4020:10, 0x4020:12, 0x4020:14, 0x4020:16

Writing Values and Scanning

All variables of a device are read together in a single request per scan, whichever address form they use. This keeps the load on the PLC and the network low even for devices with many variables, and it is why the scan rate can be kept short on large devices.

A value written from the graphics or from a script is sent to the PLC immediately rather than at the next scan. External systems write through the gateways when Writeable is enabled on the Gateway tab.

The Timeout applies to each individual request, so adding variables to a device does not shorten the time available for each one. A device that cannot be reached retries once per scan, so an offline PLC costs one timeout per scan rather than one per variable.

When a request fails, the effect depends on what failed. A problem with one address, such as a symbol that does not exist or a type that does not match the PLC declaration, marks only that variable and leaves the rest of the device scanning normally. A problem with the connection itself takes the device offline, marks its variables, and the driver reconnects on the next scan.

Something missing or wrong in this article? Contact us