Resolving S7-1200 OPC UA LREAL Tag Visibility Problems

David Krause12 min read
OPC / OPC UASiemensTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Resolving S7-1200 OPC UA LREAL Tag Visibility Problems

1. Problem Statement

An S7-1200 user program computes a 64-bit floating point value (LREAL) by combining four 16-bit Modbus holding registers. The value is visible on the online monitor of TIA Portal in both HEX and DEC, but an external OPC UA client cannot read or subscribe to that tag. The reported symptom is one of the following:

  • The OPC UA browser does not show the tag in the address space.
  • The OPC UA browser shows the tag but the value is permanently Bad or NaN.
  • The OPC UA browser shows the tag with type Float instead of Double, and the read returns half the expected value or zero.

The failure is almost always caused by one of three issues: missing entries in the TIA Portal OPC UA server interface, wrong datatype mapping between LREAL and the OPC UA Double, or incorrect byte ordering when reassembling the four Modbus words into a 64-bit value. This article isolates each cause, documents the S7-1200-specific configuration steps, and provides reusable SCL code and a verification matrix.

2. S7-1200 OPC UA Server Prerequisites

The integrated OPC UA server is available on the S7-1200 from CPU firmware V4.4 onward. Earlier firmware revisions do not expose OPC UA and require an external PC-based server. Before troubleshooting the LREAL tag itself, verify the following baseline:

Item Required State Where to Verify
CPU firmware V4.4 or higher Online & Diagnostics → CPU → Firmware version
OPC UA activated Enabled CPU Properties → OPC UA → Server → Activate OPC UA server
OPC UA license Loaded in the PLC CPU Properties → OPC UA → Runtime licenses
Server port Default 4840 (configurable) CPU Properties → OPC UA → Server → Port
Security policy None / Basic256Sha256 / Aes128Sha256RsaOaep CPU Properties → OPC UA → Security
User authentication Anonymous or Username/Password enabled CPU Properties → OPC UA → User authentication

If the OPC UA server is not yet licensed, every read returns Bad_ServerUriInvalid or Bad_ServiceUnsupported regardless of the LREAL datatype. License the server first via the TIA Portal PLC license panel or a SIMATIC Automation Tool push, then return to the address space configuration.

3. Root Cause Matrix

Symptom Most Likely Root Cause Confirm With
Tag absent from OPC UA address space DB or tag not added to the server interface TIA Portal → CPU → OPC UA → Server interface
Tag present but read fails with Bad_TypeMismatch Client requests Float (REAL), server offers Double (LREAL) OPC UA client datatype inspector
Tag returns constant NaN or denormal Modbus word order mismatch with source device Online watch table on LREAL vs. raw registers
Tag returns half the expected value Only four bytes read instead of eight Server interface DB offset and length
Tag returns zero with no error DB optimized block access enabled with no symbolic mapping DB Properties → Attributes → Optimized block access

4. Adding the LREAL Tag to the Server Interface

The S7-1200 OPC UA server only publishes data blocks (DB) and standard tag tables (TTT) that are explicitly listed in the server interface. Procedural tags, M memory, I/O, and counters are not reachable. Configure the interface as follows:

  1. Open the CPU device configuration in TIA Portal.
  2. Select OPC UA → Server interface.
  3. Choose Define server interface by user if you want full control. Choose All DBs and tags accessible only when access control is not required and the project is small.
  4. Click Add new, browse to the DB that contains the LREAL, and select the LREAL symbol.
  5. Confirm the namespace index. The default Siemens namespace index is 1 for user data.
  6. Compile and download the hardware configuration to the CPU.
If Optimized block access is enabled on the source DB, the LREAL still appears in OPC UA by symbolic name, but the numeric NodeId carries a different encoding. Clients that hard-code NS=1;S=DBX.DBX (string NodeIds on absolute addresses) must switch to NS=1;S="DB_Name"."TagName" for optimized blocks.

5. LREAL to OPC UA Datatype Mapping

The OPC UA Companion Specification for SIMATIC maps SIMATIC S7 datatypes onto OPC UA built-in types. The LREAL row is the most commonly misread:

SIMATIC Datatype OPC UA Built-in Type Size (Bytes) IEEE 754 Layout
BOOL Boolean 1
SINT SByte 1
INT Int16 2
DINT Int32 4
LINT Int64 8
REAL Float 4 IEEE 754 single
LREAL Double 8 IEEE 754 double
STRING String 2 + N
WSTRING String (UTF-8) 4 + 2*N
BYTE / USINT Byte 1
WORD / UINT UInt16 2
DWORD / UDINT UInt32 4
LWORD / ULINT UInt64 8
DTL DateTime (extension) 8

An OPC UA client that declares the NodeId with datatype Float requests only four bytes; the server truncates the read or returns Bad_TypeMismatch. Force the client to Double and the value resolves immediately.

6. Modbus Register Byte Order and LREAL Reassembly

An LREAL is eight bytes (64 bits) laid out as Sign (1) — Exponent (11) — Mantissa (52). Modbus holding registers are 16-bit words transmitted big-endian (most significant byte first) within each register, but the order of the four registers depends on the source instrument. The two common conventions are:

Convention Register Order on the Wire Examples
Big-endian word order (ABCD) W0 = MSW, W3 = LSW IEEE 754 standard, most power meters
Little-endian word order (CDAB) W3 = MSW, W0 = LSW Some Modbus TCP energy meters, Wago, Beckhoff
Byte-swapped (BADC / DCBA) Mixed Older Modbus RTU devices

The S7-1200 stores LREAL in little-endian memory order: byte 0 of the value is the least significant byte of the mantissa, byte 7 holds the sign and the upper exponent bits. Therefore the byte that arrives as the MSB of the IEEE 754 value must land at byte index 7 of the LREAL in the PLC.

6.1 Reference Conversion Formula

If the source transmits IEEE 754 big-endian across four registers (W0 = MSW … W3 = LSW), the byte mapping is:

Byte[7] = HiByte(W0)   // sign + upper exponent
Byte[6] = LoByte(W0)   // lower exponent
Byte[5] = HiByte(W1)   // mantissa bits 51..48
Byte[4] = LoByte(W1)
Byte[3] = HiByte(W2)
Byte[2] = LoByte(W2)
Byte[1] = HiByte(W3)
Byte[0] = LoByte(W3)   // mantissa LSB

If the source uses CDAB word order, swap the role of the registers first:

tmp0 := Word3;  // becomes MSW
tmp1 := Word2;
tmp2 := Word1;
tmp3 := Word0;  // becomes LSW
// then apply the same byte layout as above

6.2 SCL Function Block: ModbusWordsToLReal

The following SCL block accepts four 16-bit registers and produces an LREAL, exposing both word orders as input selectors. Use this as a starting reference and adapt it to your application.

FUNCTION_BLOCK "FB_ModbusWordsToLReal"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT
      Word0 : WORD;
      Word1 : WORD;
      Word2 : WORD;
      Word3 : WORD;
      WordOrder : INT;       // 0 = ABCD, 1 = CDAB, 2 = BADC, 3 = DCBA
   END_VAR

   VAR_OUTPUT
      Value : LREAL;
      Valid : BOOL;
   END_VAR

   VAR_TEMP
      w0, w1, w2, w3 : WORD;
      bytes AT Value : ARRAY[0..7] OF BYTE;
   END_VAR

BEGIN
    // Step 1 - normalize word order
    CASE WordOrder OF
        0:  // ABCD - IEEE 754 standard
            w0 := Word0; w1 := Word1; w2 := Word2; w3 := Word3;
        1:  // CDAB - reverse word order
            w0 := Word3; w1 := Word2; w2 := Word1; w3 := Word0;
        2:  // BADC - byte swap within each word
            w0 := WORD_BL swap(Word0) etc...
        ELSE
            w0 := Word0; w1 := Word1; w2 := Word2; w3 := Word3;
    END_CASE;

    // Step 2 - place bytes big-endian into LREAL little-endian memory
    bytes[7] := DWORD_TO_BYTE(SHR(WORD_TO_DWORD(w0), 8));
    bytes[6] := DWORD_TO_BYTE(WORD_TO_DWORD(w0) AND 16#00FF);
    bytes[5] := DWORD_TO_BYTE(SHR(WORD_TO_DWORD(w1), 8));
    bytes[4] := DWORD_TO_BYTE(WORD_TO_DWORD(w1) AND 16#00FF);
    bytes[3] := DWORD_TO_BYTE(SHR(WORD_TO_DWORD(w2), 8));
    bytes[2] := DWORD_TO_BYTE(WORD_TO_DWORD(w2) AND 16#00FF);
    bytes[1] := DWORD_TO_BYTE(SHR(WORD_TO_DWORD(w3), 8));
    bytes[0] := DWORD_TO_BYTE(WORD_TO_DWORD(w3) AND 16#00FF);

    // Step 3 - validate IEEE 754 range
    IF (Value <> Value) THEN        // NaN test
        Valid := FALSE;
    ELSIF (Value = 0.0) THEN
        Valid := TRUE;
    ELSE
        Valid := (Value > 1.0E-300) AND (Value < 1.0E+300);
    END_IF;
END_FUNCTION_BLOCK
The AT overlay bytes AT Value : ARRAY[0..7] OF BYTE requires Optimized block access disabled on the parent block. For optimized blocks, use DWORD_TO_BYTE and SHR explicitly as shown above. Always mark Value with Retain only if the source instrument requires persistence across power cycles; otherwise leave it non-retain to avoid stale data on restart.

7. TIA Portal Server Interface Modeling

The S7-1200 server interface uses the symbolic name of the DB element as the OPC UA browse path. Modeling errors typically show up as missing nodes or nodes with the wrong datatype. Follow this checklist when the LREAL still does not appear:

  1. Confirm the DB containing the LREAL has Accessible from OPC UA ticked in DB properties.
  2. Confirm the DB has been downloaded to the CPU. A new DB added offline but not compiled into the project does not exist on the controller.
  3. If you use Define server interface by user, verify the LREAL is on the list and not greyed out.
  4. Confirm the namespace index. The default for user data is index 1, system diagnostics use 0.
  5. Re-read the address space using the OPC UA client. Some clients cache the address space and require a manual refresh.

8. OPC UA Client Subscription

The client must request the tag as Double regardless of how it is named in the project. The following sample uses an OPC UA browse path expression with the symbolic name:

NodeId format (string):  NS=1;S="ModbusData"."Float64Value"
NodeId format (numeric): NS=1;S=<DBNumber>.<OffsetString>     // only for non-optimized DBs

Subscription parameters:

Parameter Recommended Value Notes
SamplingInterval 500 ms S7-1200 cannot sustain below 100 ms for many tags
PublishingInterval 1000 ms Twice the sampling interval is typical
QueueSize 10 Reduce if network bandwidth is constrained
DiscardOldest true Recommended for visualization clients
MonitoringMode Reporting Sampling is implicit; Reporting sends only changes
DataChangeFilter Deadband 0.0 for double Deadband only effective for numeric types

9. Verification Steps

  1. Open an OPC UA client (e.g., UA Expert) and connect to opc.tcp://<CPU_IP>:4840.
  2. Browse the address space. Confirm Objects → Server → <DB name> → <LREAL symbol> exists.
  3. Inspect the Node attributes. Confirm DataType resolves to Double.
  4. Drag the node into the subscription view and verify the value updates.
  5. Cross-check the value against the online watch table in TIA Portal.
  6. Toggle the LREAL inside the PLC (e.g., assign 1.0E+10) and verify the client receives the new value within one publishing interval.

If the value differs by a factor of 2 or appears truncated, the client is requesting 32 bits. If the value is NaN or denormal, the byte order is wrong. If the value never updates, the OPC UA server interface list is stale or the DB has not been re-downloaded.

10. Troubleshooting Matrix

Test Expected Outcome If Failed
ping <CPU_IP> Reply < 5 ms Check subnet, PROFINET cable, firewall
Open opc.tcp://<CPU_IP>:4840 in client Connection established OPC UA disabled, license missing, wrong port
Browse root Objects and Types folders visible Wrong security policy, server certificate rejected
Browse to LREAL Node visible with DataType Double Tag not in server interface, optimized block access issue
Subscribe to LREAL Value matches TIA online monitor Byte order mismatch, datatype mismatch
Read with DataChangeFilter Notification within 1 s of change Publishing interval too long, queue overflow

11. Field-Proven Pitfalls

  • Optimized block access versus absolute addressing. When optimized, the LREAL still has a symbolic NodeId, but the numeric representation changes after each compile. External clients that cached the numeric NodeId will fail after every recompile.
  • Endian mismatch. Two identical brands of energy meters can use different word orders. Document the convention in the device datasheet and verify with a known reference value such as 10.0 (IEEE 754 = 0x4024000000000000).
  • DB version mismatch. If the online DB differs from the offline DB, the LREAL symbol may not be resolvable. Compile and download the software component only — not just the hardware.
  • Security policy on the client. S7-1200 firmware V4.4 supports None, Basic128Rsa15, Basic256, Basic256Sha256. Some clients default to a policy the CPU does not offer; negotiate to None first to isolate the security layer from the data layer.
  • High sampling rates. The S7-1200 OPC UA server CPU load increases with each tag and each subscription. Avoid sub-100 ms sampling on more than 50 tags or the connection will drop with Bad_Timeout.
  • String encoding. WSTRING maps to UTF-8, not UCS-2. Clients that decode as UTF-16 will see garbled characters. This is rarely relevant for LREAL but documents that datatype mapping is critical across the board.

12. Related Manuals and References

For additional depth, consult the SIMATIC S7-1200 programmable controller system manual, the S7-1200 OPC UA function manual, and the TIA Portal help system entry “Modeling the OPC UA Server Interface”. The OPC Foundation Companion Specification for SIMATIC and the OPC UA Part 6 standard define the datatype mapping table in detail. The Inductive Automation documentation provides a complementary view of how OPC tag browsing works on the client side, although the S7-1200 is the server of record in this scenario.

FAQ

Why does my OPC UA client see the LREAL as Float instead of Double?

The client is requesting the tag as 32-bit Float. In TIA Portal the SIMATIC LREAL maps to the OPC UA built-in type Double (IEEE 754 64-bit). Reconfigure the client subscription to datatype Double; otherwise the server returns Bad_TypeMismatch or truncates to the lower four bytes.

The LREAL is visible in the OPC UA browser but the value is always NaN. What is wrong?

Byte order is mismatched between the four source Modbus registers and the LREAL memory layout. The S7-1200 stores LREAL in little-endian byte order while Modbus typically transmits 16-bit registers big-endian. Use the FB_ModbusWordsToLReal block above with the correct WordOrder selector and verify against a known reference such as 10.0 (IEEE 754 0x4024000000000000).

How do I publish a DB tag to the S7-1200 OPC UA server?

Open CPU Properties → OPC UA → Server interface in TIA Portal. Choose either "Define server interface by user" or "All DBs and tags accessible". Add the DB element to the user-defined list, compile the project, and download the software to the CPU. Only tags in this list appear in the OPC UA address space.

Which S7-1200 firmware version is required for OPC UA?

Firmware V4.4 or higher is required to run the integrated OPC UA server on the S7-1200. A separate runtime license must be loaded in the CPU properties before the server accepts client connections on port 4840.

Why does the OPC UA subscription drop with Bad_Timeout on a heavily loaded CPU?

The S7-1200 OPC UA server executes on the same CPU as the user program and cannot sustain more than 50 monitored tags at sub-100 ms sampling intervals. Increase the publishing interval to 1000 ms, raise the QueueSize, or reduce the number of subscribed tags to relieve CPU load.

Back to blog