Configuring RETAIN Tags in TIA Portal for S7-1200/1500 PLCs

David Krause12 min read
SiemensTIA PortalTutorial / How-to
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

Overview

Retentive tag behavior is fundamental to elevator control, conveyor tracking, batch recipes, and any application where a process variable must survive a power cycle or CPU STOP-to-RUN transition. In TIA Portal, a tag declared as RETAIN keeps its last value after power-off, restart, and STOP→RUN transitions, while a NON-RETAIN (volatile) tag is reset to its initialization value on every restart.

The TIA Portal interface presents the Retain column as a selectable attribute on global data blocks (DBs), but on the PLC tags table it is grayed out by default. The reason is that the PLC tags table is a symbolic name list bound to fixed memory areas (M, I, Q, etc.). The retentive attribute for M memory is enforced globally by the CPU, not by the tag. Engineers frequently misinterpret this as "the Retain option is broken" or "TIA Portal does not support retain." In reality, the option is simply not user-editable on the M, I, or Q areas because retention is controlled at the CPU's Retentive memory configuration.

This article walks through the two correct ways to make tags retentive in TIA Portal — (1) defining retentive memory bytes in the CPU properties, and (2) declaring RETAIN attributes inside a global DB — and applies both to a practical elevator floor-position variable.

Prerequisites

  • STEP 7 / TIA Portal V16 or later (V17 or V18 recommended for current firmware). Earlier versions of TIA Portal V13–V15 follow the same logic but have minor dialog differences.
  • A Siemens S7-1200 (firmware V4.2 or later) or S7-1500 (firmware V1.8 or later) CPU. Retain behavior for S7-300/400 differs and is not covered here.
  • PLC hardware catalog reference for the CPU in your project to confirm the maximum number of retentive MB, timers, and counters.
  • Online connection to the CPU (or a PLCSIM instance) for runtime verification.

Memory Areas in S7-1200 and S7-1500

Both families split the load memory (formerly work memory in S7-300/400) and work memory into volatile and non-volatile regions. Retentivity is implemented in on-chip SRAM backed by a maintenance-free super-capacitor on S7-1200 and by the optional SIMATIC Memory Card on S7-1500.

S7-1200 Retentivity Rules

  • Bit memory (M): bytes starting from MB0 are retentive up to the count defined in CPU properties → Retentive memory.
  • Process image of inputs (I) and outputs (Q): never retentive.
  • Timers and counters (T, C): retentive counts are set in the same dialog; up to 2048 of each on S7-1214C and above.
  • Global DB variables: each tag has its own Retain attribute that overrides CPU-level settings.

S7-1500 Retentivity Rules

  • Bit memory bytes, counter, and timer counts are configured under Properties → Retentive memory.
  • DBs may be set to Non-retain (default) or Retain at the DB level. A fine-grained per-tag Retain / Set in IDB / Non-retain selection is available when Optimized block access is enabled.
  • The S7-1500 stores retentive data in NVRAM (battery-less) plus a small protected area. The Memory Card is mandatory for firmware updates; runtime retention does not require it.

Method 1 - Enable Retentive Memory Bytes in the CPU

This is the fastest way to keep M flags (M0.0, MW2, MD4, etc.) alive across power cycles. It is the right method for small ladders that already use M memory and do not want to refactor to a DB.

Step-by-Step Procedure

  1. In the project tree, expand the CPU and double-click Device configuration.
  2. In the device view, select the CPU module so that the Properties pane appears in the inspector window.
  3. Navigate to Properties → General → Retentive memory (or Memory on older TIA versions).
  4. Enter the number of retentive memory bytes starting at MB0. For an elevator application, a value of 10 bytes is usually enough to cover the floor request, current floor, and a few status flags.
  5. Define the retentive timer count and counter count. For an elevator you typically do not need retentive T/C; leave the default 0 unless you are storing accumulated call counts.
  6. Click Save project and download the hardware configuration to the CPU. The new retentivity range takes effect on the next STOP→RUN transition.

Memory Cost Table for the S7-1200 Family

CPU Work memory Retain range (MB0..) Max timers Max counters
CPU 1211C 50 KB 0–1024 bytes 2048 2048
CPU 1212C 75 KB 0–1024 bytes 2048 2048
CPU 1214C 100 KB 0–1024 bytes 2048 2048
CPU 1215C 125 KB 0–1024 bytes 2048 2048
CPU 1217C 150 KB 0–1024 bytes 2048 2048
CPU 1212C DC/DC/DC (FW 4.4) 75 KB 0–2048 bytes 2048 2048

Reference: SIMATIC S7-1200 Programmable Controller System Manual (entry ID 109741593).

Step-by-Step Procedure (S7-1500)

  1. Open Device configuration on the CPU.
  2. Choose Properties → Retentive memory.
  3. Enter the number of memory bytes, S7 timers, and S7 counters. A 30-byte range is typical for elevator control logic plus diagnostics.
  4. Compile and download. The S7-1500 needs a stop run cycle before the new retentivity range is active.

Method 2 - Set the Retain Attribute in a Data Block

Using a global DB is the recommended method for new code. It separates the data layout from the CPU, supports optimized block access, and provides the per-tag Retain checkbox that beginners expect to see.

Create a Global Data Block

  1. In the project tree, right-click Program blocks → Add new block → Data block.
  2. Name the block (e.g. DB_Elevator) and select type Global DB.
  3. Open the new DB; the editor will show a table of tags. To expose the Retain column, right-click the column header and tick Retain in the selection dialog. By default TIA Portal hides it, which is the most common reason engineers think the option is missing.
  4. Declare the elevator variables:

Sample DB Layout for an Elevator

Name Data type Initial value Retain Purpose
CurrentFloor INT 1 ✓ Last cabin position (1..N)
TargetFloor INT 1 ✓ Pending floor request
DoorState INT 0 ✗ 0=closed, 1=open
CallUpFloor1 BOOL FALSE ✗ Latched car call (re-armed on next STOP→RUN)
CallUpFloor2 BOOL FALSE ✗ Latched car call
CallDownFloor3 BOOL FALSE ✗ Latched hall call
FaultLatched BOOL FALSE ✓ Persistent fault indication
TripCount DINT 0 ✓ Cycle counter, survives power-loss
Note on initialization: The Initial value column is loaded on every STOP→RUN transition only when the tag is non-retain. For a RETAIN tag the initial value is loaded only on the first download of the program or when the user explicitly executes Reset → Retentive data from the online menu.

Per-Tag Retain Checkbox Workflow

  1. Open the DB.
  2. Select the row for CurrentFloor.
  3. In the right-hand Properties pane, expand Attributes and set Retention to Set in IDB (optimized block access only).
  4. Tick the per-tag Retain checkbox on the row, or set it via the Retention column in the row view.
  5. Save and compile the project.

Reference: SIMATIC S7-1500 Automation System System Manual (entry ID 59191792), section "Retentivity of data".

Practical Example - Elevator Floor Hold on Power Loss

Apply the two methods side by side to keep the elevator's cabin position across a brief power interruption.

Method 1: Using MB0

// CPU properties: Retentive memory bytes from MB0 = 10
// Symbol table / PLC tags
// Name            Address    Type
// iCurrentFloor   MW0        INT     // Retentive because MB0..MB9 are retentive
// iTargetFloor    MW2        INT     // Retentive
// bCabinAtFloor   M4.0       BOOL    // Retentive

// Ladder segment (FC_CarLogic)
A     "iCabinCall"            // Car call pushbutton
JCN   end
L     "iCurrentFloor"        // Current floor value (retained)
T     "iTargetFloor"         // Store as new target, retained
end:  NOP 0
Address overlap warning: M0.0 and M0.1 are bits inside MW0, and M0.2–M0.7 are bits inside MW1. If you declare CurrentFloor as MW0 and TargetFloor as MW2, you are not overlapping. However, if you also use M0.1 for a flag, you are aliasing the low bit of CurrentFloor. Always plan the retentive byte map before placing tags.

Method 2: Using a Global DB

// DB_Elevator (optimized block access enabled)
DATA_BLOCK "DB_Elevator"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
NON_RETAIN
   STRUCT
      CurrentFloor  : INT := 1;    // RETAIN
      TargetFloor   : INT := 1;    // RETAIN
      DoorState     : INT := 0;    // NON-RETAIN
      FaultLatched  : BOOL := FALSE; // RETAIN
      TripCount     : DINT := 0;    // RETAIN
   END_STRUCT;
END_DATA_BLOCK

// OB1 - "Main" sweep
A     "iCarCallFloor3"     // Car call input
JCN   no_call
L     3
T     "DB_Elevator".TargetFloor  // Persisted across power cycle
no_call: NOP 0

Verification Procedure

  1. Compile the project (Project → Compile → All). Resolve all warnings; a warning about "retentive memory exceeds CPU limit" will block download.
  2. Go online with the CPU.
  3. Open the watch table for the DB or for the M memory and force CurrentFloor = 5.
  4. Perform a power cycle on the PLC (or use Online → Restart → Cold restart for a controlled STOP→RUN). If you used Warm restart, retentive data is preserved by definition; choose Cold restart to truly verify retention rules.
  5. Re-open the watch table. CurrentFloor should still read 5. If it returns to 1, retention is not active — revisit Method 1 or Method 2.
  6. For a negative test, go to Online → Reset → Retentive data. All RETAIN tags must reset to their Initial value.
Diagnostic tip: With the CPU in STOP, open Online & Diagnostics → Memory. The "Retentive area" field will display the active range. If it reads 0 bytes, your CPU properties did not download.

Common Pitfalls and How to Avoid Them

Symptom Likely cause Remedy
Retain checkbox grayed out on PLC tag Retain is not configurable on the PLC tags table Move the tag into a global DB, or rely on CPU-level retentive MB setting
Tag loses value after power cycle Tag is on a non-retentive M byte, or DB is configured Non-retain Extend the CPU retentive range to cover the byte, or set the DB to Retain
Tag retains value, but value is corrupted after restart Bit/byte overlap: MW0 and M0.0 both declared Re-layout the M area so no symbolic address overlaps with a multi-byte tag
Download fails with "Retentive memory exceeds limit" Configured MB count above the CPU maximum Reduce the byte count to match the CPU; the S7-1211C supports up to 1024 bytes, the S7-1214C up to 1024 bytes, etc.
Optimized DB shows no Retain column The Retain column was hidden by right-click filter Right-click the column header → enable Retain
Initial value ignored after restart Tag is RETAIN, so initial value is not loaded Online → Reset → Retentive data, or use a cold restart from a clean program
Data Block is inaccessible after a firmware update Block access attributes changed (e.g. optimized ↔ standard) Document block access settings and re-download the DB

Best Practices for Retentive Data Design

  • Place all persistent process state in dedicated global DBs named with a RETAIN_ prefix so a code reviewer can immediately see retention scope.
  • Use optimized block access for every new DB. The symbolic-only access model survives project migrations and TIA Portal upgrades far better than the absolute-address model.
  • Avoid setting Retain on large arrays or strings unless the data really must survive. Each retained byte consumes protected SRAM and lengthens start-up time on S7-1500.
  • Set the Retentive memory count to the smallest block that contains your highest retentive tag. Anything beyond is wasted protected memory.
  • Add a versioning stamp inside the DB (e.g. DB_Version : WORD := 16#0100) so you can detect a configuration change after a project handoff.
  • For redundant architectures, store the cabin position in a separate "Cockpit" DB and have the partner CPU confirm the value on every synchronization cycle.

Cross-Platform Notes

The S7-300 and S7-400 (with STEP 7 V5.x) implement retention via the Hardware → Retentive memory dialog and per-DB bit in the DB properties; TIA Portal also supports these families but the dialog wording differs. On LOGO! 8, retain is a checkbox on the Block properties → Retention tab and only applies to the function block parameters, not to flag memory. On the S7-200 / SMART 200 the retentive range is set in System Block → Retentive Ranges and is limited to V memory. For an elevator retrofit that mixes an old S7-200 with a new S7-1200, map the old V-area retention into a global DB on the S7-1200 so the logic is consistent.

Safety and Functional Considerations

Even though RETAIN preserves the floor number across a brief outage, the elevator's safety chain (door locks, overspeed governor, final limit switches) must be re-validated before the car resumes motion on a re-start. EN 81-20 / ASME A17.1 require a controlled re-leveling sequence after any power interruption. Implement a re-leveling required flag that is automatically set when retentive data indicates a power-loss event, and route it through your safety program before clearing the brake.

Safety warning: A retentive CurrentFloor value is for indication only. The actual cabin position must be determined by an absolute encoder or floor-detection limit switches on the next run-up cycle. Do not use the retained value as a substitute for the encoder.

FAQ

Why is the Retain checkbox grayed out on my PLC tags table in TIA Portal?

The PLC tags table is a symbolic name list for fixed memory areas. Retentivity for M memory is configured globally in CPU properties → Retentive memory, not per tag. Use a global data block if you need per-tag retention control.

How many retentive memory bytes can my S7-1214C store?

CPU 1214C supports up to 1024 retentive bytes starting at MB0, plus 2048 retentive timers and 2048 retentive counters. The exact maximum for your firmware revision is listed in the S7-1200 System Manual.

My RETAIN tag keeps its value during a warm restart, but resets after a power cycle. What is wrong?

This is the expected behavior of non-retain tags. Power cycle is equivalent to a cold restart, which clears volatile memory. Move the tag to a global DB with the Retain attribute set, or expand the CPU's retentive MB range to include the tag's address.

What is the difference between Retain, Non-retain, and Set in IDB on an optimized S7-1500 DB?

Retain keeps the value across STOP→RUN and power cycle. Non-retain resets to the initial value on every STOP→RUN. Set in IDB defers the choice to the per-tag Retain checkbox, which is the only option on optimized blocks.

How do I clear all retentive data on an S7-1200 from TIA Portal?

Go online, then choose Online → Reset → Retentive data. The CPU must be in STOP. Retain tags revert to their initial values; non-retain tags are not affected by this command.

Can I make a counter (CTU) retentive without using a DB?

Yes. In CPU properties → Retentive memory set the number of retentive S7 counters above zero. S7 counters from C0 upward are then backed by the protected memory area. The IEC counter (CTU) in a DB must have its own Retain attribute set per instance.

Back to blog