DWORD to REAL Conversion in S7-1200: AT Overlay, SCL, and LAD

David Krause11 min read
S7-1200SiemensTutorial / How-to
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

1. Overview: The DWORD-to-REAL Conversion Challenge in S7-1200

The S7-1200 instruction set exposes an explicit CONV block for converting between elementary data types, but the ladder editor historically blocks DWORD → REAL as a direct operation. In TIA Portal V11 SP2, the input operand of the CONV instruction does not accept a DWORD variable, and forcing it through the SCL source view typically returns a compiler error such as "Invalid data type for conversion" or "Type mismatch in expression". Engineers regularly encounter this when reading 32-bit raw registers from field devices, Modbus gateways, or PROFIBUS/PROFINET slaves that deliver floating-point measurements as raw bit patterns.

The root cause is semantic: a DWORD is an unsigned 32-bit integer, while REAL is a single-precision IEEE-754 value with sign, exponent, and mantissa fields. Direct integer-to-float conversion is meaningful, but bit-pattern reinterpretation requires the CPU to view the same 32 bits through a different lens. The S7-1200 does not provide a primitive cast for this, so the engineer must build a small piece of glue logic. This article documents four field-proven methods (AT overlay, VARIANT interpretation, two-step DINT intermediary, and an FB/FC wrapper) and shows how to verify each one with a watch table.

2. Prerequisites and Environment

Item Requirement
Controller SIMATIC S7-1200 CPU (any firmware V4.x or later)
Engineering tool SIMATIC TIA Portal V13 SP1 or later (V15.1+ recommended for AT overlay parity with S7-1500)
Programming languages LAD and SCL (both must be enabled in the project tree)
Hardware identifier A defined DB, M-area, or I/O address of type DWORD (e.g., %MD1058)
Reference standard IEEE Std 754-2008 (binary32, single precision)

Before any conversion logic is written, confirm the source data layout. If the DWORD originates from a Modbus holding register pair (function codes 03/04), the byte order may be big-endian (Modbus native) or little-endian (S7 native). The AT-overlay approach presented below assumes the S7 byte order; for word-swapped values, apply SWAP first.

3. Why the Built-in CONV Block Fails

The standard CONV instruction in TIA Portal accepts the following IN types for conversion to REAL:

  • INT
  • DINT
  • LREAL (where supported)
  • BYTE (limited to small values, sign-extended)
  • WORD and DWORD are listed in some firmware builds, but the LAD/FBD editor disables the input pin when the source tag is declared as DWORD

This is documented in the TIA Portal help: the instruction allows conversion from a numeric type to REAL, and the conversion must be value-preserving in the integer sense (e.g., divide by 10, 100, or 1000 for scaled values). A bit-pattern reinterpretation, where the binary representation of a 32-bit float is treated as an integer, is not in the CONV specification. SCL does not relax this restriction by default.

If the original poster sees "wrong converted value" while compilation succeeds, the most common cause is that the destination tag was declared as REAL while the source is DWORD. The compiler is silently coercing the integer into a real, which is a numerical conversion, not a bit-level reinterpretation. This produces a totally different number from the IEEE-754 value stored in the same 32 bits.

4. Understanding the IEEE-754 Bit Layout

A 32-bit single-precision float stores the value as three fields packed into one DWORD:

Bit position Field Width Bias / range
31 Sign (S) 1 bit 0 = positive, 1 = negative
30 .. 23 Exponent (E) 8 bits Biased by 127, range -126 .. +127
22 .. 0 Mantissa (M) 23 bits Fractional part with implicit leading 1

The numeric value is computed as:

(-1)^S × 2^(E-127) × (1.M)

For example, the hex pattern 0x40490FDB is the IEEE-754 representation of π (3.14159274…). Reinterpreting that same 32-bit pattern as an unsigned integer gives 1,076,794,331. Treating it as a signed integer gives -1,418,172,965. Only by passing the raw bits through the floating-point unit do you recover 3.14159.

For a deeper drill-down on the encoding, the IEEE-754 converter at h-schmidt.net IEEE-754 Floating Point Converter provides a bidirectional hex/float calculator that is useful for generating test vectors.

5. Method 1: AT Overlay in SCL (Recommended)

The cleanest, type-safe approach is the AT operator. AT lets a single memory area be viewed simultaneously through two different data type lenses. Both views occupy the same bytes; the compiler does not move any data, it only changes the interpretation. This is identical in spirit to the UNION/DUT technique used in Schneider Electric's Modicon M340 and documented in Schneider Electric FAQ000219304.

Create a function block with the following interface and body:

FUNCTION_BLOCK "DwordToReal"
VAR
    RawBits    : DWORD;        // Source: same 32 bits
    RealView   : REAL AT RawBits; // Overlay, no copy
END_VAR

BEGIN
    // No code body required.
    // "RealView" is automatically a REAL interpretation of "RawBits".
END_FUNCTION_BLOCK

Usage from any OB, FB, or FC:

"DB_DwordToReal".RawBits := %MD1058;     // DWORD input from periphery
myFloat := "DB_DwordToReal".RealView;     // REAL output, IEEE-754 value

The assignment is a pointer alias; no MOVE and no extra cycle are needed. This compiles in TIA Portal V13 SP1 onward for the S7-1200 and behaves identically on the S7-1500. The S7-300/400 does not support AT, so the alternative methods below are required for legacy CPUs.

Confirm that "Strict type checking" is enabled in the project properties. With strict mode off, TIA Portal will allow a hidden implicit conversion of DWORD to REAL as a numeric coercion, which masks the actual problem. Always enable IEC check in the compiler options.

6. Method 2: VARIANT Interpretation in SCL

When you cannot change the data type of an existing tag (for example, a flag from a peripheral driver block), use the VARIANT input and reinterpret it as REAL with a bytewise copy through an AT overlay on a temporary:

FUNCTION "ConvDwordToReal" : REAL
VAR_INPUT
    pIn : VARIANT;
END_VAR
VAR_TEMP
    dwBuf : DWORD;
    rView : REAL AT dwBuf;
END_VAR

BEGIN
    dwBuf := DWORD#16#0;
    IF TypeOf(pIn) = DWORD THEN
        dwBuf := pIn;                  // raw bit copy
        // Implicit cast through AT is preserved across assignments
        ConvDwordToReal := rView;
    ELSE
        ConvDwordToReal := 0.0;        // safety return
    END_IF;
END_FUNCTION

Call example:

myFloat := "ConvDwordToReal"(pIn := %MD1058);

This pattern is especially useful when wrapping a vendor-supplied data block whose tag is locked to DWORD by their library.

7. Method 3: LAD Workaround with MOVE and Type Cast

Although the LAD editor disallows DWORD on the input of the CONV to REAL, you can still accomplish the same reinterpretation by using a temporary tag declared as a REAL AT-overlay at a DWORD location, then using MOVE (or just an unconnected contact-coil assignment) to bring the raw bits in. In TIA Portal V14+ this can be done entirely from the LAD editor without writing SCL:

  1. Open the project, navigate to Program blocks → Add new block → Data block.
  2. Declare a tag raw_bits as DWORD in the new DB.
  3. Declare a second tag real_view as REAL AT "raw_bits". (In V14 you can type the AT clause directly into the declaration table; in V13 you may need to use SCL for that one line.)
  4. From the LAD/FBD editor, drop a MOVE_BLK or MOVE box and connect your peripheral DWORD to the raw_bits input.
  5. Connect real_view as the source for any REAL operation downstream.

This is the LAD-friendly equivalent of the SCL pattern and is what most field engineers settle on because it requires the least code editing.

8. Method 4: Two-Step Conversion (DWORD→DINT→REAL) with Caveats

A widely seen shortcut is to first convert the DWORD to DINT and then to REAL. The compiler accepts this with IEC checking enabled, but the result is not a bit-level reinterpretation. Instead, the integer value is treated as a number and then converted to its floating-point equivalent.

// 0x40490FDB as DINT = 1,076,794,331
// 1,076,794,331 as REAL = 1.076794331E+09
iTmp := DINT_TO_DINT( DWORD_TO_DINT(%MD1058) );  // numeric cast
rTmp := DINT_TO_REAL(iTmp);                       // 1.07679e9, not π

Use this method only when the source truly is a 32-bit unsigned integer count or scaled value and you want the float equivalent of that count. Do not use it to recover an IEEE-754 bit pattern. The two interpretations are mathematically unrelated.

9. Common Compiler Errors and Fixes

Error message Cause Fix
"Invalid data type at input IN of CONV" Source tag declared as REAL instead of DWORD Change tag to DWORD or add an AT overlay
"Type mismatch in expression" (SCL) Mixing DWORD and REAL in arithmetic Use AT overlay or pass through a temporary REAL
"Input side DWORD not allowed" (LAD) Editor limit in TIA V11 SP2 Upgrade to V14+ or move the conversion to SCL
"Function not allowed in this language" Used DINT_TO_REAL in SCL with IEC strict mode Enable IEC check, but the result is still numeric, not bit-level
Output value wildly wrong but compiles Numeric cast rather than bit reinterpretation Apply AT overlay (Method 1)

10. Building a Reusable FC/FB

For projects that perform many such conversions (typical for Modbus bridges with 30+ scaled measurements), wrap Method 1 in a parameterized FB:

FUNCTION_BLOCK "FB_DwordToRealBank"
VAR_INPUT
    pRaw  : POINTER TO DWORD;   // optional, or use VARIANT
    nCnt  : INT;
END_VAR
VAR_OUTPUT
    Values : ARRAY[1..64] OF REAL;  // AT-views declared below
END_VAR
VAR_TEMP
    i : INT;
    pV : POINTER TO REAL;
END_VAR

BEGIN
    pV := pRaw;        // assume same byte count
    FOR i := 0 TO nCnt - 1 DO
        Values[i + 1] := pV^;
        pV := pV + 1;  // advance by 4 bytes (REAL width)
    END_FOR;
END_FUNCTION_BLOCK

Call it once per scan with the start address of the DWORD array and the element count. This pattern minimizes PLC cycle time and keeps the data model clean.

11. Verification and Watch Table Procedure

  1. Open the project in TIA Portal, compile, and download to the CPU.
  2. Right-click Program blocks → Add new watch table and name it WT_DwordToReal.
  3. Add the following tags to the watch table:
    • %MD1058 (DWORD) – the source bits
    • "DB_DwordToReal".RawBits (DWORD) – overlay source
    • "DB_DwordToReal".RealView (REAL) – interpreted float
  4. Click Monitor all (glasses icon). The REAL column should show the IEEE-754 decoded value of the hex pattern in the DWORD column.
  5. Cross-check with the converter at h-schmidt.net: enter the hex value from the DWORD column and confirm the decimal value matches the REAL column.
  6. Force the DWORD to known test vectors: 16#40490FDB (π), 16#3F800000 (1.0), 16#BF800000 (-1.0), 16#7F7FFFFF (max single), 16#00000000 (0.0).
If the REAL column reads 0.0 when the DWORD is non-zero, you are probably still in numeric-conversion mode. Re-check that the source tag is DWORD and that the destination uses an AT overlay rather than a separate REAL tag.

12. Cross-Platform Notes: S7-300/400, S7-1500, and Modicon M340

Platform Method supported Notes
S7-1200 (V4.x) AT overlay (V13 SP1+), VARIANT, two-step with caution Primary target of this article
S7-1500 AT overlay, VARIANT, REAL AT declared DB tag Same syntax, no limitations
S7-300/400 (STEP 7 V5.x) No AT in classic STEP 7; use ANY pointer + manual byte copy, or FC105/FC106 workarounds Build a small STL block that loads four bytes into MD and reads it back as REAL
Modicon M340 / M580 (EcoStruxure Control Expert) DUT with UNION of DWORD and REAL; documented in Schneider FAQ000219304 Conceptually identical to AT overlay

For S7-300/400, the equivalent STL snippet is:

AUF   DB_DwordToReal
L     DBD   0          // load the DWORD area
T     MD    100        // store as REAL bit pattern (alias)
L     MD    100        // reload
T     DBD   4          // write into REAL destination

Because both the source and destination are 32 bits at the same memory address, the load/store pair effectively reinterprets the bits without arithmetic. This is the legacy equivalent of AT.

13. FAQ

Why does CONV from DWORD to REAL fail in LAD on S7-1200 V11 SP2?

The LAD/FBD editor in TIA Portal V11 SP2 does not expose a DWORD input on the CONV instruction for the REAL output. The compiler treats the operation as numeric, not as a bit-pattern reinterpretation, and refuses it. The fix is to use the AT-overlay technique (Method 1) in SCL or to upgrade to TIA Portal V14+ where the editor accepts the declaration.

Is DWORD_TO_REAL the same as DINT_TO_REAL?

No. DINT_TO_REAL treats the source as a signed integer and converts its numeric value to the nearest float (e.g., 1,076,794,331 → 1.07679e9). DWORD_TO_REAL, in the IEEE-754 sense, reinterprets the 32 raw bits through the floating-point unit (1,076,794,331 → 3.14159). Use AT overlay for the second case.

How do I verify the conversion in a watch table?

Add the DWORD source tag and the AT-overlay REAL tag to the same watch table, enable monitoring, and compare the REAL display to the hex value in the DWORD using a reference tool such as the IEEE-754 Floating Point Converter. The values must match for test vectors such as 0x3F800000 (1.0) and 0x40490FDB (π).

Can I do this without writing any SCL?

Yes, in TIA Portal V14 or later. Declare a DB tag of type DWORD, add a second tag of type REAL with an AT clause pointing to the first tag, then drop a MOVE box in LAD to populate the DWORD from the peripheral. The REAL view is automatic and requires no extra code.

Does this work for Modbus big-endian data?

Only after you swap the byte or word order. Modbus delivers the high byte first; the S7-1200 is little-endian, so apply SWAP (byte swap) or two consecutive WORD swaps before the AT overlay. The AT technique is byte-order agnostic at the bit-pattern level; the byte order must still match the device's IEEE-754 emission.

Back to blog