S7-1200 TONR Retentive Timer and CTU Counter: TIA Portal Setup
The SIMATIC S7-1200 CPU 1214C exposes the IEC 61131-3 timer and counter family (TON, TOF, TP, TONR, CTU, CTD, CTUD) as software blocks whose state lives inside an instance data block. The most common commissioning complaint is that a TONR placed inside a Function (FC) appears to reset itself every time the FC is called. The root cause is that an FC has no static memory; a local instance is reconstructed from its initial value on each call. This reference walks through the root cause, the three robust solutions, the TIA Portal retain configuration, code examples, diagnostic flows, and verification steps.
1. IEC Timer and Counter Family on the CPU 1214C
The S7-1200 firmware library (refer to the S7-1200 System Manual, entry ID 109751784) provides the following blocks. The CPU does not reserve a hardware timer area; every timer is a software instance.
| Block | Function | Reset Input | Behavior at IN = 0 | Retentive on Power Cycle? |
|---|---|---|---|---|
| TON (On-delay) | Delays the rising edge of Q by PT | none (auto at IN=0) | Q = 0, ET = 0 | Only if instance is Retain |
| TOF (Off-delay) | Holds Q high for PT after IN falls | none (auto at IN=0) | Q = 1, ET held | Only if instance is Retain |
| TP (Pulse) | Generates a pulse of length PT | none (auto at IN=0) | Q = 0, ET = 0 | Only if instance is Retain |
| TONR (Retentive on-delay) | Accumulates elapsed time | R (explicit reset required) | ET preserved, Q held if ET ≥ PT | Yes, by design when instance is Retain |
| CTU (Up counter) | Counts rising edges on CU | R (explicit reset) | CV preserved | Yes, when instance is Retain |
| CTD (Down counter) | Counts down from PV | LD (explicit load) | CV preserved | Yes, when instance is Retain |
| CTUD (Up/Down counter) | Bidirectional count | R, LD | CV preserved | Yes, when instance is Retain |
TONR is the only block whose name implies retentive behavior, but every block above can be made retentive through the instance DB's Retain attribute.
1.1 CPU 1214C Relevant Specifications (firmware 4.4 and later)
| Parameter | Value |
|---|---|
| Number of IEC timers / counters | Limited only by work memory and data memory |
| Maximum time value PT / ET | T#24d20h31m23s647ms (32-bit signed ms) |
| Maximum count value CV | ±2,147,483,647 (DINT) |
| Retentive memory (work memory backed up) | 10 kB on CPU 1214C (6ES7214-1...) |
| Number of FB / FC / DB | Up to 1024 FBs, 1024 FCs, 1024 DBs (firmware dependent) |
| Backup without power | ~50–60 hours via maintenance-free super-capacitor |
The 10 kB retentive memory is shared between all retain-marked instance DBs, bit memories (M), and data blocks marked as retentive. A typical TONR instance consumes 16–32 bytes; a CTU instance consumes ~20 bytes. For exact part numbers, refer to the S7-1200 Function Manual entry ID 109798671 and the product page at siemens.com/s7-1200.
2. Why a TONR Resets in an FC: Root Cause Analysis
The S7-1200 stores the working variables of an IEC timer in an instance. The instance is a copy of the block's input, output, in/out parameters plus the static (STAT) area. When you call a TONR block from inside a Function (FC) directly, TIA Portal creates a local instance that is held in the FC's TEMP area. The TEMP area is reused on every call, and any instance data that the FC owns is initialized to the IEC initial values at the start of every invocation. This is the "automatic reset" symptom most engineers observe.
Three mechanisms contribute to the apparent reset:
- Local instance lifecycle. The FC owns the timer; when the FC is called, the timer is reconstructed from its initial value (ET = 0, CV = 0).
- Conditional FC calls. If the FC is only called under certain conditions (for example, in an OB that is not the cyclic OB1, or behind an if-then that gates the call), the timer is processed only on those calls. Retentivity can only be applied to instance data that survives across CPU STOP/RUN transitions, which is impossible for a local FC instance.
- No Retain attribute. A standalone global DB created when a block is placed inside an FC is marked as non-retain by default. Even if TIA Portal creates a backing DB, that DB has no Retain attribute set.
%FC1.statRunTimer or a similar local-internal path, the instance is local. If the path is DB_Timers.statRunTimer, the instance is in a global DB.3. Three Robust Solutions
3.1 Solution 1 — Multi-Instance Inside a Function Block (Recommended)
A Function Block owns a static instance data block whose values are preserved between calls. A multi-instance is a sub-instance declared inside another FB's STAT area.
Prerequisites:
- STEP 7 Basic (TIA Portal) V11 SP2 or later. Retain selection in the block properties is available from V11; TIA Portal V13+ provides an improved user interface.
- CPU 1214C with firmware 4.0 or higher (4.4 is current at the time of writing).
- An existing project with OB1 cyclic main program.
Procedure:
- In the project tree, right-click Program blocks → Add new block → Function Block. Name it
FB_MachineCycle, language LAD. - Open
FB_MachineCycleand drag a TONR block from the Timers folder into Network 1. - Click on the TONR block header. In the Inspector Properties → General, the calling convention is Multi-instance by default in TIA Portal V14+. Rename the instance to
statRunTimer. - Wire the inputs:
Network 1: "bStart" "statRunTimer" "bRun" ——TONR————————— IN ET Q PT = T#30s | | | R = "bReset" - Open the FB's Static tag table. TIA Portal exposes the new multi-instance as a static tag of type
IEC_TIMER. Click on the column Retain and select Retain for that tag. - Save and compile. From the right-click context menu of
FB_MachineCycle, choose Generate instance DB automatically when prompted. A new DB, for exampleDB_MachineCycle, is generated. - Right-click the new instance DB, choose Properties → Attributes and confirm that Retain is set on the relevant tags. The default retain attribute propagates from the FB's static definition.
- Call the FB from OB1: drag the FB into Network 1, assign a meaningful name such as
DB_MachineCycleto the instance DB. - Download to the CPU. The TONR will now retain its ET value across power cycles and across RUN→STOP→RUN transitions.
3.2 Solution 2 — Single Instance in a Global DB
If you must keep the calling block as an FC (for example, to call the same logic from multiple places without instantiating an FB), the TONR/CTU can be instantiated in a global DB.
- Add a new Global DB: Program blocks → Add new block → Data Block. Name it
DB_Timers. - In the new DB, declare a tag of type
IEC_TIMER(orIEC_COUNTER,IEC_SCOUNTER,IEC_DCOUNTER,IEC_USCOUNTER). Example:DATA_BLOCK "DB_Timers" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 STRUCT statCycleTimer : IEC_TIMER; // ~16-32 bytes statPartCounter : IEC_COUNTER; // ~20 bytes END_STRUCT; END_DATA_BLOCK - Click the Retain column for both tags and set it to Retain.
- In the FC, place a TONR block, click the instance selector above the block, and choose
DB_Timers.statCycleTimeras the instance. - Compile and download.
This method is functionally equivalent to a multi-instance but is visible in the project tree as a separate DB. With TIA Portal V14+ and optimized block access (the default for new DBs), the retentive attribute is set per tag, not for the whole DB.
3.3 Solution 3 — Keep the FC as a Local Instance but Force a Cyclic Call
In rare applications where the FC is the most appropriate block type, you can keep the TONR as a local instance in the FC and ensure the FC is called every scan. The TONR will then retain its ET for the duration of one RUN session, but it will not survive STOP→RUN or power-down. Use this only when running-state retention is acceptable.
To force a cyclic call:
- Always call the FC from OB1 unconditionally.
- If you need to call it from an FB, do not gate the call with a conditional branch that becomes false.
- Do not place the FC in an OB that runs only on events (time-of-day OB, error OB, startup OB).
This is the most common source of the "TONR resets by itself" complaint: the FC is correctly written, but it is called from a conditional branch or from a cyclic interrupt that is not actually triggered every cycle.
4. TIA Portal Code Examples (SCL, LAD, FBD)
4.1 TONR with Retain in FB (SCL)
FUNCTION_BLOCK "FB_MachineCycle"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR RETAIN
statRunTimer : IEC_TIMER; // retentive
END_VAR
VAR
bStart : BOOL; // input
bReset : BOOL; // input
bRun : BOOL; // output
END_VAR
BEGIN
// TONR: accumulate time, reset only on bReset
statRunTimer(IN := bStart,
PT := T#30s,
R := bReset,
Q => bRun);
END_FUNCTION_BLOCK
4.2 CTU with Retain in FB (SCL)
FUNCTION_BLOCK "FB_PartCounter"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR RETAIN
statCnt : IEC_COUNTER; // retentive
END_VAR
VAR
bPulse : BOOL; // count edge
bReset : BOOL; // reset
iCount : INT; // output
bDone : BOOL; // reached PV
END_VAR
BEGIN
statCnt(CU := bPulse,
R := bReset,
PV := 1000,
CV => iCount,
Q => bDone);
END_FUNCTION_BLOCK
4.3 LAD Network (TONR in FB)
Network 1: Retentive run timer ————————— | "bStart" "bRun" | ——| | | | | ——TONR————( )—— | | PT = T#30s | | R = "bReset" —————————
4.4 FBD Network (CTU in FB)
Network 2: Retentive part counter
"bPulse"
———|
|
———| ——CTU————— "bDone"
| CU | Q
| R |
| PV = 1000 |
| —— "iCount"
CV
"bReset"—————
5. Setting the Retain Attribute in TIA Portal
The path to set retain depends on the TIA Portal version. The following steps apply to TIA Portal V16/V17/V18 (current at the time of writing).
5.1 Retain for Multi-Instance Tags (FB static)
- Open the FB that contains the multi-instance.
- Click on the Static interface row for the
IEC_TIMER/IEC_COUNTERtag. - In the Inspector Properties → Retain, choose one of:
- Non-retain: tag is reset to its initial value on STOP→RUN and on power-up.
- Retain: tag is preserved across STOP→RUN, RUN→STOP, and power cycles, within the limits of the CPU's retentive memory.
- Set in IDB: the actual setting is taken from the instance DB; allows the same FB to be used with different retain behaviors for different instances.
- For a TONR application, select Retain.
5.2 Retain for Tags in a Global Instance DB
- Open the global DB that owns the
IEC_TIMERorIEC_COUNTERinstance. - Switch to the Data view.
- Click the Retain column of the relevant tag. A check mark indicates the tag will be retained.
- For a TONR application, the ET and the Q are part of the
IEC_TIMERstructure; selecting Retain on the parent tag is enough.
5.3 Retain for the Whole Instance DB (Non-Optimized Blocks)
- Right-click the instance DB in the project tree.
- Select Properties.
- Under Attributes, tick IEC retain. This is required only if the block access is set to "standard" (non-optimized). With optimized access, retain is a per-tag property.
6. CTU Counter Considerations and Counter Types
The CTU counts rising edges on input CU. With TIA Portal V14+, the IEC_COUNTER type (32-bit signed) is the recommended choice for new applications. For HMI displays and arithmetic, the 32-bit counter is preferred. The legacy 16-bit S5-style counter (S_CU) is still available but is not part of IEC 61131-3.
| Use case | Type | Size | Retain strategy |
|---|---|---|---|
| Count machine cycles, retain across shifts | IEC_COUNTER (CTU) | 32-bit signed | Retain on the instance |
| Track remaining cycles (count down from PM interval) | CTD | 32-bit signed | Retain on the instance |
| Bidirectional buffer position | CTUD | 32-bit signed | Retain on the instance |
| Short pulses counted per scan (less than 32k) | IEC_SCOUNTER (CTU_S) | 16-bit signed | Retain optional |
| Large count up to 2^31-1 | IEC_COUNTER | 32-bit signed | Retain required |
CTUD counts up on the rising edge of CU and down on the rising edge of CD; if both CU and CD are true in the same scan, CD wins (down-count). The output QU fires when CV ≥ PV; the output QD fires when CV ≤ 0. Retention works identically to TONR: the CV value is held if the instance is marked retentive.
7. Diagnostic Matrix and Error Codes
| Symptom | Most Likely Cause | Verification Step | Fix |
|---|---|---|---|
| ET returns to 0 every scan | TONR is a local instance in an FC | Inspect call site: is the FC called every cycle from OB1? | Move TONR into an FB as a multi-instance, or to a global DB instance |
| ET returns to 0 on STOP→RUN | Instance DB or tag not marked Retain | Check the FB static or DB tag retain attribute | Set Retain on the IEC_TIMER tag |
| ET returns to 0 on power-down | Retentive memory not configured for the data block | Check PLC → Properties → Memory and Clock bits | Increase "Retain" memory or set tag retain |
| ET counts to PT and Q goes high, but then Q goes low again | IN signal is dropping to 0 between calls | Use a status viewer to see the IN bit in real time | Hold IN high; use a latching input with explicit R |
| Counter CV resets on a power cycle even though DB is retentive | CPU retentive memory exhausted | Check diagnostic buffer for "Retain memory error" or "Loss of retain data" | Reduce number of retentive tags or upgrade to larger CPU |
| Compilation error "Instance cannot be multi-instance" | Trying to declare a multi-instance in an FC static | FCs do not have a static area | Move to FB or use a global DB |
| TONR ignores the R (reset) input | Reset signal is not a rising edge but a level | Make R a one-shot (R_TRIG) | Use a rising-edge R_TRIG ahead of the R input |
7.1 Common Error Codes
| Error Code (Hex) | Origin | Cause | Remedy |
|---|---|---|---|
| 0x0001 | IEC block | Generic internal error | Reboot CPU; check firmware |
| 0x0002 | CTU/CTUD | CV overflow | Use 32-bit counter; reset before reaching limit |
| 0x4302 | CPU diagnostic buffer | Loss of retain data | Verify backup time, check retain attribute |
| 0x4303 | CPU diagnostic buffer | Retain memory size mismatch | Adjust retentive memory in CPU properties |
| 0x4503 | CPU | Re-entrancy error: block called in OB that is not allowed | Check that the FB/FC is not called in startup OB while still being initialized |
8. Verification Procedure
8.1 Online Verification in TIA Portal
- Establish an online connection to the CPU 1214C and go online.
- Open the FB that contains the TONR multi-instance.
- Click Monitor all (the glasses icon). The ET field displays the current elapsed time in T# format.
- Force IN to TRUE. Watch ET increment each second. Force IN to FALSE. ET must hold.
- Force R to TRUE. ET must return to 0.
- Toggle the CPU to STOP, then back to RUN. ET must be preserved.
- Cycle power to the PLC. After power-up, force the same online view. ET must be preserved.
8.2 Programmatic Verification via HMI / Web Server
If a SIMATIC HMI is connected, expose the static tag of the FB instance (for example, DB_MachineCycle.statRunTimer.ET) as an HMI tag. The HMI will display the same value seen in the online monitor. For the S7-1200, the user-defined web server (activated in CPU properties) can also be used to display the value.
8.3 Diagnostic Buffer Inspection
If retention is lost on power-up, open Online & Diagnostics → Diagnostic buffer and look for events such as:
- Loss of retain data (event ID 0x4302): the retentive memory contents were lost. Indicates either a power-down exceeding the CPU's backup capacitor time, or that the backup was explicitly disabled.
- Retain memory error (event ID 0x4303): the configured retentive memory size is inconsistent with the actual data that needs to be retained.
The CPU 1214C has no battery; retain is maintained by a maintenance-free super-capacitor that holds the data for typically 50 to 60 hours after power removal. If the panel has been unpowered longer than this, the retentive data is lost regardless of the software configuration. For applications requiring longer backup, install the optional SIMATIC Memory Card (SMC) and set the data block property Store in load memory to true.
9. Best Practices, Edge Cases, and Migration Notes
9.1 Best Practices Checklist
- Always instantiate a TONR (or any IEC timer that must accumulate) in an FB as a multi-instance, or in a global DB. Never in an FC.
- Set the Retain attribute on the
IEC_TIMER/IEC_COUNTERtag, not on the entire DB (with optimized block access). - Use TIA Portal V16+ where possible; the optimized block access model is the default and yields clearer retain behavior.
- Group all retentive tags of an FB under a
VAR RETAINblock in SCL for readability. - Avoid the S5-style counters (S_CU, S_CD) for new applications. The IEC_COUNTER types are clearer and portable to S7-1500.
- Always wire the R input of TONR/CTU with a defined reset condition. An un-wired R is a common source of "the timer never resets" confusion.
- Document the meaning of the Retain attribute in the block header comment of the FB, especially if "Set in IDB" is used.
9.2 Field-Proven Edge Cases
- Reset timing. The R input of TONR/CTU is level-sensitive. If R is held high, the timer/counter never starts counting. For a one-shot reset, pulse R with an R_TRIG block.
- Very long times. PT can be up to T#24d20h31m23s647ms, but the implementation uses 32-bit signed milliseconds. Do not pass a negative TIME value; the runtime behavior is undefined.
- PT in DBs. When PT is read from a DB tag rather than a literal, the IEC block re-reads the value every scan. If you change PT during operation, the new value takes effect on the next scan. For TONR, ET is not reset by changing PT.
- Multiple assignment of the same instance. A frequent error is to assign the same multi-instance tag to two FBs. TIA Portal will compile but the behavior is undefined. Always create one multi-instance per FB that needs it.
- Implicit reset on download. Downloading a new program to the CPU does not reset the retain memory by default. The behavior is governed by Reset retain memory on download in the online menu, which is off by default. If you want a clean state after a download, toggle this option once.
9.3 Migration Notes (S7-300/400 → S7-1200)
- The legacy S5-style timers S_ODT, S_PULSE, etc. are not available on the S7-1200. Replace with TONR, TP, TOF as appropriate.
- The S7-300/400 had a fixed hardware-based timer area (T0..T255 on an S7-300). The S7-1200 has no such area; every timer is a software instance.
- The S5-style counter (C0..C255) does not exist on the S7-1200. Replace with CTU, CTD, or CTUD.
- The "Retentive on power failure" property of legacy timers/counters is replaced by the Retain attribute on the instance data block.
The migration tool in TIA Portal warns about unsupported timer/counter references. After migration, verify that the generated FB has the Retain attribute set on the IEC_TIMER/IEC_COUNTER multi-instance tags.
9.4 Performance Considerations
Each IEC timer/counter call consumes a small but measurable amount of CPU time. Typical figures for the CPU 1214C:
| Block | Approximate Execution Time (μs) |
|---|---|
| TON, TOF, TP | 2 – 4 |
| TONR | 3 – 5 |
| CTU, CTD, CTUD | 2 – 4 |
For applications with thousands of timers (for example, batch tracking of thousands of positions), the aggregate cost can add up. If the scan time is critical, gate the timer call with the input condition so that the IEC block is only executed when its IN transitions from 0 to 1.
9.5 Connection to HMI and OPC UA
When a retentive timer is used as the runtime counter of a machine, the ET and CV values are typically exposed to the operator panel. With optimized block access (default in TIA Portal V14+), the HMI tag is created by browsing the DB and selecting the relevant member:
- Path:
DB_MachineCycle.statRunTimer.ETfor the elapsed time - Path:
DB_PartCounter.statCnt.CVfor the count value
In WinCC (TIA Portal) or on a SIMATIC Comfort Panel, the HMI tag points directly at the optimized DB member. The data is exchanged via the S7 communication protocol; the operator panel does not need to know that the value is retentive.
If the CPU 1214C is configured as an OPC UA server (firmware 4.4+ with the OPC UA license), the same data is exposed over OPC UA. A SCADA system can subscribe to the value and display it on a dashboard. The OPC UA subscription continues to receive updates during power cycles because the next published value is the retained value.
10. Diagrams: Topology and State Machines
10.1 Topology
10.2 TONR State Diagram
The key behavioral difference between TON and TONR is visible: in TON, IN = 0 returns the timer to Idle immediately; in TONR, IN = 0 holds the current ET value and only R = 1 resets it.
10.3 Internal Memory Layout of IEC_TIMER
TIA Portal exposes the internal data structure of these system-defined types. Knowing the layout is useful for advanced diagnostics.
TYPE IEC_TIMER
STRUCT
IN : BOOL; // input: enable counting
PT : TIME; // preset time
Q : BOOL; // output: ET >= PT
ET : TIME; // elapsed time
STATE : BYTE; // internal state (running, expired, etc.)
STIME : TIME; // start time stamp (relative)
END_STRUCT;
END_TYPE
The STATE byte of IEC_TIMER is internal and should not be modified from user code. Modifying it is a common cause of "the timer behaves inconsistently" support calls.
11. Frequently Asked Questions
Why does my TONR reset when the FC is called?
Because a local instance inside a Function (FC) is reconstructed every time the FC is called. The TONR's elapsed time is not stored in a retained instance DB, so it is initialized to zero on each call. Move the TONR into a Function Block (FB) as a multi-instance, or instantiate it in a global DB, and set the Retain attribute on the tag.
Do I need to use TONR, or is a TON with retain also valid?
A TON with a Retain-marked instance is functionally equivalent to a TONR when the input is held high. The practical difference is that TON resets its ET to 0 automatically when IN returns to 0, while TONR holds the accumulated ET and only resets when R is asserted. For accumulating run-time across process interruptions, use TONR.
How long does the CPU 1214C keep retain data without power?
Typically 50 to 60 hours, supported by an internal maintenance-free super-capacitor. For longer backup, the optional SIMATIC Memory Card can be used to store retentive data to load memory on shutdown. Verify the diagnostic buffer entry if the CPU reports loss of retain data.
Can I have more than one TONR in the same FB?
Yes. Declare each as a separate multi-instance tag in the FB's Static interface. Avoid declaring the same IEC_TIMER tag in two different FBs, which would create two separate instances that do not share state.
Why does my counter reset on STOP→RUN but a TONR with the same settings does not?
Both behaviors depend on the Retain attribute of the instance. If only the TONR is marked Retain and the CTU is not, the CTU will be reset to its initial value on every STOP→RUN transition. Mark both tags as Retain for consistent behavior.
Is the IEC_TIMER a system data type or a UDT?
IEC_TIMER is a system-defined data type (SDT) provided by the S7-1200 system library. It is a structure containing inputs (IN, PT, R), outputs (Q, ET), and internal static fields. It is portable between S7-1200, S7-1500, and S7-300/400 with minor differences.