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:
INTDINT-
LREAL(where supported) -
BYTE(limited to small values, sign-extended) -
WORDandDWORDare listed in some firmware builds, but the LAD/FBD editor disables the input pin when the source tag is declared asDWORD
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.
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.
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:
- Open the project, navigate to Program blocks → Add new block → Data block.
- Declare a tag
raw_bitsasDWORDin the new DB. - Declare a second tag
real_viewasREAL 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.) - From the LAD/FBD editor, drop a
MOVE_BLKorMOVEbox and connect your peripheral DWORD to theraw_bitsinput. - Connect
real_viewas 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
- Open the project in TIA Portal, compile, and download to the CPU.
- Right-click Program blocks → Add new watch table and name it
WT_DwordToReal. - 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
-
- Click Monitor all (glasses icon). The REAL column should show the IEEE-754 decoded value of the hex pattern in the DWORD column.
- 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.
- 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).
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.