Siemens S7 M 0.2 Encoder Counter Not Updating on HMI

David Krause17 min read
S7-300SiemensTroubleshooting
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

Siemens S7 M 0.2 Encoder Counter Not Updating on HMI: Field Diagnostic Reference

A palletizing machine uses a Hohner shaft encoder wired into digital input I 0.2 on a Siemens SIMATIC S7 CPU. The pulse train is conditioned inside an STL counting FC that copies I 0.2 into a memory bit M 0.2, scales and accumulates the result, and the resulting word is supposed to drive the hoist position display on the HMI. After a service interval, the HMI stops showing the live count even though the hoist still positions mechanically. The PLC program appears to run, the encoder turns, the input LED flickers, but the value on the panel freezes. This article walks through every layer of the failure path: bit/word overlap in the M area, STL semantics of the XOW instruction, STEP 7 reference data cross-referencing, Hohner wiring, and HMI tag binding. It is written for the maintenance engineer who has to put the line back in service before second shift.

1. Problem Overview

The reported symptom is a silent loss of count: no fault, no SF/BF LED on the CPU, no diagnostic buffer entry, no operator error. Only the HMI tag that should show the live encoder position is frozen, while the mechanical hoist still traverses correctly because the limit-switch backup path is independent of the count register.

Two distinct fault families cause this exact behavior on S7-300/400 cells:

Family Typical Indicator Where to Look
Bit/word memory overlap in the M area Counter value is computed but ends up in the wrong MW or gets XOR-clobbered by a parallel FC STEP 7 Reference Data, cross-reference of MW 0, MW 2, MW 50, MW 52
HMI tag binding or WinCC area pointer failure Online value is correct in VAT/PLCSIM, wrong or static in WinCC flexible / TIA Portal HMI tag connection, update cycle, area pointer, PLC-HMI connection diagnostics

Both families can be present at once. The diagnostic procedure below is ordered so the cheapest, fastest checks come first.

2. S7 Memory Bit Architecture and the MW 0 Trap

The S7 M area is a flat byte-addressed memory. Bit, byte, word, and double-word addresses all share the same physical bytes. The address M 0.2 is bit 2 of byte 0, which is the least significant bit 2 of the word at MW 0 and of the high word of MD 0. Anyone in the program can read or write the same physical location using any of these four address forms. The PLC does not enforce a name.

Physical byte 0 of the M area: address aliases
Bit Address Byte Address Word Address DWord Address
M 0.0 ... M 0.7 MB 0 MW 0 MD 0 (low word)
M 1.0 ... M 1.7 MB 1 MW 0 (high byte) MD 0 (low word)

Therefore M 0.2 is bit 2 of MW 0 and bit 18 of MD 0. If any FC, OB, or FB writes to MW 0, MB 0, MD 0, or even accesses M 0.0 through M 0.7 with a different instruction, the value at M 0.2 can be flipped independently of the encoder FC. The most common scenario in service is exactly the one shown in the source: a separate FC computes a status word and writes MW 0 at the end of its cycle, erasing the pulse that the counting FC just set.

3. Special M Bits: What Is Actually Reserved

Siemens does not reserve M 0.2 for any system function. The only address ranges that are not free for user logic are:

  • Clock memory bits (clockmerker): a user-selected byte (default often MB 0, configurable in HW Config / PLC properties -> Clock Memory). The configured byte becomes read-only when the bit is used as a clock source. If clock memory is enabled and the configured byte happens to be MB 0, then M 0.0 through M 0.7 are all reserved as 10 Hz / 5 Hz / 2 Hz / 1 Hz / 0.5 Hz / 0.2 Hz / 0.1 Hz / 0.05 Hz outputs. This is the most common reason a hand-written bit that "looked free" behaves strangely.
  • Process-image write protection on certain F-CPU safety programs for M bits above the configured maximum M area size.
Field check: In STEP 7, open the CPU hardware object, select Properties -> Cycle/Clock Memory, and read the configured clock memory byte. If it is MB 0, MB 1, or MB 2, relocate the counting FC to a higher M byte before continuing the diagnosis.

4. Hohner Shaft Encoder Signal Path

Hohner (now part of Hohner Elektrotechnik) shaft encoders are incremental, two-channel quadrature devices typically used in industrial palletizers. The relevant series for low-speed hoist positioning is the H20 / H25 incremental family with HTL push-pull or TTL output stage. The encoder provides:

  • Channel A (and optionally B for direction)
  • Index Z (once per revolution, optional)
  • Supply: typically 10-30 V DC, current draw 50-150 mA depending on model
Typical Hohner H20/H25 wiring (PNP HTL output)
Encoder Pin Signal S7 Terminal Notes
Brown +V (10-30 V DC) 24 V DC sensor supply Verify load capacity; check for voltage drop under load
Blue 0 V 24 V DC return Single-point ground with PLC backplane
Black Channel A Digital input terminal, e.g. I 0.2 If long cable, use shielded twisted pair, shield grounded at cabinet entry only
White Channel B (direction) Optional I 0.3 for up/down count Only used if FC does direction discrimination
Shield Drain Earth bar at cabinet entry Never bond both ends of shield

For the symptom in the source (count lost on HMI, but the hoist still moves) the most likely hardware causes, in order, are:

  1. Open conductor on the encoder supply: encoder still outputs pulses capacitively on a charged cable for a few seconds, then dies. Often visible as a slow count drift that stops.
  2. Broken wire on Channel A: zero pulses, no count. Easily confirmed with VAT online monitoring of I 0.2.
  3. Input module channel failure: LED on the DI module is on, but the input register bit is 0. Swap channel and rewire.
  4. Ground loop on the encoder shield: high common-mode voltage clips the input at one rail; only the rising edge crosses the threshold, halving the apparent count.

5. Counter FC in STL: Pulse-to-Bit Mapping

The S7 counting FC described in the source is written in STL (Statement List) and has the structure:

//  Pulse conditioning FC (illustrative STL)
A    I 0.2          // raw encoder channel A
=    M 0.2          // conditioned pulse bit
A    I 0.3          // raw encoder channel B
XOR  // direction discrimination
S    M 0.3          // direction flag
A    M 0.2
CU    Z 0           // up counter (S_CU) or IEC CTU on Z0
NOP 0

The relevant counter primitives on S7-300 are:

  • Z 0 ... Z 255: classic S7 counters (S_CU, S_CD, S_CUD). The current count is read as a BCD or integer word directly from the counter's accumulator register.
  • IEC counters CTU, CTD, CTUD declared as FB instances in an instance DB. Current value is in DBXx.CV.

Whichever counter is used, the HMI tag must point at the counter's current value, not at M 0.2. The bit M 0.2 is the per-cycle pulse, not the integrated count. If the HMI tag was bound to MW 0 (because the programmer thought the bit was being assembled into a word manually) and another FC clobbers MW 0, the count never appears.

6. M 0.2 Bit Tracking Through MW 0

When you cannot "find" M 0.2 further in the program by string search, the reason is that nobody else uses it as a bit. The other consumers of that memory are reading or writing the same physical bits via a word address. Search the program offline for any of the following and you have effectively searched for every consumer of M 0.2:

Search patterns for M 0.2 consumers (STEP 7 / TIA Portal)
====================================================
MW 0          // entire word containing M 0.0 ... M 1.7
MB 0          // entire low byte
MB 1          // entire high byte of MW 0
MD 0          // entire double word
M 0.0 ... M 0.7   // any sibling bit that the user is using as a flag
M 1.0 ... M 1.7   // any sibling bit that the user is using as a flag

In the source, the program contains exactly such a word-level consumer:

L    "MW 0"     // load the very word that contains M 0.2
L    "MW 52"    // load a status / pattern word
XOW              // 16-bit word XOR
T    "MW 50"    // store result
L    "MW 0"     // load MW 0 again
...

Note that this snippet reads MW 0 twice. The XOR and the store do not modify MW 0. So this particular FC is not the cause of the lost count. The diagnostic value of this snippet is that it confirms the program does access MW 0, and therefore any FC that writes to MW 0 is a candidate. The candidate search is performed with reference data, as described in section 8.

7. STL XOR / XOW Pattern Decoded

The XOW instruction (XOR Words) is bitwise XOR on 16-bit words. It is most often used to:

  • Toggle a subset of bits in a status word without using a mask and a separate copy step.
  • Implement a toggle flip-flop for HMI control bits.
  • Decode an error pattern by XORing against an expected value.

The pattern L MW 0; L MW 52; XOW; T MW 50 computes MW 50 = MW 0 XOR MW 52. The bit M 0.2 therefore contributes to bit 2 of MW 50 indirectly, via the value of MW 0 at the time the FC runs. If your HMI tag is bound to MW 50 rather than the counter's CV, you are reading a derived status word, not a position. This is a common bind-by-name mistake when the programmer reused the symbol "CounterWord" between the original S7 project and the migration into TIA Portal.

8. STEP 7 Reference Data Diagnostic

Reference data is the canonical tool for this failure. It lists every read and write of every address in the user program, cross-block, and lets you find the colliding FC.

  1. In STEP 7 Manager, select the S7 program node and choose Options -> Reference Data -> Display.
  2. In the reference data window, select Program Structure and confirm that all expected blocks (FCs, FBs, OBs) are listed. Missing blocks indicates the offline/online project mismatch.
  3. Switch to the Cross-Reference view.
  4. Type the address MW 0 in the filter and press Enter. The view lists every access: address, symbol, block, network, access type (R = read, W = write, RW = read/write), and the language.
  5. For every write entry on MW 0 outside the counting FC, click the network to jump to the source. The collision is almost always there.
  6. Repeat the filter for MW 50, MW 52, the counter's CV address (e.g. DBx.DBW0 for an IEC counter instance), and the HMI tag's address.

The same data is available in TIA Portal under Program info -> Cross-references. The filter syntax differs (use the Go to address dialog and tick the "All accesses" box) but the principle is identical.

Tip: Reference data is generated from the offline project. After every change to the program, the data must be re-generated (right-click the S7 program -> Reference Data -> Generate). Stale reference data is one of the top reasons a search returns "no hits" on a clobbering FC that is in fact present in the online program.

9. HMI Tag Binding: The Most Common HMI Loss Cause

When the live count disappears only on the HMI while the value in the PLC remains correct, the fault is on the HMI side, not the PLC. The four most common causes in order of frequency are:

Cause Symptom Resolution
Tag address changed in PLC, not in HMI project HMI value frozen at last good value or shows 0 Re-compile HMI tag table, refresh the connection, re-download to the panel
Update cycle too long for fast-changing tag HMI value lags or skips Lower the acquisition cycle (e.g. 100 ms) or switch to "Continuous" for fast tags
Area pointer disabled or wrong slot All tags from the area pointer static, while direct tags update Verify area pointer configuration in both PLC and HMI connections, ensure consistent DB number and offset
PLC-HMI connection down (PROFINET/MPI cable) Connection icon yellow/red on the HMI diagnostics page Check cable, IP/subnet or MPI address, restart connection from HMI diagnostics view

For a count tag, the binding must be:

HMI tag configuration (WinCC flexible / TIA Portal)
==================================================
Name:        HoistPosition
PLC tag:     "Counter_DB".CV       // IEC counter current value
            (or ZW 0 for S7 classic counter Z0)
Data type:   INT  (or DINT, match PLC type)
Length:      1 word
Acquisition: Continuous           // required for live count
Display:     IO field, format: signed decimal

If the HMI tag is bound to MW 0 with a symbol name that suggests it is the count, the field experience is the same as a memory overlap. Switch the HMI tag to the counter's CV address and re-download.

10. Field Diagnostic Procedure

The following procedure resolves 95% of "M 0.2 count not on HMI" reports in under one shift. Execute in order, do not skip a step.

  1. Verify the encoder is turning and the input is firing. Open STEP 7 / TIA Portal, go online, open a VAT, and monitor I 0.2. Manually rotate the encoder and confirm the bit toggles at the expected PPR (pulses per revolution). A 1024-PPR Hohner H20 at 100 rpm should produce 1706.67 pulses per second. If the bit does not toggle, the fault is hardware: encoder, cable, DI module.
  2. Verify the conditioned bit. Monitor M 0.2 in the same VAT. Confirm the bit follows I 0.2. If M 0.2 is always 0, the counting FC is not executing, the call is missing, or a SET/CLR in OB100 or an init FC has just cleared it. Check the OB1 call of the FC, and check OB100.
  3. Verify the counter value. Monitor the counter's current value (classic Z 0 in VAT, or instance DB CV for IEC). Confirm it increments when the encoder turns.
  4. Verify the HMI tag address. In the HMI project, open the tag table, find the count tag, confirm the PLC address matches the counter's CV word exactly. Re-compile the HMI project and re-download to the panel.
  5. Check for memory overlap. Generate fresh reference data, cross-reference MW 0, find any write that is not in the counting FC. Either move the counting FC to a free M byte (e.g. MB 100) and update I 0.2 -> M 100.2, or move the colliding FC to a different MW.
  6. Check the HMI connection. On the HMI diagnostics page, confirm the connection is "Connected" (green). If it is yellow or red, check the cable, addresses, and the area pointer DB number.
  7. Check the clock memory configuration. In the CPU hardware object, confirm the clock memory byte is not MB 0 (or whichever byte the counting FC is using). If it is, change the clock memory byte to a byte the program does not use, or move the counting FC.

11. Hardware and Software Verification

After the fix, verify the system end-to-end with a known, repeatable test before handing the line back to production.

End-to-end verification matrix
Test Method Pass Criterion
Encoder continuity Disconnect at encoder, ring out brown/blue/black/white to cabinet terminals with multimeter < 1 ohm supply, < 5 ohm signal
Encoder supply under load Measure 24 V at encoder terminals with engine running and hoist moving 22.0 V to 26.4 V (per IEC 61131-2)
Input waveform Scope at I 0.2 terminal, hoist moving at slow speed Clean 24 V square wave, no ringing above 30 V or below 0 V
PLC count accuracy Turn encoder exactly 10 revolutions, read counter CV in VAT Count = 10 x PPR (e.g. 10240 for 1024 PPR)
HMI live update Turn encoder at 60 rpm, observe HMI IO field for 10 s Count increments smoothly, no jumps, no freeze
Direction reversal Reverse motor, count should decrement or maintain via M 0.3 direction flag Direction flag toggles, count behaves per spec
Reference data clean Cross-reference the new M byte (e.g. MW 100) Only the counting FC and the HMI tag access this address

12. Specific Findings From the Reported Cell

The reported program has the following concrete characteristics that should be addressed in the engineering change order, regardless of the immediate HMI loss fix:

  • Symbol table audit: the symbols for MW 0, MW 50, and MW 52 must be unique and descriptive. If three different FCs use a generic symbol like Status_Word for three different physical words, refactor the symbol table to CountPulseBits, StatusMask, StatusResult.
  • FC ownership: every M bit or M word must have exactly one writer. The counting FC owns MW 0 in this application; the XOR/Status FC must read it, not write it. If a write is required, the FC must do it via a dedicated, renamed MW (e.g. MW 50) and the reader must read MW 50.
  • HMI tag bind-by-CV: rebind the hoist-position HMI tag to the IEC counter's CV or to ZW 0 for classic counters, never to a generic M word.
  • Clock memory move: move the clock memory configuration to a byte outside the user M area used for I/O mapping (e.g. MB 200 if the program is large, or disable clock memory entirely if not used).
Safety note: The mechanical hoist has a redundant limit-switch path that is independent of the encoder count. Do not disable the redundant path during commissioning. The encoder-based positioning is a precision refinement; the limit switches are the safety boundary. The relevant standard is ISO 13849-1 for safety-related parts of control systems. Verify the category and performance level (PL) required for the hoist application before re-commissioning.

13. Preventive Measures for the Next Cell

To avoid the same failure on the next encoder-equipped machine:

  1. Reserve an M-byte block per I/O island. Convention: MB 0...MB 9 for CPU clock memory (if used), MB 10...MB 19 for hoist 1, MB 20...MB 29 for hoist 2, and so on. Document in the project standard.
  2. Document the HMI tag source. In the HMI tag table, the comment field on every count tag should name the counter's instance DB and field. The commissioning engineer should be able to read the source of truth in one click.
  3. Add a watchdog or sanity tag. Add a non-critical HMI tag that mirrors M 0.2 and animates at 1 Hz. A frozen watchdog tag on the HMI immediately tells the operator which side is broken.
  4. Add reference-data review to the code review checklist. Every merge request must include a reference-data screenshot of the affected MW range.

With the steps above, an "M 0.2 count lost on HMI" report is reduced to a 15-minute lookup of the HMI tag's actual address plus a one-line check of the cross-reference for the relevant M byte.

FAQ

Is M 0.2 reserved in Siemens S7-300/400 CPUs?

No. M 0.2 is a normal user memory bit, identical to M 0.0, M 100.7, or M 1023.7. The only reserved M bits are the configured clock memory byte (in CPU properties under Cycle/Clock Memory) and any bits outside the configured M area size. If clock memory is enabled and the configured byte is MB 0, then M 0.0...M 0.7 are reserved as 0.05 Hz to 10 Hz clock outputs.

How do I find every consumer of M 0.2 in an S7 program?

Generate fresh reference data (Options -> Reference Data -> Display in STEP 7, or Program info -> Cross-references in TIA Portal), filter by MW 0, and inspect every read and write. Any FC that writes MW 0, MB 0, MB 1, or MD 0 clobbers M 0.2 because all four addresses share the same physical byte 0.

What does XOW do in STL, and why is it used with MW 0 in the program?

XOW is the 16-bit word XOR instruction. The pattern L MW 0; L MW 52; XOW; T MW 50 computes MW 50 = MW 0 XOR MW 52, which is a common way to toggle bits in a status word without a separate mask and copy step. The pattern is harmless to MW 0 because both loads are reads. The risk is only that another FC writes MW 0 in parallel and overwrites the pulse that the counting FC just set.

Why does the live count show in PLCSIM or VAT but not on the WinCC flexible / TIA Portal HMI?

The HMI tag is bound to the wrong address or its acquisition cycle is too long. Open the HMI tag table, confirm the PLC address matches the counter's current value (ZW 0 for classic S7 counters, or DBx.CV for IEC counters), and set the acquisition cycle to "Continuous" for live values. Re-compile and re-download the HMI project.

What Hohner encoder wiring should I expect for a 24 V PNP HTL incremental encoder to a Siemens DI module?

Brown to +24 V DC sensor supply, blue to 0 V, black to the digital input (e.g. I 0.2), white to the direction input (e.g. I 0.3) if used, drain/shield to the cabinet earth bar at the cable entry only. Verify 22.0-26.4 V at the encoder terminals with the hoist running, and verify a clean 24 V square wave at the input terminal with a scope. Long cables require shielded twisted pair, with the shield bonded at the cabinet end only to avoid ground loops.

Back to blog