Problem Description: Weekend Data Loss on S7-300 CPU 315-2DP
A production conveyor application counts boxes and stores the running total in a Siemens S7-300 Data Block (DB). The line is powered down every weekend. When the CPU is switched back on Monday morning, the count value has been reset to 0 rather than continuing from the value present at the previous power-off.
The hardware in question is a SIMATIC S7-300 CPU 315-2DP with an MMC (Micro Memory Card) as the only load memory, programmed with STEP 7 (SIMATIC Manager) V5.3 + SP3. The CPU firmware reported by the user is V2.0. This combination of firmware version and load memory type is the key to the correct root cause and the correct remedy.
| Item | Value |
|---|---|
| CPU | 6ES7 315-2AG10-0AB0 (CPU 315-2DP) |
| Firmware | V2.0 |
| Load memory | MMC (no onboard flash on this CPU class) |
| Work memory | Volatile RAM, battery-backed only if a backup battery is fitted |
| STEP 7 | V5.3 + SP3 |
| Data of interest | Counter / accumulated value inside a DB |
| Power cycle | Full OFF over weekend, no UPS / no buffer |
Root Cause: Why the DB is Reset to Zero on Power-On
The PLC does not, by default, mirror live runtime values from work memory back to the load memory (the MMC) at every scan. The model to keep in mind is:
- Load memory (MMC): the project, the initial DB contents, and the program.
- Work memory (RAM): where DBs are mirrored at RUN time and where the live counter value lives.
- Retentive memory: a small, battery-backed or non-volatile slice of work memory that survives power-off.
On the S7-300 firmware family, the retentive behaviour of a DB is governed by three things, and the S7-300 CPU 315-2DP with firmware V2.0 follows the rules in the table below.
| CPU firmware | DB retentive at POWER OFF / POWER ON / STOP->RUN ? | How it is configured |
|---|---|---|
| < V2.1.0 (e.g. V2.0) | All DB contents are always retentive at POWER ON/OFF and at STOP->RUN. The "Non-Retain" property does not yet exist as a runtime control. | Implicit. You do not need to set any tick box to retain DB contents. |
| >= V2.1.0 (typical V2.x, V3.x) | Each DB can be flagged retentive or non-retentive. Non-retentive DBs revert to their initial values on STOP->RUN or POWER OFF->ON. | DB Properties > General Part 2 > "Non-Retain" tick box. Tick = non-retentive (reset to initial values). Untick = retentive. |
For this specific system — CPU 315-2DP firmware V2.0 — the retentive behaviour of every DB is implicit and is, by definition, retentive. That means the count should survive a power-off as long as the work memory is preserved across the outage. If the count is in fact being lost, the most likely root causes are:
- No backup battery fitted in the CPU. The S7-300 has a buffered RAM region that is kept alive by a lithium backup battery. If the battery is missing, dead, or has been removed, the work memory is wiped on every power-off, and the next start uses the initial values stored on the MMC.
- Wrong MMC type or an MMC that has been re-initialised. Certain MMC operations (format, delete, re-download) force the next cold start to use the initial values from the project.
- CPU is performing a cold restart (OB102) instead of a warm restart (OB101) or hot restart (OB100). A cold restart reloads the work memory from the load memory and uses the DB initial values.
- DB was marked "Non-Retain" in a project edit while the firmware was reported incorrectly. The reported firmware is V2.0, so this property should not be active, but verify the firmware actually present at runtime (see Verification section).
Confirming the Real Firmware and the Buffer Status
Before changing code, validate the actual CPU firmware and the buffer configuration in STEP 7 > PLC > Module Information (online > accessible node > Module Information).
| Field | Where to find it | What to look for |
|---|---|---|
| Firmware version | Module Information > "Firmware" tab | Should be V2.0.x. If it is V2.1 or higher, the Non-Retain property becomes active. |
| Operating mode of last start | Diagnostic buffer | "Warm restart", "Hot restart" or "Cold restart" |
| Battery status | Diagnostic buffer > "Battery failure" events; or the BAT LED on the CPU | No "Battery failure" or "Back-up battery voltage low" events since the last battery change. |
| Retentive memory areas | CPU Properties > Retentive Memory | Number of retentive bytes, MB / DB / timers / counters set |
If the diagnostic buffer reports a Cold restart as the last startup, the DB initial values are used regardless of firmware, and you will need to either (a) change the startup mode to Warm restart in the CPU properties, or (b) save the value to the MMC with SFC84 before power-off (see below).
Solution Path A: Fix the Retentive Mechanism (No SFC84 Required)
For CPU 315-2DP firmware V2.0, the simplest, most reliable fix is to ensure the retentive path is intact. Carry out the checks below in order.
A1. Verify or Install the Backup Battery
- Open the CPU front cover and confirm a 3.6 V lithium backup battery is fitted (e.g. 6ES7 971-1AA00-0AA0, type "A").
- Measure the battery voltage under load; replace if below approximately 3.0 V.
- Set the battery switch on the CPU to the "BATT" or "ON" position; older CPU 315-2DP have a toggle on the front panel.
A2. Set Retentive Areas for the DB
Open the CPU hardware object in STEP 7 and select Retentive Memory. Define the area of work memory that should survive a power-off. The minimum needed is the DB number and a byte count large enough to cover the counter variable plus any neighbouring tags you want preserved.
| Setting | Example for this application | Effect |
|---|---|---|
| Retentive DBs | DB 10 (count DB), Byte 0 .. Byte 7 | Bytes 0-7 of DB 10 are buffered. |
| Retentive MB | None | No merker bytes retained. |
| Retentive timers / counters | 0 | Counter is stored in the DB, not in the S7 counter area. |
With the battery present and the DB declared retentive, the work memory is preserved across the weekend power-off, and the counter will resume from the last value automatically. SFC84 is not required in this case.
Solution Path B: Use SFC84 "WRIT_DBL" to Save the DB to the MMC
If a backup battery cannot be used (some sites prohibit lithium cells on the shop floor, or the user wants a true non-volatile persistence), the alternative is to write the DB from work memory back to the MMC on demand using SFC84 "WRIT_DBL". This makes the MMC a non-volatile mirror of the live DB.
B1. What SFC84 Does
SFC84 copies the contents of a DB in work memory to the corresponding DB in load memory (the MMC). After the call, the next POWER-OFF / POWER-ON cycle or STOP / RUN transition will use the values that were present at the moment of the last SFC84 call.
| Parameter | Declaration | Type | Meaning |
|---|---|---|---|
| REQ | INPUT | BOOL | Edge-triggered request to start the write (rising edge) |
| DB_NR | INPUT | WORD | DB number (must exist in load memory) |
| RET_VAL | OUTPUT | INT | Return value (error code, see B5) |
| BUSY | OUTPUT | BOOL | 1 while the write is in progress |
B2. Sample Ladder Call
Network 1: Save DB10 to MMC on power-fail event
| P#+Save_DB10 Save_DB10 ( Edge flag )
------| /|-----( )-----( S )------------+-----------------------/
| |
| "PS-PowerFail" | WRIT_DBL
| Save_DB10 DB_NR | EN ENO RET_VAL BUSY
| | | (S) 10 |---] [------(SFC84)------
| | | | DB10
| | | | Save_DB10 (RE trigger)
| | | | / \
| | | | +-----------+
| | | | RET_VAL -> MW 100
| | | | BUSY -> M 110.0
Re-trigger the call on a rising edge of Save_DB10. If BUSY = 1, do not call SFC84 again; the call is single-instance per cycle.
B3. Structured Text Equivalent
// One-shot rising edge from power-fail detector
IF "PF_PowerFailEvent" AND NOT "Save_DB10_Trig" THEN
"Save_DB10_Trig" := TRUE;
// Triggers SFC84 below
"Save_DB10_Req" := TRUE;
END_IF;
IF NOT "PF_PowerFailEvent" THEN
"Save_DB10_Trig" := FALSE;
"Save_DB10_Req" := FALSE;
END_IF;
// SFC84 call
IF "Save_DB10_Req" THEN
"RetVal_SFC84" := WRIT_DBL(REQ := "Save_DB10_Req",
DB_NR := 10);
END_IF;
B4. MMC Write-Cycle Limit (Critical)
Recommended trigger sources for the conveyor count DB:
- Operator "Save" button on the HMI.
- End-of-shift time signal.
- Detection of an imminent power-off via a hardware signal on a digital input wired to a UPS / line monitor.
- OB81 (power fault) if a buffered detection mechanism is in place.
B5. SFC84 Return Value (RET_VAL) Error Codes
| RET_VAL | Meaning | Remedy |
|---|---|---|
| 0000h | No error | — |
| 0080h | No error, BUSY still set, function not yet finished | Wait for BUSY = 0 before next call |
| 80A1h | DB_NR invalid or DB not in load memory | Verify DB exists in offline project and is on the MMC |
| 80B1h | Internal error, MMC missing / not formatted | Check MMC is inserted and readable via STEP 7 |
| 80B2h | DB is currently being processed (e.g. by SFC84 / SFC83 from another OB) | Serialise calls; wait until BUSY = 0 |
| 80C1h | No write access to MMC (e.g. write-protected, password) | Check MMC switch, project password, operator panel lock |
| 80C3h | Not enough free space on MMC | Reduce the volume of project data; archive and format MMC |
| 80C4h | DB is too large to be written in one SFC cycle | Split or reduce DB size; the SFC operates on one DB at a time |
| 8xxxh | General SFC error | Refer to the S7-300/400 System and Standard Functions manual |
Solution Path C: Detecting Imminent Power-Off and Triggering SFC84 in OB81
The user asked specifically whether the PLC can detect the loss of mains and run a shutdown routine to call SFC84. The S7-300 supports this through OB81 (Power Supply Fault OB) and an external line monitor. The procedure is:
- Wire a line-voltage monitor (e.g. a Phoenix Contact or Siemens SITOP UPS module) to a digital input on the S7-300. The signal must assert at least 1 to 2 seconds before the DC 24 V supply collapses to give the SFC84 call time to complete.
- Configure the SITOP / UPS module for buffer time > 1.5 s, with a "power-fail imminent" relay contact wired to input I 0.0.
- In OB81, evaluate the input. Because OB81 runs on power fault and on return of power, distinguish the two events with a flag set in OB1 each scan, and only act when the flag disappears (i.e. a power-down event was just seen).
- Inside the power-fail branch of OB81, call SFC84 with a one-shot to write the count DB to the MMC. Do not call other heavy SFCs; you have only a few hundred milliseconds to a few seconds of buffer time.
Sample OB81 Skeleton
FUNCTION_BLOCK FB 1 "FB_PowerFailSave"
VAR
SaveDone : BOOL;
END_VAR
BEGIN
// Rising edge of mains-OK lost, but DC 24 V still present
IF NOT "MainsOK" AND NOT SaveDone THEN
"RetVal_SFC84" := WRIT_DBL(REQ := TRUE,
DB_NR := 10);
SaveDone := TRUE; // one-shot, do not retry
END_IF;
// Reset latch once power is fully restored and CPU is in RUN
IF "MainsOK" AND "OB1_Running" THEN
SaveDone := FALSE;
END_IF;
END_FUNCTION_BLOCK
OB 81 "Power Supply Fault OB"
BEGIN
// FB_PowerFailSave.DB10 instance
"InstPowerFailSave"(MainsOK := "I0.0_MainsOK");
END_ORGANIZATION_BLOCK
Comparison of the Three Solution Paths
| Criterion | Path A: Battery + retentive DB | Path B: SFC84 on demand | Path C: SFC84 in OB81 on power fail |
|---|---|---|---|
| Hardware needed | Backup battery (already part of CPU) | Existing MMC | UPS / SITOP module with mains-fail signal |
| Code complexity | None | One SFC call, edge trigger | OB81, FB, line monitor wiring |
| MMC wear | None | One write per trigger | One write per power-fail |
| Survives battery removal ? | No | Yes, until next cold start that reverts to initial values | Yes |
| Failure mode | Battery exhausted after some years | Power-off before SFC84 executes | Buffer time too short for SFC84 to complete |
| Recommended for this case | Yes, primary | Yes, secondary (HMI save button) | Yes, advanced |
Verification Procedure
After applying the fix, perform the following verification to confirm weekend-style behaviour does not return.
- Online > Monitor > force the count DB to a recognisable value, e.g.
DB10.DBD0 = 12345. - Power down the PLC completely (turn off the line isolator; do not just STOP the CPU).
- Wait at least 30 seconds; longer than the typical SITOP buffer time, to mimic a true weekend.
- Power the PLC back on.
- Connect online and read
DB10.DBD0. It must still be12345. If it is0, the retentive mechanism is not active: recheck battery and DB retentive settings, or verify that the SFC84 path actually executed in OB81 before power-down. - Inspect the diagnostic buffer for the last startup type. It should report "Warm restart" for a CPU 315-2DP without a configured cold-restart OB102.
- If the MMC-based path is in use, run the test five times consecutively. If the count is consistent across all five cycles, the SFC84 is firing reliably and the wear concern is bounded by the trigger rate.
Troubleshooting Matrix
| Symptom | Most likely cause | Fix |
|---|---|---|
| Count resets to 0 every Monday | No backup battery fitted; or battery exhausted | Replace battery, declare DB retentive in CPU properties |
| Count resets to 0 after STEP 7 download | Download of project re-writes initial values to MMC | Avoid full project downloads; use Online > "Download to target system" with care, or use SFC84 immediately after download |
| Count resets to 0 after a power dip < 5 s | SITOP buffer not present; battery nearly dead | Add UPS / SITOP or replace battery |
| Count is correct on Monday but SFC84 reports 80C3h | MMC full | Archive and reformat MMC; reduce project size; remove old logs |
| SFC84 reports 80B2h intermittently | SFC84 is being called from two OBs in the same cycle | Serialise: call only from OB1 (with edge) or only from OB81 (with one-shot) |
| Count is correct on Monday but MMC has failed within 6 months | SFC84 is being called in OB1 every scan | Move the call to an event-driven trigger; MMC endurance has been exceeded |
| DB initial values are correct, runtime values disappear immediately | DB has been declared non-retentive (Non-Retain = TRUE) on firmware V2.1+; the user is on V2.0 but the project was authored on a newer firmware | Untick "Non-Retain"; recompile and re-download the project |
Field Notes and Best Practices
- For an S7-300 CPU 315-2DP with firmware V2.0, the Non-Retain tick box in DB properties is shown by the editor but is functionally ignored at runtime. The DB will always be retentive if the backup battery is in place. Do not rely on the tick box to disable retentivity on this firmware.
- If you upgrade the firmware above V2.1.0 in the future, re-evaluate the Non-Retain setting on every DB. The default is retentive, so leaving the tick box empty is the safe choice for production data.
- Where possible, do not use SFC84 on an S7-300 for routine save. The MMC endurance is a maintenance liability. The S7-400, S7-1200 and S7-1500 have different mechanisms (e.g. retain tags, recipe DBs) that are better suited to this use case.
- For the conveyor count application specifically, the cleanest approach is to keep the value inside a retentive DB and let the backup battery handle the weekend. Add an HMI save button that triggers SFC84 only as a belt-and-braces safeguard.
- Always store production-critical counts in a retentive DB or, better, mirror them to a higher-level SCADA so the PLC is not the only place the value lives.
Related STEP 7 / Siemens Documentation
For deeper reference on the SFC84 block, the S7-300 retentive memory model and the SFC error codes, see the official Siemens automation support manuals:
- SFC84 "WRIT_DBL" — description and parameters
- Retentive behaviour of S7-300 CPUs and DBs at POWER ON / POWER OFF
- S7-300 CPU 31x retentive memory — configuration and diagnostics
- S7-300 CPU 31xC and 31x Manual — Chapter 4: Retentive areas
Why does my S7-300 DB reset to zero on every power-off even though the DB is retentive?
On a CPU 315-2DP firmware V2.0, the DB is implicitly retentive, but only if the backup battery is fitted and healthy. A missing or exhausted battery erases the work memory on every power-off, so the next start uses the DB initial values from the MMC. Fit a fresh 3.6 V lithium battery (e.g. 6ES7 971-1AA00-0AA0) and re-test.
Does SFC84 wear out the MMC? How often can I call it?
Yes. S7-300 MMC cards have a finite write endurance, typically 100,000 to 1,000,000 writes per sector. Calling SFC84 once per PLC scan will destroy an MMC in days. Call it only on a meaningful event: end of shift, operator save button, or detected power-fail in OB81. For weekend-only persistence on a CPU 315-2DP V2.0, prefer the battery-backed retentive approach over SFC84.
Can I detect a power failure and run SFC84 before the PLC dies?
Yes, but only with external support. Wire a line-voltage monitor or a SITOP UPS module that asserts a digital input at least 1 to 2 seconds before the DC 24 V supply collapses. Evaluate the input inside OB81 (Power Supply Fault OB) and call SFC84 there as a one-shot. Size the SITOP buffer for the worst-case SFC84 write time plus a safety margin.
What does the Non-Retain tick box do on a firmware V2.0 CPU 315-2DP?
On firmware V2.0, the Non-Retain property is displayed in the editor but is ignored at runtime. All DBs are retentive on this firmware as long as the backup battery is present. The property becomes active only on firmware V2.1.0 and higher, where ticking Non-Retain will cause the DB to be reset to its initial values on STOP->RUN and POWER OFF->ON.
What does SFC84 return value 80C3h mean?
Return value W#16#80C3 indicates that there is not enough free space on the MMC to write the DB. Archive the project, free space on the MMC, or remove obsolete blocks. W#16#80A1 means the DB number is invalid or the DB is not in load memory; W#16#80C1 means the MMC is write-protected or the project is password-locked.