Resolving TIA Portal Hex Display DW#16#7F800000 in S7-1200 Function Blocks
When an S7-1200 or S7-1500 function block built in TIA Portal V15.1 or later suddenly returns a value displayed as DW#16#7F800000 in online monitoring, the display format is rarely the real defect. The hex pattern 0x7F800000 is the IEEE 754 single-precision bit pattern for positive infinity (+∞), and it indicates a real numerical overflow (or division-by-zero condition) inside the averaging block. The hex view is simply the way the CPU exposes the corrupted bit pattern when the tag's declared data type is DWORD or when the monitor cell is forced to hexadecimal representation. Treat the symptom as a numerical fault first, and a display fault second.
1. Symptom Description
The reported FB computes a moving average over a fixed-size array in SCL (Structured Control Language):
#TempAverage := 0.0;
FOR #TempCounter := 0 TO #ArraySize DO
#TempAverage := #TempAverage + #StatValues[#TempCounter];
END_FOR;
#TempAverage := #TempAverage / (#ArraySize + 1);
#Average := #TempAverage;
With a single-precision REAL (32-bit) declared for #TempAverage and #Average, online monitoring shows the result as #Average = DW#16#7F800000. Switching the watch table column to Decimal still shows the raw DWORD value. Switching to Float shows +Inf. This is the diagnostic fingerprint of IEEE 754 positive infinity being stored in a 32-bit word and rendered as a hex literal because the declared type is DWORD.
2. Why 0x7F800000 Means +Infinity (IEEE 754 Bit Layout)
IEEE 754 single-precision (REAL in S7-1200 / S7-1500) lays out 32 bits as sign, biased exponent, and fraction. The pattern 0x7F800000 decodes as follows:
| Bit Range | Field | Value at DW#16#7F800000 | Meaning |
|---|---|---|---|
| 31 | Sign | 0 | Positive |
| 30..23 | Biased exponent | 1111 11112 = 255 | All-ones (reserved for ∞ / NaN) |
| 22..0 | Fraction (mantissa) | 0 | Zero mantissa = infinity, not NaN |
An all-ones exponent with a zero mantissa encodes +∞. With the sign bit set (0xFF800000) it is −∞. With a non-zero mantissa and an all-ones exponent, the result is NaN (Not a Number) - the bit pattern of NaN is sign-dependent and includes 0x7FC00000, 0xFFC00000, and many other values.
Hexadecimal is the engineer's preferred shorthand for IEEE 754 special values because each hex digit maps to exactly four binary bits, so a 32-bit pattern is read as eight characters instead of thirty-two. This is the underlying reason the same bits surface in the watch table as DW#16#7F800000 rather than as +Inf or 2139062784.
3. How TIA Portal Selects the Online Display Format
STEP 7 (TIA Portal) chooses the watch-table representation based on the tag's declared data type, not the bits physically stored in the register. The same 32 bits can render in three different ways depending on the declaration:
| Declared Data Type | Default Monitor Format | Bit Pattern 0x7F800000 Renders As |
|---|---|---|
| BOOL | 0 / 1 | n/a (bit truncation) |
| INT / DINT / LINT | Decimal signed | 2,139,062,784 (large positive decimal) |
| UINT / UDINT / ULINT | Decimal unsigned | 2,139,062,784 |
| WORD / DWORD / LWORD | Hexadecimal | DW#16#7F800000 (or W#16#8000 for the high half) |
| BYTE | Hex / B#16# | B#16#0 or decimal 0 |
| REAL | Floating point | +∞ |
| LREAL | Floating point, 64-bit | Invalid (pattern is 32-bit; shows 1.26E+313 as the LREAL interpretation of the 64-bit value zero-extended) |
| S5TIME / TIME / DATE / DTL | Time format | Display error or T#0ms (interpreted as 0) |
| CHAR / WCHAR / STRING | Character / string | Non-printable (0x7F is DEL, the rest are NULs) |
The compiler enforces type-safe assignment in SCL, so a direct DWORD assignment from a REAL source is not allowed in strictly-typed blocks. The bit pattern only appears in a DWORD when the variable was explicitly declared as DWORD and was assigned either a direct hex literal, the output of a non-SCL source (e.g. a library block or a MOVE), or a hand-coded DWORD accumulator.
4. Root Cause: Arithmetic Overflow in the Averaging Loop
In a summing loop, +∞ is produced whenever a partial sum exceeds the REAL upper limit of approximately 3.4028235E+38 (largest finite single-precision value) or whenever the divisor is zero. Common triggers in the averaging FB include:
-
Unclamped input values. The block accepts
#Valueas a REAL but does not clamp to a safe engineering range. If the upstream sensor returns the fullscale of an INT (32767) interpreted as a pressure or flow, repeated array writes push the running sum past 3.4E+38 in just a few hundred iterations. - Two large values in a single add. A single addition of two REALs both near 2.0E+38 produces +∞ immediately because the mathematical result exceeds the largest finite single-precision value. The IEC 61131-3 standard requires the runtime to round to +∞ in this case.
-
Divisor collapse. If
#ArraySizeis declared asSINTand is set to -1, the expression#ArraySize + 1is 0 and the divide triggers IEEE 754 division-by-zero, which is defined to produce +∞ for a positive numerator (and NaN for 0/0). The IEC 61131-3 standard, which SCL follows, mandates this IEEE 754 behaviour. -
Static area not initialized. On the first scan the static
#StatValuesarray may contain uninitialized REAL data. If the array is in the load memory of a non-retentive FB, the values on first execution can be any bit pattern - including 0x7F800000 - which the loop treats as a real number. -
Library block hidden conversion. The block may call a Siemens library (e.g.
Scale,Total) whose output type is DWORD, silently producing a hex literal on the first scan.
Once #TempAverage reaches +∞, the divide step returns +∞ unchanged because IEEE 754 arithmetic on +∞ is closed under the four basic operations (except for indeterminate forms such as ∞-∞ and 0/0, both of which yield NaN). The FB then propagates +∞ to #Average for every subsequent scan until the CPU is restarted or the FB is reset.
5. Diagnostic Procedure: From Symptom to Cause
- Open the FB in the TIA Portal project. In the block interface window (top of the editor), confirm the declared data type of
Average. A common mistake is to declare it asDWORDwhen the value is meant to be a floating-point average. - Compile the project (Project → Compile → All) to surface any implicit conversion warnings. SCL will warn on REAL-to-DINT truncations and on any unreachable code.
- Go online with the PLC, open a Watch table, and drag
#Average,#TempAverage, and#ArraySizeinto the table. Right-click the column header and switch the display to Float for the average, Decimal for the index, and Hex for the raw DWORD if needed. - Add
#StatValues[0]through#StatValues[#ArraySize]to the watch table. Sort the column descending to find the largest contributor to the sum. - Compute the theoretical maximum sum on paper:
maxSum = (ArraySize + 1) * max(|#Value|). IfmaxSum > 3.4028235E+38, the FB will overflow by design and the data type must be LREAL (S7-1500) or the inputs must be clamped. - Watch
#StatCounteracross scans to verify that the array index never wraps to a negative value. In S7-1200 firmware V4.2 and earlier, integer wrap-around of a SINT/INT can produce -1; the subsequent#ArraySize + 1becomes 0 and the divide returns +∞. - Force
#ArraySize := 9in the OB startup and observe whether the average is finite on the first run. If it is, the issue is index wrap; if it is not, the issue is the running sum. - Use the TIA Portal Trace function to record
#TempAverageand#Valueon a high-resolution timebase. A spike in#TempAveragefollowed by a constant +∞ confirms overflow; a constant +∞ from the first scan confirms an uninitialized static area.
6. Solution A — Correct the Data Type Declaration
If the average is meant to be a floating-point number, the data type of #TempAverage, #Average, and every #StatValues[i] must be REAL (or LREAL for S7-1500). A DWORD for the running sum silently truncates the mantissa on every addition, which by itself produces wild results, and it also defeats the IEEE 754 overflow detection the runtime would otherwise provide.
Open the FB interface, change the type of Average to REAL, change TempAverage to REAL or LREAL, and recompile. The monitor view will switch to floating-point automatically, and the bit pattern 0x7F800000 will be displayed as +Inf, which is the explicit indication that the arithmetic is overflowing. This is the correct outcome - the display now matches the engineering meaning.
7. Solution B — Eliminate the Arithmetic Overflow
After correcting the data type, address the numerical condition that produced +∞:
-
Clamp the input range. Add a defensive clamp before the array write:
IF #Value > 1.0E+30 THEN #Value := 1.0E+30; END_IF; IF #Value < -1.0E+30 THEN #Value := -1.0E+30; END_IF;
Keep the clamp well below the IEEE 754 max (3.4E+38) to preserve headroom for the sum. -
Use LREAL for the accumulator on S7-1500. Declare
#TempAverageasLREALand cast every array entry:#TempAverage := #TempAverage + LREAL#StatValues[#TempCounter];
LREAL extends the upper limit to ~1.7976931E+308 and gives 15-17 significant decimal digits, which absorbs most real-world sensor scales without overflow. - Rescale before summing. If the engineering unit is in millivolts and the running sum grows rapidly, divide each input by a constant scale factor (e.g. 1.0E+3) before adding and multiply the result back at the end. This keeps the sum within REAL range at the cost of one extra multiply.
-
Guard the divisor. Replace
(#ArraySize + 1)with a precomputedDINTdivisor declared in the static area, and assert at the FB boundary:IF #Divisor = 0 THEN #Average := 0.0; #Overflow := TRUE; RETURN; END_IF; -
Detect and reset on overflow. The S7-1500 firmware (V2.6 and later, CPU 1511-1518) provides the
IS_FLOAT_VALIDandIS_FLOAT_NANoperators in SCL. For S7-1200 firmware V4.4 and later, use a manual check:IF (#TempAverage > 3.4E+38) OR (#TempAverage < -3.4E+38) THEN #Average := 0.0; #Overflow := TRUE; END_IF; -
Initialize the static area. In SCL, set the Start value column in the block interface for every
#StatValues[i]to0.0. Without this, the first scan reads garbage from the load memory of a non-retentive FB instance.
A robust averaging pattern for an S7-1500 with the array declared in LREAL:
#TempAverage := LREAL#0.0;
FOR #TempCounter := 0 TO #ArraySize DO
#TempAverage := #TempAverage + LREAL#StatValues[#TempCounter];
END_FOR;
IF (#ArraySize + 1) <> 0 THEN
#Average := REAL#LREAL_TO_REAL(#TempAverage / DINT_TO_LREAL(#ArraySize + 1));
ELSE
#Average := 0.0;
END_IF;
8. Solution C — Change the Online Display Format (Cosmetic Only)
If the underlying value is acceptable and only the display is wrong, the format can be changed locally in the watch table or the HMI without altering the program:
- Open the watch table, right-click the column for the DWORD tag, choose Display Format → Decimal or Display Format → Float.
- In an HMI tag (WinCC Professional, WinCC Comfort/Advanced, or TIA Portal Unified), open the tag properties and switch the Representation property to Decimal or FloatingPoint. The value 0x7F800000 will display as
2139062784(decimal) or+Inf(float) at the panel. - For the FB interface, the only way to make the value look right in the default monitor is to change the declared data type. The monitor format follows the declaration, not the watch table column - the watch table column override applies only to that watch table.
9. Recommended Variable Declarations for an Averaging FB
| Variable | Recommended Type | Reason | Avoid |
|---|---|---|---|
Value (input) |
REAL | Process value engineering unit | INT, WORD |
StatValues : ARRAY[*] OF ... |
REAL (S7-1200), LREAL (S7-1500) | Holds the rolling window | DWORD, INT (loss of precision) |
TempAverage |
LREAL (S7-1500) or REAL (S7-1200 with range check) | Running accumulator | DWORD (silent truncation), INT (overflow at ±32767) |
Average (output) |
REAL or LREAL | Final average in engineering unit | DWORD, INT, BOOL |
StatCounter, TempCounter |
DINT, INT | Loop index, must be integer | REAL (rounding can break the FOR loop) |
ArraySize |
INT (positive), or DINT with input range check | Loop bound, must be ≥ 0 | SINT (can be negative) |
StatArrayFull, Overflow |
BOOL | Status flag | WORD bit (poor readability) |
Match the data type to the engineering meaning of the variable. A "running average" is a continuous quantity, so REAL/LREAL is the correct type. DWORD is appropriate only for raw register access (Modbus holding registers, PROFINET status words, shift-register bit packing).
10. Cross-Platform Notes: S7-1200 vs S7-1500 vs S7-300/400
| Platform | REAL Type | LREAL Support | Overflow Detection in SCL | Notes |
|---|---|---|---|---|
| S7-1200 (CPU 1211-1217, firmware V4.0+) | 32-bit IEEE 754 | No (some V4.4+ add limited support) | Manual: ABS(x) > 3.4E+38
|
Use clamp + REAL; LREAL not generally available |
| S7-1500 (CPU 1511-1518, firmware V1.8+) | 32-bit IEEE 754 | Yes (64-bit IEEE 754) |
IS_VALID_REAL, IS_NAN from V2.6 |
Prefer LREAL for accumulators |
| S7-300 / S7-400 (legacy STEP 7 V5.x) | 32-bit IEEE 754 | No | Manual | Watch table shows the same hex literal; format change via Display Format → Float |
| ET 200SP CPU (firmware V2.5+) | 32-bit IEEE 754 | Yes | Same as S7-1500 | Same diagnostics apply |
The IEEE 754 +∞ bit pattern is identical across all platforms because the standard is platform-independent. A REAL +∞ is always 0x7F800000, regardless of CPU family. LREAL +∞ is always 0x7FF0000000000000. The display format may differ (S7-300/400 in STEP 7 V5.x shows the same hex literal for a DWORD tag; S7-1500 in TIA Portal V18+ shows the floating-point value when the type is REAL).
11. HMI / WinCC Integration
The HMI tag connected to #Average must use the same data type as the PLC tag, otherwise the panel will display the value using its own representation rules and may show DW#16#7F800000 even after the PLC has been corrected. Configure the HMI tag as follows:
-
WinCC Professional (TIA Portal): HMI tag → Properties → Data type =
Real, Length = 4, Representation =FloatingPoint, Decimal places = 2 (or as required). -
WinCC Comfort / Advanced: Tag → Properties → Data type =
Float, Format =999.99to suppress NaN/Inf rendering and force the panel to draw a clean number. -
TIA Portal Unified (WinCC Unified): HMI tag → Properties → Data type =
Real, Display format configured in the connected IO field. Use a script to suppress+Infif the panel does not render it.
For alarming, the HMI can subscribe to the PLC's #Overflow BOOL bit and raise a message on the HMI log. This is more reliable than parsing the numeric value at the panel.
12. Verification Procedure
- Recompile the project (Project → Compile → All) and resolve any warnings about type conversion.
- Perform a full download (not just delta) and restart the CPU in STOP → RUN to clear any stuck state in the FB's static area. If a hot download is required, verify in TIA Portal that the FB retains its static variables - the option is under Download to device → Options → Consistent download.
- Place the PLC in RUN, drive the input
#Valuethrough its full engineering range, and verify that#Averagetracks the expected value within a tolerance consistent with the number of samples. - Apply a boundary test: set
#Valueto3.0E+38(the maximum finite REAL) and confirm that#Averageremains finite. With a properly clamped or LREAL-based FB, it should be a large but finite number. - Apply a negative boundary:
#Value = -3.0E+38. The output should be the corresponding negative finite average. Any output of 0xFF800000 (or DW#16#FF800000) is a negative overflow and must be addressed. - Watch the tag for at least 1000 scans (one full FIFO rotation) to confirm there is no transient that produces +∞ under any legal input combination.
- Check the HMI value: it should now match the PLC's REAL value to the configured decimal precision. If the HMI still shows
DW#16#7F800000, the panel tag is configured as a raw word; reconfigure its representation to FloatingPoint (WinCC) or Real (Unified). - For permanent monitoring, add the average to a TRACE configuration in TIA Portal so the historical curve will show the transient if it recurs.
13. Related IEEE 754 Patterns to Recognize
| Hex Pattern (32-bit) | IEEE 754 Meaning | Likely Cause |
|---|---|---|
| 0x7F800000 | +∞ | Positive overflow, division of large positive by zero |
| 0xFF800000 | −∞ | Negative overflow, division of large negative by zero |
| 0x7FC00000 (and ~16M other patterns) | NaN (quiet) | 0/0, ∞-∞, sqrt of negative, log of negative, uninitialized REAL |
| 0x7FA00000 | NaN (signaling, SNaN) | Uninitialized memory in SCL, bad cast |
| 0x00000000 | +0.0 | All inputs zero or uninitialized in a positive-sign block |
| 0x80000000 | −0.0 | Negation of a zero result; treated as equal to +0.0 by == |
| 0x7F7FFFFF | Max finite REAL (≈ 3.4028235E+38) | Saturation - one step before overflow |
| 0x00800000 | Min positive normalized REAL (≈ 1.1754944E-38) | Underflow threshold |
| 0x00000001 | Min positive denormalized REAL (≈ 1.401298E-45) | Gradual underflow |
| 0x7F800001 (and 0x7FBFFFFF) | NaN (with non-zero mantissa) | Indeterminate form, library-block internal error |
Recognizing these patterns on the watch table speeds up diagnostics the next time the FB misbehaves. For the corresponding 64-bit LREAL patterns, the prefix is 0x7FF0000000000000 for +∞, 0xFFF0000000000000 for -∞, and 0x7FF8000000000000 for the canonical quiet NaN.
14. Safety, Commissioning, and Library Notes
- Document every data-type change in the project change log. TIA Portal's Project history feature captures the change automatically if it is enabled (Project → Settings → Project history).
- Place the CPU in STOP only if the FB is on a non-critical path; otherwise, hot-update via TIA Portal's Download to device with the program in RUN-P, and verify that the FB retains its static variables.
- If the FB is part of a SIL-rated path, follow the functional safety change procedure: a tool change-control sign-off and a second-person review of the new arithmetic. The TIA Portal Safety version (STEP 7 Safety) has its own acceptance test workflow.
- For S7-1200, the SCL editor compiles REAL arithmetic with 32-bit precision regardless of CPU firmware. S7-1500 with firmware V2.6 and later supports the full LREAL range.
- Avoid hand-coded
DWORDaccumulators in SCL. Use the RET_VAL of an explicit type conversion (e.g.REAL_TO_DWORD) only when a downstream block genuinely requires a bit pattern; otherwise the typedREALvariable will save you from the hex display problem at the source. - When porting the FB to a TIA Portal version older than V15.1, the LREAL constant literal syntax differs (
LREAL#was not consistently accepted in V13 SP1). Use the explicit conversionREAL_TO_LREAL(x)for backward compatibility. - For S7-300 / S7-400 in legacy STEP 7 V5.x, the same diagnostics apply, but the watch table column change is under Display format → Float and the IEEE 754 special value rendering is identical.
15. Frequently Asked Questions
Why does TIA Portal show DW#16#7F800000 instead of +Inf for my average value?
The tag is declared as DWORD, so the online monitor renders the raw 32-bit pattern in hexadecimal. The pattern 0x7F800000 is the IEEE 754 single-precision encoding of +∞, but TIA Portal only shows the float interpretation when the data type is REAL. Change the declaration to REAL and the same bits will appear as +∞.
How do I know if my averaging FB is overflowing versus just being formatted wrong?
Open a watch table, add the running sum and the output, and switch the column to Float. If the value is +∞, the sum exceeds 3.4028235E+38 and the arithmetic must be clamped or computed in LREAL. If the value is a finite REAL, the issue is purely the watch-table format.
Is DW#16#7F800000 the same on S7-1200 and S7-1500?
Yes. For REAL (32-bit) the IEEE 754 +∞ bit pattern is identical on both platforms. On S7-1500, the LREAL (64-bit) representation of +∞ is 0x7FF0000000000000; if you see the 64-bit pattern in a watch table, the value is +∞ in LREAL, not a corrupted DWORD.
Why is the default online display hexadecimal for WORD and DWORD?
WORD and DWORD are explicitly bit-addressable integer types in STEP 7. Hexadecimal is the shortest human-readable representation of a binary pattern and avoids ambiguity for high-bit values. Decimal is reserved for signed/unsigned INT/DINT and floating-point values.
Can I force the HMI to show a decimal value of 2139062784 instead of DW#16#7F800000?
Yes. In the HMI tag configuration, change the representation to Decimal or Binary Coded Decimal. However, this only changes the rendering. The PLC still holds the IEEE 754 +∞ bit pattern, and downstream logic that interprets the value as REAL will still see +∞. The arithmetic must be fixed first.
For additional reference material, see the Siemens Industry Online Support portal for the STEP 7 (TIA Portal) programming and operating manual, the S7-1200 programmable controller system manual, and the S7-1500 automation system manual.