S7-1200 IEC Counter Retentivity Reset Issue: Root Cause and Fix

David Krause11 min read
S7-1200SiemensTroubleshooting
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

Problem Overview

On Siemens SIMATIC S7-1200 (CPU 1211C/1212C/1214C/1215C/1217C, firmware V4.2–V4.6) and S7-1500 (CPU 1511–1518, firmware V2.5–V3.0) controllers programmed in TIA Portal V15.1 through V18, an IEC counter (CTU, CTD, or CTUD) configured with a self-clearing reset wired from the negated counter output (/Q) appears to lose its accumulated value on a STOP-to-RUN transition, power-off/power-on cycle, or warm restart, even when the "Retentivity" option is enabled in the function block instance properties.

The classical symptom is:

  • Counter increments correctly while the PLC is in RUN.
  • The "Retain" flag is set on the instance DB (or the IEC counter tag is marked retentive in the PLC tag table).
  • When the power supply is removed (or the CPU is stopped and restarted), the counter value returns to zero instead of the last accumulated value.

The cause is rarely the retentivity mechanism itself; it is almost always a logic race between the reset input and the negated output at the moment the user program starts scanning after a restart.

Root Cause Analysis

Two separate mechanisms collide during a cold/warm restart:

  1. Output Q initializes to FALSE. When the IEC counter instance is created with retentivity enabled, the CV (current value) is preserved across the restart, but the Q boolean (the threshold-reached bit) is not guaranteed to be TRUE until the OB1 main scan evaluates the counter for the first time. For a brief window at the top of OB1, Q = FALSE.
  2. Negated output /Q is therefore TRUE. A wire from /Q directly to the R (reset) input of the same counter presents a logic TRUE at the reset input during that first scan, which clears the retained CV to zero before the user has any opportunity to react.

The retained value is therefore valid in the instance DB image, but it is destroyed within the first program cycle of OB1 because the reset path is unintentionally active. This explains why checking the "Retentive" box in the instance properties appears to have no effect.

Critical: Retentivity protects the bit/word/byte from being overwritten by the CPU's restart OB during a power-off cycle. It does not protect a value from being overwritten by your own program logic in the first scan after restart. Any wiring that can drive the counter reset to TRUE before or during the first evaluation of Q will defeat retentivity.

Why a Negated Self-Reset Fails on Power Cycle

The wiring pattern at the centre of the problem looks like this in FBD/LAD:

      +---------+
      |         |
  CU-->|   CTU   |--Q----[ Output / use ]
      |  PV=5   |
CV_in-->|         |---/Q--+--> R (reset input)
      +---------+        |
                         |
                         +--- (back to same counter)

In a steady-state RUN, when CV reaches PV:

  • Q = TRUE
  • /Q = FALSE
  • Reset input sees FALSE; counter stays at PV, downstream logic activates.

During a power-off/power-on or STOP→RUN transition:

  • Retained CV is restored from the load memory / work memory image (subject to retentivity configuration).
  • Q is reset to FALSE by the CPU startup logic at the start of OB1.
  • /Q = TRUE on the very first scan.
  • The reset input is asserted, which forces CV to zero before the program has completed one full scan.

The retentive image of CV in the instance DB is therefore overwritten on the first scan, making it appear that retentivity is broken.

Affected Firmware and Software Versions

Component Versions Where the Issue Is Observed
S7-1200 CPU 1211C DC/DC/DC, 1212C, 1214C, 1215C, 1217C — firmware V4.0 through V4.6
S7-1500 CPU 1511-1 PN, 1513-1 PN, 1515-2 PN, 1516-3 PN/DP, 1517-3 PN/DP, 1518-4 PN/DP — firmware V1.8 through V3.0
ET 200SP CPU 1510SP-1 PN, 1512SP-1 PN — firmware V1.8 through V2.9
TIA Portal V15.1, V16, V17, V18 (engineering)
IEC counter FB CTU (FB count up), CTD (count down), CTUD (count up/down)

Reference: TIA Portal cloud documentation — Counter operation (IEC counters).

Solution Architecture

Three independent fixes can be applied. Use one of them — not all three at once — depending on the structure of the rest of your program.

Fix 1: Eliminate the Negated Self-Reset (Recommended)

Replace the direct /Q → R wiring with an explicit one-shot that fires only when the counter has just reached the preset. This is the most robust pattern and is independent of scan order on startup.

// STL equivalent (S7-1200/S7-1500)
A   "DB_Counter".Q          // Q bit of the CTU instance
FP  "Tag_EdgeReset"         // positive edge flag, retentive not required
=   "DB_Counter".R          // drive R from a one-shot pulse

The rising edge of Q produces exactly one scan of R = TRUE. After the counter clears, Q goes FALSE, the edge detector resets, and the reset input is released. On a power cycle the retained CV is restored, Q is FALSE at scan zero, no edge is detected, and the value is preserved.

Fix 2: Use the Same Threshold for ON and OFF

For simple two-position counters where the upstream signal needs to stay ON until the counter reaches the preset, set both the ON and OFF parameters to the same value (for example, 5 / 5). This produces a one-shot behaviour without any auxiliary flag:

  • Counter starts incrementing while the input is TRUE.
  • When CV reaches the preset, Q goes TRUE and the counter auto-resets (depending on FB variant), producing exactly one pulse.
  • On restart with retained CV equal to PV, no fresh pulse is generated because the threshold has already been satisfied.

Fix 3: Store Counter Value in a Global Retentive DB

If the application requires custom counters implemented in SCL rather than the standard CTU FB, place the counter word inside a global data block whose "Retain" attribute is set to Retain. This guarantees that CV is restored from the retentive memory area even if a one-shot logic ever misfires.

// SCL custom counter in a global DB named "DB_RetentiveCnt"
IF "bCountUp" THEN
    "DB_RetentiveCnt".CV := "DB_RetentiveCnt".CV + 1;
END_IF;

IF "DB_RetentiveCnt".CV >= "DB_RetentiveCnt".PV THEN
    "DB_RetentiveCnt".Q := TRUE;
ELSE
    "DB_RetentiveCnt".Q := FALSE;
END_IF;

IF "bReset" THEN
    "DB_RetentiveCnt".CV := 0;
END_IF;

Open the DB properties in TIA Portal → "Attributes" and set the "Retain" value to Retain (not Non-retain) for the CV and Q tags. Per the Siemens S7-1200 manual collection, only data stored in a global DB or a multi-instance DB is eligible for retentive behaviour beyond the standard PLC tag retain area.

Step-by-Step Implementation in TIA Portal V18

  1. Open the project and navigate to the program block containing the IEC counter (e.g., OB1 "Main" or a cyclically called FB such as FB_Count).
  2. Right-click the counter instance and select "Change instance DB" if you want the data to remain in a multi-instance DB (default for FBs). For retentive data, prefer a global DB approach instead — see Step 3.
  3. Insert a new global DB: Project tree → Program blocks → Add new block → Data block. Name it DB_CounterRet. Open its properties → Attributes → Retain = Retain.
  4. Inside the DB, add tags of the appropriate type:
    TYPE "DB_CounterRet"
    VERSION : 0.1
    NON_RETAIN
       STRUCT
          CV : INT;       // current value, retain
          PV : INT;       // preset value, retain
          Q  : BOOL;      // threshold reached, retain
          R  : BOOL;      // reset request, NOT retain
          Edge : BOOL;    // edge memory for FP, retain
       END_STRUCT;
    END_TYPE
  5. Rewrite the counter logic in SCL using a rising-edge detector for the reset:
    IF "DI_Count" AND NOT "DB_CounterRet".Edge THEN   // rising edge of count pulse
        "DB_CounterRet".CV := "DB_CounterRet".CV + 1;
    END_IF;
    "DB_CounterRet".Edge := "DI_Count";
    
    IF "DB_CounterRet".CV >= "DB_CounterRet".PV THEN
        "DB_CounterRet".Q := TRUE;
    END_IF;
    
    IF "DB_CounterRet".Q AND NOT "Tag_ResetLatch" THEN
        // one-shot reset
        "DB_CounterRet".CV := 0;
        "DB_CounterRet".Q := FALSE;
    END_IF;
    "Tag_ResetLatch" := "DB_CounterRet".Q;
    
  6. Compile the block (Ctrl+B) and download to the CPU.
  7. Open the online view: Project → Online → Go online. Force CV to 3 and trigger a STOP→RUN transition. Confirm that CV stays at 3 and that Q does not flicker.

Configuring Retentivity Correctly

There are three places where retentivity is configured in TIA Portal, and confusing them is the second most common cause of "my counter still resets" tickets.

Location Setting What It Retains
PLC tag table Retain column = "Retain" or "Non-retain" Global tags declared in the tag table
Instance DB of an FB Right-click the tag → Properties → Retain Tags inside a single-instance DB
Global DB DB properties → Attributes → Retain All tags inside the global DB unless overridden per tag
Multi-instance DB FB declaration: "Retain" = SET in the FB interface Static tags of the FB

To retain a value across a power cycle, the tag must reside in one of the retentive areas and the program must not write to it during the first OB1 scan after restart. The TIA Portal cloud documentation confirms that counter data is made retentive by assigning the IEC counter block to a global DB or a multi-instance DB whose Retain attribute is set to Retain.

Verification Procedure

  1. Download the modified program to the CPU.
  2. Place the CPU in RUN. Increment the counter to a known value (for example, CV = 4 with PV = 5).
  3. Open Online & Diagnostics → Online & Diagnostics, then perform a STOP followed by RUN. Watch the CV tag in the watch table; it must read 4 within 100 ms of the RUN transition.
  4. Cycle power to the PLC (turn off the 24 V supply, wait 10 seconds, restore). Confirm that CV is still 4 on the first scan after restart.
  5. Repeat with CV at the preset (CV = PV) and confirm that Q is TRUE immediately on RUN, not FALSE-then-TRUE.
  6. Trigger a warm restart (MRES) to verify the value is also preserved across a cold start if desired.

Alternative Counter Patterns

For complex applications, consider one of these patterns instead of CTU with self-reset:

  • IEC CTUD with manual reset flag: Use CU for the count input, CD tied to FALSE, and R driven from an explicit one-shot. The QU output reflects the threshold and is never wired back to R.
  • SCL counter in a global retentive DB: See Fix 3 above. Best for tallies that need to survive both power cycles and download-without-retain.
  • System clock / runtime counter (SFB 4 / SFB 5): For elapsed-time counting, use the runtime meter blocks; their values are retained automatically by the operating system.

Troubleshooting Matrix

Observed Behaviour Likely Cause Corrective Action
Counter resets every cycle even in steady RUN Negated output /Q wired directly to R without edge detection Replace with rising-edge detector or explicit one-shot
Counter resets on STOP→RUN R input is TRUE during scan zero because Q initializes FALSE Use an edge detector that requires a TRUE→TRUE transition
Counter resets on power cycle Tag is in non-retentive memory, or retentive tag is overwritten in scan 1 Move tag to global DB with Retain attribute; add first-scan guard
Counter loses value after download (online) Download overwrites the load memory image used for retention Use "Download to device → Keep current values" or first-scan initial value of 0
Counter increments twice per pulse Edge memory is in non-retentive area, causing phantom edges after restart Place edge memory in retentive area
Counter retains but Q is wrong Q not marked retentive, so it initialises FALSE on restart Mark Q as retentive OR recompute it from CV >= PV on every scan

Field-Proven Caveats

  • On S7-1200 firmware V4.0 and earlier, the maximum number of retentive tags is limited (typically 4 KB for bit memory, 8 KB for DB tags). Always check the CPU's "Memory" section in the device configuration before declaring large counter arrays retentive.
  • If the program is downloaded with the "Reset to factory settings" option, all retentive data is lost by design. Verify that the operator PC is configured for "Download to device — Keep current values" when working with production counters.
  • The "Retain" attribute is only honoured by warm restart and hot restart. A cold restart (power-on after a memory reset) reinitialises all values to their declared initial values regardless of the Retain setting.
  • For applications that must survive a firmware update, place the counter in a global DB and document its tag names in the project change log. Re-creating the DB during an update overwrites the data.
  • When using the negated output of an IEC counter in a multi-instance FB, the negation is resolved at runtime, not at compile time. The same race condition applies regardless of whether the counter is called once or multiple times in the cycle.

Why does my S7-1200 CTU counter reset even though I checked Retentive?

Because your program is forcing the reset input TRUE during the first scan after restart. The IEC counter's Q output is FALSE at scan zero, so /Q is TRUE and clears the retained CV. Replace the direct /Q → R wiring with a rising-edge detector on Q.

Where do I configure retentivity for an IEC counter in TIA Portal?

Open the counter's instance DB (or the global DB containing the counter tags), go to Properties → Attributes and set Retain = "Retain" for the CV and Q tags. The same setting is available in the PLC tag table for global tags. Per the TIA Portal S7-1200 manual collection, only data in a global DB or multi-instance DB is fully supported for retentive counter values.

Does an S7-1500 counter survive a STOP-to-RUN transition without retentivity?

No. Without an explicit Retain attribute the tag is reinitialised to its declared start value (typically 0) on every STOP→RUN transition. Mark the counter tag as retentive if it must keep its value across a CPU stop or power cycle.

Can I keep the negated self-reset pattern and still have retention?

Only if you add a startup-OB or first-scan flag that suppresses the reset for the first cycle. This is fragile and harder to maintain than switching to an edge-triggered one-shot. The recommended pattern is rising-edge detection on Q driving the reset input.

What is the maximum retentive counter value on an S7-1200?

For an INT counter it is 32 767. For DINT it is 2 147 483 647. The overall retentive memory size depends on the CPU model — for example, the CPU 1214C allows up to 10 KB of retentive DB data, while the CPU 1217C allows 50 KB. Always verify in the device configuration of your specific CPU.

Back to blog