S7-1200 KTP900 IO Field Flashing 0.00: Merker Tag Root Cause and Fix
1. Problem Overview
A S7-1200 CPU writes an analog pressure value into a tag that is read by a KTP900 Basic HMI. The I/O field on the panel displays the correct engineering value (e.g. 23.4 bar), but at apparently random intervals the value drops to 0.00 for one to two seconds and then returns to the correct reading. Live monitoring in TIA Portal on the PLC side never shows the drop, so the issue appears to be HMI-side.
This is a classic memory-area reuse symptom in S7-1200 projects where the HMI is bound to a Merker (M) word instead of a Data Block (DB) tag. The fix in every reported case is to move the value into a global or instance DB and re-bind the HMI tag to the new address.
2. Affected Hardware, Firmware, and Software
| Component | Confirmed / Typical | Source |
|---|---|---|
| PLC | SIMATIC S7-1200 (CPU 1211C / 1212C / 1214C / 1215C / 1217C) | Field report |
| HMI | SIMATIC KTP900 Basic (6AV2 123-2JB03, Basic Panel 9", PN) | Field report |
| HMI Engineering | WinCC Comfort V15.1 / V16 / V17 (TIA Portal) | WinCC Comfort V17 Manual |
| PLC Engineering | STEP 7 V15.1 / V16 / V17 (TIA Portal) | WinCC Comfort V17 Manual |
| PLC Firmware | V4.2 - V4.6 (any V4.x behaves identically for this issue) | S7-1200 System Manual, Edition 04/2023 |
| HMI Runtime | Image V15.1.0.6 or higher on KTP900 Basic | KTP900 Basic Operating Instructions |
The defect is independent of firmware version. It is a programming-pattern defect in the S7-1200 user program combined with the way WinCC samples tags.
3. Root Cause: Merker Area Reuse and HMI Read Cycle
The S7-1200 memory model exposes the following retentive/volatile areas to the user program and to HMI tag connections:
- Process image of inputs (I) and outputs (Q) – automatically refreshed once per OB1 cycle at fixed phase boundaries.
- Merker area (M) – global, byte-addressable working memory. The S7-1200 M area is volatile (not retained unless explicitly configured as retentive in the PLC properties).
- Data Blocks (DB) – structured storage. Global DBs are ideal for plant-level variables; instance DBs hold FB static data.
- Local stack (L) – per-block temporaries, NOT visible to HMI.
Merker bytes/words/doublewords are a tempting scratchpad because they are global, indexable, and survive the block call boundary. The problem is that they are also global to the rest of the user program. Any FC, FB, or OB that writes to the same MW address — even temporarily, even with a different data type — overwrites the bits that the HMI is reading.
The HMI does not read the tag at the end of the OB1 cycle. WinCC Comfort uses an independent acquisition cycle for each tag (default 1 s), driven by the HMI's own task scheduling. If the HMI requests the tag at a moment when an FC in OB1 is in the middle of writing a temporary 32-bit value into that MW, the HMI reads whatever happens to be in those four bytes at the moment of the GET request. The TIA Portal PLC online monitor, by contrast, samples when you click the refresh button, so it almost never catches the transient corruption.
This is exactly the symptom chain that produced the original report on the Siemens SiePortal support forum thread and is documented in the Siemens FAQ 109778709 for "strange runtime behaviour of HMI tags".
4. Why a Bit-Level Overwrite Produces Exactly 0.00
The S7-1200 uses IEEE 754 single-precision floating point for the REAL data type. A 32-bit REAL is laid out as follows:
| Bits 31 (sign) | Bits 30-23 (exponent, bias 127) | Bits 22-0 (mantissa, hidden leading 1) |
|---|---|---|
| 0 = positive, 1 = negative | 0x00 = 0x00; 0x7F = exponent 0; 0x80 = 1.0 | Fractional bits |
The literal value 0.0 is the unique 32-bit pattern 0x00000000. If a single bit is set in the exponent or mantissa, the value is no longer zero — it is either a denormal, a small subnormal, infinity, or NaN, depending on which bit was flipped.
Conversely, if a function block overwrites a REAL located in MW with a 16-bit integer (INT) and a separate INT, or moves a BOOL reset, the low 16 bits of the REAL can become 0x0000 while the high 16 bits still hold the high half of the original REAL. Conversely, if a function pre-initializes the four bytes with 0x00 as a scratch clear and then later in the same OB1 cycle the FC runs again with a partial value, the HMI can sample the moment when all four bytes are 0x00, producing exactly 0.00.
That is why the HMI display shows 0.00 and not some other small number — the transient state is the cleared state of the scratch word, not a partial computation.
5. Why TIA Online Monitoring Does Not Show the Fault
Three reasons converge to hide the corruption from a PLC engineer staring at the online watch table:
- Sample timing. The watch table is updated on demand. By the time the cursor flashes, OB1 has finished and the M area has been re-written with the correct value.
-
Display format. The watch table is decoded as
REALbased on the column format. A momentary 16-bit write to MWx and MWx+2 can be interpreted as 0.0 in REAL but as a non-zero value in HEX, which is why the value is invisible in a column configured for floating point. - Symptom scale. The corruption window can be a single PLC cycle (1–10 ms). The HMI is more likely to catch it than a human pressing F5 every couple of seconds.
6. Solution: Move the Value into a Data Block
The robust fix is to bind the HMI tag to a symbol in a Data Block. The DB's memory is owned by the user program; the compiler allocates it once, the HMI reads it via the standard PUT/GET or S7 communication, and concurrent writes from unrelated blocks are eliminated by the structured-name contract.
7. Step-by-Step Fix in TIA Portal
-
Add a global DB. In the project tree, right-click Program blocks > Add new block > Data block (DB). Name it
DB_Process. Uncheck Optimized block access only if you need the HMI to address it via absolute address (older WinCC projects require this for PUT/GET). For V17 and later, optimized blocks are fully supported over S7-1200 symbol access; leave optimized access enabled to benefit from download without re-init. -
Declare the pressure tag. Open
DB_Processand add a static tag:// DB_Process pressure_REAL : REAL; // 0.0 .. 100.0 bar pressure_raw : INT; // 0 .. 27648 pressure_OK : BOOL; // 1 = scaled value valid -
Write the scaled value into the DB. In your scaling FC, replace the
MWtarget withDB_Process.pressure_REAL:// FC_Scale_AI // Input: AIW (INT) // Output: pressure (REAL 0..100 bar) IF AIW < 0 OR AIW > 27684 THEN DB_Process.pressure_OK := FALSE; DB_Process.pressure_REAL := 0.0; RETURN; END_IF; DB_Process.pressure_OK := TRUE; DB_Process.pressure_REAL := INT_TO_REAL(AIW) / 27648.0 * 100.0; -
Re-bind the HMI tag. In the HMI tag list, open the pressure tag and change the PLC address from
MW200(or whatever was used) to the symbolic referenceDB_Process.pressure_REAL. Confirm that Access mode is Symbolic and the Acquisition cycle is appropriate (e.g. 1 s). - Compile and download. Compile the S7-1200 program first, then the HMI project, then download both. Watch the S7-1200 go to RUN; the IO field should now read continuously without flashes.
- Retain the previous M references only as intermediate scratch. If the scaling FC needs a 32-bit scratch, declare a TEMP variable (L area) so that scratch storage is local to the FC and disappears when the block exits.
8. Alternative Diagnostic: PLC Trace
If you want to confirm the diagnosis before changing the program, use the S7-1200 Trace (firmware V4.0 and later). The Trace can record the value of MW200 at the OB1 cycle rate and reveal the 0.0 transient.
- Project tree > Traces > Add new trace.
- Add a signal:
MW200, display format Floating-point (REAL). Optionally add a second signal in HEX to expose bit-level corruption. - Set recording duration to 30 s and trigger on the rising edge of OB1_PERIPH_OK or manual start.
- Download the trace configuration to the CPU and start. With the IO field flashing observed on the HMI, the trace will show the underlying transient.
Traces are documented in the S7-1200 System Manual, section "Trace and logic analyzer function".
9. IO Field Configuration Best Practices on KTP900 Basic
When binding the new DB tag to the IO field on the KTP900 Basic, configure the following properties (in the I/O field Configuration dialog in TIA Portal under Properties > General > Appearance and Properties > General > Value):
| Property | Recommended Value | Why |
|---|---|---|
| Tag |
DB_Process.pressure_REAL (Symbolic) |
Stable binding; immune to DB re-numbering |
| Acquisition cycle | 1 s (process) or 500 ms (fast) | Smoother visual update, less HMI load |
| Display format | 999.9 (or 999.99) | Avoids leading-zero flicker; matches REAL precision |
| Mode | Output (read-only) | Prevents operator entry corrupting scaled value |
| Limits | Min 0.0, Max 100.0 | Triggers color/visibility alarm if value goes out of band |
| Decimal places | 1 or 2, matching the scaled REAL | Prevents display rounding hiding the flash |
Real, not LTime or DTL.10. HMI Tag Acquisition Cycle and Update Rate
For S7-1200 ↔ KTP900 Basic communication over PROFINET, the HMI operates as a PN IO device and exchanges data with the CPU on the configured S7 connection. The relevant timing values are:
- Update time on the HMI tag — the cycle in which WinCC reads the value from the S7 connection buffer. Minimum 100 ms, default 1 s. Lower values increase PROFINET load and S7-1200 communication task time.
- S7-1200 PN communication budget — limited. Up to 8 active PUT/GET or operator-panel connections total. Keep HMI-visible tags in a single DB to minimize the number of variables per read request.
- OB1 cycle time — typically 1–20 ms for a small program. The HMI will sample on a millisecond scale, but the acquisition cycle is the dominant parameter.
Even with a 1 s acquisition cycle, a 1 ms corruption window of the M area is statistically certain to be hit, which is why the symptom is reproducible but appears random.
11. Verifying the Fix
- Power-cycle the KTP900 and ensure the project is reloaded. Confirm the tag address in the HMI tag list shows
DB_Process.pressure_REALand notMW200. - Force the AIW to a known value (e.g. 13824) using a watch table, with the S7-1200 in RUN. The IO field should display 50.0 bar continuously.
- Vary the AIW in steps of 2765 (10% of full scale) over 5 minutes and watch the IO field. No flash to 0.00 should be observed.
- Set the AIW to 0 and to 32767 (out-of-range). The IO field should display 0.0 and 118.8 (or be clamped by limits), and the
pressure_OKtag should toggle — confirming that the scaling logic is still in the OB1 path. - Run an S7-1200 Trace on
DB_Process.pressure_REALfor 60 s while the operator screen is open. The trace should show a smooth, monotonic trace without zero transients.
12. Preventive Best Practices
- Single source of truth. Every HMI-visible variable lives in a global or instance DB. The DB acts as the contract between the PLC program and the HMI; the program writes, the HMI reads.
-
No M area in HMI tags. Add a TIA Portal cross-reference check in the HMI tag list: filter the PLC address column to
%M*. The list should be empty in a mature project. - Use TEMP (L area) for block scratch. The L stack is private to the running block instance and is overwritten on block exit. It is the correct place for intermediate computation, not MW.
- Avoid BOOL/INT overlays on REAL. If you must pack multiple flags, use a STRUCT in a DB with a BOOL array. The compiler will not overlay it with a REAL.
- Watch table hygiene. When debugging, monitor DB tags, not MW. That way you see what the HMI sees, not a transient working value.
- Use symbolic HMI tags. With optimized block access and symbolic tags (TIA V15.1 and later), you avoid the silent breakage that occurs when DB numbers are renumbered after a recompile.
13. Related Configuration Pitfalls
| Pitfall | Symptom | Fix |
|---|---|---|
HMI bound to Q area bit (e.g. Q0.0) |
IO field reads the process-image bit interpreted as INT/REAL and jumps | Move to a DB; never bind HMI to I or Q without an explicit data type contract |
Data type mismatch (PLC REAL, HMI tag INT) |
IO field shows scaled noise or NaN | Match the data type in the HMI tag properties |
| PUT/GET access disabled on S7-1200 (CPU properties > Protection) | HMI shows 0.0 or "#" for every tag | Enable Permit access with PUT/GET for operator panels, or use symbol access via the S7 connection |
| HMI tag has no connection configured | IO field shows "####" | Confirm the HMI connection points to the correct S7-1200 and the connection is in the Connection list |
| DB optimized access mismatch with old WinCC project | IO field reads zero because the HMI cannot decode the symbol | Either turn off optimized access for the DB or update the HMI project to symbolic tags (recommended) |
| Multiple writers to same MD (e.g. main and a HMI script) | Glitching values | Enforce single writer; HMI should be read-only |
14. Frequently Asked Questions
Why does the IO field flash to exactly 0.00 and not some other small number?
Because the underlying S7-1200 Merker word is being momentarily cleared (all 32 bits = 0) by an FC that uses the same MW as scratch storage. IEEE 754 single-precision floating point decodes the bit pattern 0x00000000 as exactly 0.0, so the HMI shows a clean 0.00 for the duration of the GET request.
Can I just change the HMI tag acquisition cycle to 100 ms to smooth out the flash?
No. The flash is caused by the value being 0.0 at the moment of the HMI read, not by jitter. A faster cycle actually makes the symptom more frequent because the HMI samples more often. The only durable fix is to move the value into a Data Block and bind the HMI tag symbolically.
My TIA Portal online watch table on the PLC tag never shows 0.00. Is the HMI broken?
The HMI is reading the tag correctly; the PLC tag itself is transiently zero. Online watch tables are sampled on demand, so a 1–10 ms corruption window is easily missed. Use a PLC Trace (firmware V4.0+) to record the tag at OB1 cycle rate to confirm the transient.
Is the Merker (M) area retentive on the S7-1200?
By default, the M area is non-retentive. Specific MB/MW/MD ranges can be marked retentive in the CPU properties under Retain memory. This does not affect the issue described above; the symptom is independent of retention because the corruption happens during the PLC cycle, before any power-loss retention is relevant.
Do I have to use a global DB, or can I use an instance DB of an FB?
Either works for HMI binding. A global DB is the conventional choice for plant-level process variables; an instance DB is appropriate when the value is owned by a specific FB (e.g. a valve FB exposing its current pressure setpoint). In both cases, the HMI tag must be bound symbolically, never to MW or Q area.