1. S7-1200 DataLog System Architecture Overview
The SIMATIC S7-1200 DataLog mechanism stores structured process records on a Siemens SMC (SIMATIC Memory Card) inserted in the CPU. Each DataLog is a binary file written under /DataLog/ on the SD card, indexed by an internal DWORD identifier returned by DataLogCreate. A typical deployment in TIA Portal V15 targets a CPU firmware V4.x class controller (S7-1211C through S7-1215C and S7-1217C), where the DataLog instruction set is implemented as multi-instance-capable FBs inside the Program blocks > System blocks > Extended instructions > Data log library.
Records are appended sequentially, and once the configured RECORDS maximum is reached the system is required to signal a full condition through the STATUS output of DataLogWrite. The full-condition code is the well-known 16-bit value 0001 (W#16#0001). When this code is missing, the most common user-visible symptom is silent overwrite of the oldest record without an error being latched into the application code, which defeats the very purpose of bound logging in regulated or audited processes.
The DataLog family consists of six instructions:
-
DataLogCreate – Allocates a new
.csv/.binfile and binds it to aDWORDID. -
DataLogOpen – Re-opens an existing log so
DataLogWritecan resume. - DataLogWrite – Appends a single record (variant).
- DataLogClose – Flushes buffers and releases the file handle.
- DataLogNewFile – Closes the current file and creates a new one with the same name pattern (timestamped) once the old one is full.
- DataLogDelete – Removes a file from the SD card.
All instructions use a single-instance DB (or multi-instance inside an FB) and the standard REQ / BUSY / DONE / ERROR / STATUS execution model that is consistent with all S7-1200 asynchronous system FBs.
DataLogCreate returns status 0008 (no memory card).
2. DataLog Instruction Set Reference (TIA Portal V15)
The instruction set is part of the Extended Instructions palette. Each instruction is added to a code block by dragging from the right-hand task card, after which TIA Portal automatically instantiates the multi-instance DB or lets the engineer wire a separate instance DB. The CALL signature is identical for LAD, FBD, and SCL.
The instruction set and corresponding DB family (default names in parentheses):
| Instruction | Default Instance DB | Primary Function | Asynchronous? |
|---|---|---|---|
| DataLogCreate | DatalogCreate_DB |
Allocates new log file, returns ID | Yes |
| DataLogOpen | DatalogOpen_DB |
Re-opens an existing log file | Yes |
| DataLogWrite | DatalogWrite_DB |
Appends one record | Yes |
| DataLogClose | DatalogClose_DB |
Closes the file and flushes | Yes |
| DataLogNewFile | DatalogNewFile_DB |
Closes current, opens next sequenced file | Yes |
| DataLogDelete | DatalogDelete_DB |
Removes file from SMC | Yes |
All instructions are classified as asynchronous in the S7-1200 system manual because the actual write to the SD card happens in a background task and the FB may require multiple OB1 scans to complete. A rising edge on REQ launches the job, and BUSY stays TRUE until DONE or ERROR is reported.
3. DataLogCreate Parameter Reference
The DataLogCreate block defines the size, format, and identity of the data log. Every parameter below is required to obtain deterministic full-file behavior. TIA Portal V15 exposes these parameters in the block interface and the F1 help contains the authoritative description.
| Parameter | Direction | Data Type | Meaning / Constraints |
|---|---|---|---|
REQ |
IN | BOOL | Rising-edge trigger to start the create job |
RECORDS |
IN | DINT | Maximum number of records (typical 1 – 65535). Determines when status 0001 will be reported |
FORMAT |
IN | USINT | 0 = internal binary, 1 = CSV (readable on PC). Affects record size and 0005 errors |
TIMESTAMP |
IN | USINT | 0 = none, 2 = system time. Adds 8 bytes to each record |
NAME |
IN | STRING | Filename without extension. Max 24 characters; ASCII only |
ID |
OUT | DWORD | Internal handle; pass this to all subsequent DataLog calls |
DONE |
OUT | BOOL | TRUE for one cycle on success |
BUSY |
OUT | BOOL | TRUE while the job is running |
ERROR |
OUT | BOOL | TRUE on failure |
STATUS |
OUT | WORD | 16-bit status word, 0000 on success, see Section 4 for error codes |
RECORDS input is the only field that bounds the file size and is therefore the single field that controls when DataLogWrite returns status 0001. If the application is reusing the same NAME in subsequent calls to DataLogCreate, the old file is deleted and a fresh, empty file is created; this is the most common cause of the reported bug — the file is never full because the application keeps recreating it.
To prevent silent recreation, the application must:
- Call
DataLogCreateonce at first-run, gated by a persistent bit (retain tag, DB bit, or checkDataLogOpensuccess first). - Store the
IDin a retentive tag so it survives power-cycle. - Only create a new file if
DataLogOpenreturns 0007 (file does not exist) or afterDataLogNewFilecloses the current segment.
4. DataLogWrite Parameter Reference and Status Code Map
DataLogWrite is invoked once per record. The RECORD input is a VARIANT pointing to a STRUCT or DB whose layout must match the data declared at creation time. A mismatch causes status 000A (header does not match).
| Parameter | Direction | Data Type | Meaning |
|---|---|---|---|
REQ |
IN | BOOL | Rising edge appends one record |
ID |
IN | DWORD | Handle returned by DataLogCreate / DataLogOpen |
RECORD |
IN | VARIANT | Pointer to record data (DB or STRUCT tag) |
DONE |
OUT | BOOL | One-cycle pulse on success |
BUSY |
OUT | BOOL | Job in progress |
ERROR |
OUT | BOOL | Job failed |
STATUS |
OUT | WORD | 0x0000 = no error, see codes below |
4.1 DataLogWrite Status Code Map
The complete 16-bit STATUS word returned by DataLogWrite in TIA Portal V15 / CPU firmware V4.x is summarized below. Always cross-check the F1 help of the local TIA Portal installation for the exact firmware you compile against.
| STATUS (hex) | Meaning | Recommended Action |
|---|---|---|
| 0000 | No error, record appended | Continue |
| 0001 | Data log is full — record was not appended | Call DataLogClose + DataLogNewFile, or rotate filename, then reopen |
| 0002 | Data log does not exist (ID unknown) | Recreate with DataLogCreate, then retry |
| 0003 | File write error / I/O fault | Check SMC, replace card, retry |
| 0005 | Data record too long for declared header | Fix RECORD size or recreate the file with the correct struct |
| 0007 | Data log not open | Call DataLogOpen first |
| 0008 | No memory card inserted | Insert SMC, restart CPU |
| 0009 | SMC is write-protected | Slide lock, retry |
| 000A | Header / data structure does not match | Re-create the log with the correct struct |
| 000B | Record number out of range | Internal error; capture and contact SIOS |
| 000C | File system error / SMC removed mid-write | Replace card, verify grounding |
| 80C0 | Resource exhausted (internal buffer) | Throttle write rate, avoid <1 ms writes |
| 80C3 | Job in progress (BUSY conflict) | Wait for BUSY = FALSE before next REQ |
STATUS word is reset to 0000 on the next rising edge of REQ regardless of whether the new job succeeds or fails. If the application latches the previous status for diagnostics, do it on the falling edge of BUSY.
5. Root Cause: Why Status 0001 Is Not Returned
The reported symptom — “log silently overwrites the existing records and never reports 0001” — has four field-observed root causes, ranked by frequency in TIA V15 / CPU firmware V4.x deployments.
5.1 Root Cause A — Repeated DataLogCreate Calls
If the OB1 calls DataLogCreate on every cycle (or every scan after a power-up), the call deletes the existing file and creates a new one with zero records. The RECORDS ceiling is therefore never reached, and status 0001 is never produced because the file is “full” only relative to a single OB1 scan, which never contains more than one record write.
Diagnostic: Monitor the DataLogCreate.DONE pulse with a counter. If the counter increments while the log is supposed to be filling, the program is recreating the log.
5.2 Root Cause B — DataLogNewFile in the Wrong Place
DataLogNewFile closes the current log and immediately allocates a new sequenced file. If this FB is triggered every time a full condition is detected but is triggered from a rung that does not confirm 0001, the log is rotated prematurely and never reaches RECORDS.
5.3 Root Cause C — RECORDS Set to Zero or Negative
Although TIA Portal normally validates the input at compile time, a runtime-loaded RECORDS from an HMI tag can pass zero. With RECORDS = 0, the firmware either treats the file as immediately full and never accepts a write (no overwrite), or in early V4.x firmware truncates the existing file. The resulting behavior is platform-dependent and frequently misinterpreted as “overwrite”.
5.4 Root Cause D — Instance-DB Re-Initialization at Restart
If the instance DB for DataLogCreate is not marked non-retain with initial values > retained ID, the firmware recreates the DB on restart, losing the stored ID and forcing the next DataLogWrite to fail with 0002. A fall-back rung in the user program then re-issues DataLogCreate, deleting the file (Root Cause A).
All four causes funnel into the same observable symptom: the log never holds more than 0 – 1 records and 0001 is never produced. The fix is to enforce the lifecycle described in Section 6.
6. Step-by-Step Resolution Procedure
- Open the TIA Portal V15 project containing the affected S7-1200 station. Verify the CPU is online and that the project on the engineering station matches the running firmware (right-click CPU → Online & diagnostics → Firmware).
- Locate the DataLogCreate call in the OB1 or the data-log management FB. Use Project tree → Program blocks → search → "DataLogCreate" if it is not in OB1 directly.
-
Read the F1 help for the DataLogCreate block. Confirm the
RECORDS,NAME,FORMAT, andTIMESTAMPinputs and note any “Behavior on full” parameter that is specific to the firmware in use. -
Move DataLogCreate out of the cyclic path. The create call should fire only on first-run, on a user command, or on a detected 0002 / 0007 status from
DataLogOpen. Wrap the call in anIFguarded by a retentive"Log_Created"BOOL. -
Add a retentive
DataLogIDtag (DWORD, located in a retain-enabled DB) and pass this to every DataLog call. Initialize it with16#0— the firmware treats zero as “no valid ID”. -
Add full-detection logic in the same FB that calls
DataLogWrite:IF "DataLogWrite_DB".STATUS = 16#0001 AND NOT "DataLogWrite_DB".BUSY THEN "Log_Full" := TRUE; END_IF; -
Implement the rotation: when
Log_Fullis set, callDataLogClose; on its DONE pulse, callDataLogNewFileand assign the newIDback to the retentive tag. ResetLog_Fullafter the new file is opened. - Compile and download the project (Stop CPU → Download → Run). Clear the SD card first if you want a known clean state.
-
Force a fill by writing more than
RECORDSfrom a watch table and confirm thatSTATUS = 16#0001is now latched intoLog_Full. -
Verify the rotation by checking the SMC
/DataLog/folder via Web Server → File browser or by removing the SMC and reading it on a PC. The sequenced file should appear with the timestamp appended.
http://<CPU-IP>/DataLog. This is the fastest way to confirm that the file count and size match the writes the CPU reports.
7. Working SCL Sample Code with Full Detection
The following SCL code is a self-contained FB that demonstrates the correct lifecycle. Drop it into Program blocks > Add new block > Function block, declare the variables as shown, and call it from OB1 with a one-second Cyclic_Trigger BOOL from a TON timer.
FUNCTION_BLOCK "DataLogManager"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
Cyclic_Trigger : BOOL; // 1 Hz pulse
Record : "typeProcessRecord"; // user record struct
END_VAR
VAR_OUTPUT
Log_Full : BOOL;
Last_Status : WORD;
END_VAR
VAR RETAIN
ID : DWORD; // 0 = no valid handle
Log_Created : BOOL;
END_VAR
VAR
Create_DB : "DatalogCreate";
Open_DB : "DatalogOpen";
Write_DB : "DatalogWrite";
Close_DB : "DatalogClose";
NewFile_DB : "DatalogNewFile";
Step : INT; // state machine 0..6
Rotate : BOOL;
END_VAR
BEGIN
// ---- Step 0: try to open existing log ----
IF Step = 0 AND Cyclic_Trigger THEN
"DatalogOpen_DB"(REQ := TRUE,
MODE := 0,
NAME := 'ProcessLog',
ID := ID,
DONE => Open_DB.DONE,
BUSY => Open_DB.BUSY,
ERROR => Open_DB.ERROR,
STATUS => Open_DB.STATUS);
IF Open_DB.DONE AND Open_DB.STATUS = 16#0000 THEN
Step := 2; // jump to write
ELSIF Open_DB.DONE AND Open_DB.STATUS = 16#0007 THEN
Step := 1; // need to create
ELSIF Open_DB.DONE AND Open_DB.ERROR THEN
Last_Status := Open_DB.STATUS;
Step := 99; // diagnose
END_IF;
END_IF;
// ---- Step 1: create new log ----
IF Step = 1 AND NOT Create_DB.BUSY THEN
"DatalogCreate_DB"(REQ := TRUE,
RECORDS := 1000,
FORMAT := 1,
TIMESTAMP := 2,
NAME := 'ProcessLog',
ID := ID,
DONE => Create_DB.DONE,
BUSY => Create_DB.BUSY,
ERROR => Create_DB.ERROR,
STATUS => Create_DB.STATUS);
IF Create_DB.DONE AND Create_DB.STATUS = 16#0000 THEN
Log_Created := TRUE;
Step := 2;
ELSIF Create_DB.DONE AND Create_DB.ERROR THEN
Last_Status := Create_DB.STATUS;
Step := 99;
END_IF;
END_IF;
// ---- Step 2: write one record ----
IF Step = 2 AND Cyclic_Trigger AND NOT Write_DB.BUSY THEN
"DatalogWrite_DB"(REQ := TRUE,
ID := ID,
RECORD := Record,
DONE => Write_DB.DONE,
BUSY => Write_DB.BUSY,
ERROR => Write_DB.ERROR,
STATUS => Write_DB.STATUS);
IF Write_DB.DONE THEN
Last_Status := Write_DB.STATUS;
IF Write_DB.STATUS = 16#0001 THEN
Log_Full := TRUE;
Step := 3; // rotate
ELSIF Write_DB.STATUS <> 16#0000 THEN
Step := 99; // diagnose
END_IF;
END_IF;
END_IF;
// ---- Step 3: close + new file ----
IF Step = 3 AND NOT Close_DB.BUSY THEN
"DatalogClose_DB"(REQ := TRUE,
ID := ID,
DONE => Close_DB.DONE,
BUSY => Close_DB.BUSY,
ERROR => Close_DB.ERROR,
STATUS => Close_DB.STATUS);
IF Close_DB.DONE AND NOT Close_DB.ERROR THEN
Step := 4;
ELSIF Close_DB.DONE AND Close_DB.ERROR THEN
Last_Status := Close_DB.STATUS;
Step := 99;
END_IF;
END_IF;
IF Step = 4 AND NOT NewFile_DB.BUSY THEN
"DatalogNewFile_DB"(REQ := TRUE,
ID := ID,
DONE => NewFile_DB.DONE,
BUSY => NewFile_DB.BUSY,
ERROR => NewFile_DB.ERROR,
STATUS => NewFile_DB.STATUS);
IF NewFile_DB.DONE AND NOT NewFile_DB.ERROR THEN
Log_Full := FALSE;
Step := 2; // resume writes
ELSIF NewFile_DB.DONE AND NewFile_DB.ERROR THEN
Last_Status := NewFile_DB.STATUS;
Step := 99;
END_IF;
END_IF;
// ---- Step 99: error diagnosis, requires operator intervention ----
IF Step = 99 THEN
// Hold last status; operator must clear via HMI reset
END_IF;
END_FUNCTION_BLOCK
7.1 State Machine Diagram
8. Verification and Commissioning Tests
After the fix is downloaded, perform the following sequence to confirm deterministic behavior:
-
Reset the SD card. Use the Web Server to delete any existing
ProcessLogfiles, or remove the SMC and re-format it with the S7-1200 CPU (online → Functions → Format memory card). -
Force a low RECORDS value (e.g.
RECORDS = 5) so the test runs in seconds rather than hours. -
Trigger 6 writes from a watch table or test FB. The 6th write must report
STATUS = 16#0001withERROR = FALSE. -
Observe the state machine.
Stepmust transition 0 → 1 (create) → 2 (write) → 3 (close) → 4 (new file) → 2 (write resumes). -
Inspect the SMC via Web Server. The number of files under
/DataLog/should grow by one for each rotation. -
Cycle power. After restart,
Stepshould remain at 2 because the retentiveIDis preserved and the existing log is opened rather than recreated.
DataLogNewFile appended a timestamp suffix but the user is opening the wrong one. Always check the filename before concluding the rotation failed.
9. Troubleshooting Matrix
| Symptom | Likely Cause | Diagnostic | Fix |
|---|---|---|---|
| No 0001 ever, file stays < RECORDS | DataLogCreate called every scan | Monitor Create_DB.DONE counter | Gate create with retain bit |
| No 0001, file has 1 record only | RECORDS = 0 (runtime HMI write) | Force RECORDS from watch table | Validate HMI input range |
| STATUS = 000A after restart | Struct definition changed | Compare RECORD variant with declared header | Re-create file with new struct |
| STATUS = 0008 | No SMC inserted | Check online → diagnostics → memory card | Insert SMC, restart |
| STATUS = 0009 | SMC write-protect slider engaged | Check slider position | Unlock, retry |
| STATUS = 80C0 | Write rate too high (< 10 ms) | Measure OB1 time | Throttle with TON or cyclic interrupt OB |
| STATUS = 0007 | CPU restart lost the file | Check SMC presence and retain | Ensure ID is in retain DB |
| STATUS = 0003 sporadic | SMC failing or counterfeit | Replace SMC with 6ES7954-8LF02 | Use genuine Siemens SMC only |
| STATUS = 0002 | ID corrupted | Inspect retain tag | Reset ID, re-open |
| STATUS = 0001 immediately after create | RECORDS < 2 | Verify constant | Set RECORDS ≥ 10 |
10. Best Practices for Production Deployments
- Use Siemens SMC only. Article numbers 6ES7954-8LF02-0AA0 (4 MB), 6ES7954-8LE02-0AA0 (12 MB), 6ES7954-8LL02-0AA0 (24 MB) are validated for DataLog. Counterfeit cards are the #1 cause of 0003 errors in the field.
- Pick CSV (FORMAT = 1) unless binary size is critical. CSV files are human-readable and can be analysed in Excel or with the S7-1200 Web Server. Internal binary (FORMAT = 0) is faster but requires the TIA Portal DataLog viewer for analysis.
- Bound the record size. Each record has a fixed 12-byte overhead plus the size of the user struct. A struct larger than 256 bytes causes measurable OB1 jitter.
- Throttle writes to ≥ 100 ms. The SD card wear-leveling expects this. Writes faster than 10 ms will hit 80C0.
-
Always use a state machine. Cyclic calls to DataLogCreate are a leading cause of silent data loss. Drive the create open write close new file sequence from a single FB with a
Stepinteger. -
Monitor SMC health with
RD_SINFOand theGetSMCInfouser library. Replace cards at 80 % of the rated write cycles. - Enable the Web Server for diagnostics. Without it, the only way to inspect the SD card is to remove it and read it on a PC, which is impractical in a running plant.
- Log the Last_Status tag to the HMI so operators can see why a log rotation failed.
11. Firmware and TIA Portal Version Notes
| TIA Portal | CPU Firmware | Behavior Note |
|---|---|---|
| V13 SP1 | V4.0 | Original DataLog; DataLogNewFile introduced |
| V14 SP1 | V4.1 | STATUS code table extended; 000A added |
| V15 | V4.2 | Current discussion baseline. DataLogCreate parameter interface unchanged |
| V15.1 | V4.3 | Improved web server file browser; faster CSV export |
| V16 / V17 | V4.4 / V4.5 | Symbolic access optional. STATUS codes backward-compatible with V15 |
The DataLog instruction set has been functionally stable since firmware V4.1. Applications written against V15 will recompile and run unchanged in V16 / V17 provided the S7-1200 CPU is updated in lockstep with the TIA Portal version used to compile. The status code 0001 has had the same meaning — data log full, record rejected — across all these versions, which is the contract the user program can rely on.
12. Diagnostic Procedure Flowchart
The flowchart above is the fastest path to isolate which of the four root causes in Section 5 is active. In production, it is worth running this against any S7-1200 DataLog program during the commissioning FAT.
Why does DataLogWrite never return status 0001 even when the file is supposed to be full?
The most common cause is that DataLogCreate is being called cyclically, which deletes the existing log and creates a new empty one before the RECORDS ceiling can be reached. Move DataLogCreate out of the cyclic path, gate it with a retentive Log_Created BOOL, and store the returned ID in a retain DB. After this, status 0001 will be latched into your application code the moment the configured RECORDS count is exceeded.
What is the exact meaning of DataLogWrite status 0001?
Status word 16#0001 from DataLogWrite means the data log has reached its RECORDS maximum and the new record was not appended. ERROR is FALSE in this case — it is a logical full condition, not a hardware fault. The application should call DataLogClose followed by DataLogNewFile to rotate to a timestamped file and then resume writes.
How do I prevent data loss when the log is full?
Implement a state machine with the steps Open → Create (only on first run) → Write → (on 0001) Close → NewFile → Write again. Latch the Log_Full flag in a retain DB so the rotation survives a power cycle, and store the new ID returned by DataLogNewFile in the same retain location. Avoid writing faster than 100 ms to prevent 80C0 resource-exhausted errors.
Does DataLog work without a Siemens SMC?
No. The S7-1200 DataLog family requires a Siemens-branded SMC inserted in the CPU card slot. Without an SMC, DataLogCreate returns status 0008 and DataLogWrite will fail with 0007. The internal load memory of the CPU is reserved for the user program and cannot be used for DataLog files. Use article numbers 6ES7954-8LF02-0AA0 (4 MB), 6ES7954-8LE02-0AA0 (12 MB), or 6ES7954-8LL02-0AA0 (24 MB) depending on retention requirements.
Can I copy a S7-1200 DataLog FB to a S7-1500 project?
No. The S7-1500 uses the “Recipe and Data Log” instruction palette and a different status code table. The SCL code shown in this article must be rewritten for the S7-1500. However, the architectural pattern — a state machine that creates the log once, writes records, and rotates on full via DataLogNewFile — is identical and serves as a sound starting point for the S7-1500 implementation.
How do I verify that the log file is actually persisting to the SD card?
Enable the S7-1200 Web Server (CPU properties → Web server → Activate → check “Allow data log file access”). Browse to http://<CPU-IP>/DataLog in a browser; you will see the active CSV file and any rotated timestamped copies. The file size in bytes is the number of records multiplied by the record size, which provides a quick sanity check against your application’s write counter.