Problem Description
On a SIMATIC S7-1214C CPU programmed with TIA Portal V11 SP2, a Data Log block set created with the standard extended instructions (DataLogCreate, DataLogWrite, DataLogClose) exhibits a cluster of symptoms that render the captured CSV unusable for downstream analysis:
- Each log file is capped at 25 records even though the project was originally designed to grow beyond that.
- Records are presented with the most recent entry at the top rather than at the bottom of the file (reverse chronological order).
- No carriage return / line feed (CR/LF) appears between successive records — lines run together with only a single space.
- The
//Endterminator that the S7-1200 normally appends to a closed Data Log CSV is missing. - The behavior persists after a factory reset of the CPU and after deleting every previous log file on the device.
The CPU reports well over 80% free load memory, and each individual log consumes only about 2% of the remaining capacity. The project initially worked, then degraded without any code change. No SIMATIC memory card is inserted; the PLC is running from internal load memory only.
//End — all four are correlated and point at the same root cause: a Data Log file living in the S7-1200 internal load memory rather than on a SIMATIC memory card, with the file never being cleanly closed between sessions.
Affected Hardware and Firmware
The behavior is documented against the following hardware revision and firmware generation that pairs with TIA Portal V11 SP2:
| Item | Value |
|---|---|
| CPU family | SIMATIC S7-1200 |
| CPU model | CPU 1214C |
| Typical MLFB (V11 SP2 era) | 6ES7214-1AE30-0XB0 / 6ES7214-1AG31-0XB0 |
| Engineering tool | TIA Portal V11 SP2 (HMI / PLC bundle) |
| CPU firmware generation | FW 2.x – 3.x |
| Work memory (data + code) | 50 KB (1214C, FW 2.x) / 75 KB (1214C, FW 3.x) |
| Internal load memory | 2 MB integrated flash |
| Removable storage | SIMATIC memory card (not fitted in this case) |
The 1214C is a 14/10/2 (DI/DO/AI) bit-count CPU with onboard PROFINET. The data log subsystem is identical across the S7-1200 family; any 1200-series CPU without a memory card and running pre-V14 firmware reproduces the symptoms described above.
Root Cause Analysis
The four symptoms collapse into a single root cause when the Data Log file system is examined against the S7-1200 Programmable Controller System Manual and the Working with data logs reference page on the Siemens TIA documentation portal.
1. No SIMATIC memory card is fitted
Without a SIMATIC memory card, every Data Log you create is written to the internal load memory (the integrated flash). Internal flash is intended for program and project retention, not for high-frequency log writes. The S7-1200 firmware mitigates wear by treating the internal flash as a write-buffered medium: writes are committed in pages and the file is not fully materialised on every DataLogWrite call.
2. Records are appended but the file is not always closed
The //End marker and the CR/LF separator are written when a Data Log is explicitly closed with DataLogClose or when the CPU is placed in STOP / performs a clean power-down. If the CPU is power-cycled, restarted by TIA Portal, or downloads a new project without a clean close, the trailing records are written into the buffered area but the file's tail — including the final CR/LF and the //End sentinel — is not flushed. When the file is then read back, it appears truncated, run-together, and missing its terminator.
3. The 25-record "cap" is a display artifact, not a hard limit
The hard ceiling on a Data Log is governed by the record size and the available file space — Siemens documents that a CPU may host up to 1 000 Data Logs subject to memory, not 25 records per file. The 25-record cap reported in the field is the amount that survived a power-down or a TIA Portal download — the buffered tail was simply not committed. After more cycles, the surviving count can shift up or down; what the engineer is seeing is the last successfully flushed page, not a firmware limit.
4. Reverse order is a downstream tool artifact
The on-CPU file is always written in append order (oldest first). The reverse-order display is produced by the consumer: MS-Word's text-view table, certain spreadsheet import wizards, and the TIA Portal online table of the Data Log all sort by TIME or DATE_AND_TIME descending. Because the header is missing the //End line, the importer cannot locate the true end of record and either re-sorts the partial buffer or stops at the first unparseable line.
DataLogClose on every cycle, and (c) display tools that re-sort by timestamp produces the four symptoms in the field. The user’s correct response was to stop using the on-CPU log function and export via Ethernet instead.
Why the Symptoms Appear Together
| Observed symptom | Root mechanism | Source of evidence |
|---|---|---|
| 25-record cap | Only the last fully flushed flash page is visible after a power cycle / project download | Working with data logs — buffer-flush rules |
| Reverse order | Spreadsheet / Notepad sorts lines by timestamp when CR/LF is missing | Tool behavior, not PLC behavior |
| Missing CR/LF | Trailing buffered records are not committed, so the final line terminator never reaches flash |
DataLogClose not executed |
Missing //End
|
//End is written only on a clean close / STOP transition |
S7-1200 System Manual, Data Log section |
The factory-reset of the CPU and the deletion of all previous log files do not change the behavior because none of those actions affect how the log is being written — they only clear the previous (already corrupted) file. The buffering logic, the internal-flash target, and the missing close cycle are still in place.
Diagnostic Procedure
- Open Project tree → PLC → Online & diagnostics → Diagnostics → Memory and confirm that no SIMATIC memory card is inserted. If the slot is empty, the diagnosis is confirmed at the hardware level.
- From the same Online & diagnostics view, open Data logs and look at the
Statuscolumn. A status ofCLOSEDconfirms the file was cleanly closed;OPENindicates the file is still buffered in the internal flash and its tail is not yet on the medium. - In the PLC program, trace the calls to
DataLogWriteand confirm whether a matchingDataLogCloseis executed when the log is rotated or when the CPU transitions to STOP. Add a temporaryDataLogClosecall beforeDataLogCreateto force a flush of the previous file. - Download the file via the Web server (PLC → Web server → Data log file browse) and via TIA Portal (Online → Data logs → ↑ button). If the two views differ, the issue is in the TIA display, not the file content.
- Open the downloaded file in Notepad with View → Show symbol turned on. If the final line is missing its CR/LF, the buffered tail was not flushed. If the file in Notepad is identical to the file in MS-Word, the reverse-order display is being produced by MS-Word's table view, not the file.
Solution A — Correct Use of the Built-in Data Log (Recommended when a SIMATIC card is available)
If you can fit a SIMATIC memory card, the built-in Data Log is the cleanest path. The card moves the file off the internal flash, removes the page-buffering ambiguity, and gives you the full record count up to the available space.
- Insert a Siemens SIMATIC memory card (SMC) into the CPU slot. Use a card whose capacity comfortably exceeds your worst-case log footprint — 4 MB or 12 MB SMC parts are typical for the 1214C.
- In TIA Portal, change the project setting PLC → Properties → General → Store data log on to Memory card.
- In the program, call
DataLogCloseafter every write burst, and call it unconditionally before each newDataLogCreate. This is the change that turns the symptoms off in practice. - Recompile, download the project, and re-verify with the diagnostic procedure above. The file should now end with a CR/LF and the
//Endsentinel after every rotation.
Solution B — TSEND_C Export Workaround (Used by the Original Engineer)
When the application cannot tolerate a memory card — for example, when the PLC is sealed inside a remote panel and the only available service is the PROFINET port — the field-proven workaround is to bypass the on-CPU file entirely and stream each record over TCP to a Windows service that writes a CSV. This is the approach the original engineer adopted, and it removes all four symptoms because the CPU never again tries to materialise a file in internal flash.
S7-1214C side — SCL / LAD example
The example below sends one record per call as a comma-separated string framed with < and >:
// Data block: "SendBuffer" (DB), length 256 bytes
// Connection: TSEND_C, ID = 1, partner = PC, port = 2000
"SendBuffer".data[0] := '<';
"SendBuffer".data[1] := INT_TO_CHAR(year);
...
// Pack each field, comma-separated, into the buffer
// Terminate with '>' + CR + LF
"SendBuffer".data[N] := '>';
"SendBuffer".data[N+1]:= '$R';
"SendBuffer".data[N+2]:= '$L';
// Trigger the send
"TSEND_C_DB".REQ := TRUE;
"TSEND_C_DB".DATA := "SendBuffer";
"TSEND_C_DB".LEN := N + 3;
The CR/LF pair ($R$L) guarantees the receiver can split records on byte boundaries. The framing <...> lets the PC reject partial or out-of-order packets without needing the S7-1200 to negotiate record boundaries.
PC side — TCP listener outline
Any language that can open a TCP socket will work. A compact outline:
# Pseudo-code (PC listener)
listener.bind(0.0.0.0, 2000)
file = open("log.csv", "a", encoding="utf-8")
while running:
chunk = listener.recv(1024)
text = chunk.decode("ascii", errors="replace")
for line in text.splitlines(keepends=False):
if line.startswith("<") and line.endswith(">"):
file.write(line[1:-1] + "\r\quot;)
else:
file.write("# partial: " + line + "\r\quot;)
file.close()
The receiver writes each frame as one CSV row. Because every record carries an explicit CR/LF, the downstream tool never needs to guess the line boundary, and the # partial branch makes network noise visible in the log rather than corrupting real data.
Why this workaround is robust
- No file on the CPU. Internal flash is no longer in the loop, so the buffering-and-close behavior cannot truncate the data.
- No 25-record cap. Record count is bounded only by disk space on the PC.
- No reverse-order artifact. Records arrive and are written in send order, which is the chronological order the application wrote them.
-
Deterministic CR/LF. The S7-1200 appends
$R$Lto every record, so the receiving file is a clean CSV. - Protocol-agnostic. The same buffer can be read by a custom C# service, a Python listener, or an existing SCADA historian.
TSEND_C is connection-oriented and reaches that line rate when the records are larger than ~ 200 bytes. For short records, the round-trip latency of the partner's ACK dominates and the practical ceiling sits at 200–400 records per second — more than enough for typical process logging.
Verification
-
On the CPU: In TIA Portal, watch the Online → Data logs table (or remove the table if you have switched to TSEND_C) and confirm the
Statuscolumn remainsCLOSEDfor every log you rotate. -
On the wire: Use Wireshark on the PC side and filter by
tcp.port == 2000. EachTSEND_Ccycle should produce one TCP segment per record, with the last three bytes of the segment equal to0x3E 0x0D 0x0A(>\r\n). - On disk: Open the resulting CSV in Notepad with symbol view on. Each record must end with CR/LF, the file must have no partial lines, and the row count must equal the number of sends the CPU performed.
- In a spreadsheet: Open the same CSV in MS-Excel. With explicit CR/LF the rows import in send order, eliminating the reverse-order artifact observed with the broken on-CPU file.
Common Pitfalls and Edge Cases
-
Closing the log on every write is wasteful.
DataLogCloseforces a flash write; calling it inside a fast loop will exhaust the flash endurance in days. Close on rotation, not per record. -
TSEND_C buffer overflow. If the receiver is paused, the S7-1200 will raise
STATUS = 0x80C9on the TSEND_C instance. Either drop records on the CPU side or pause the producer when the partner disconnects. -
String encoding. The default TIA Portal string type is ASCII. Unicode (UTF-8) fields must be expanded to
WSTRINGor escaped in the PC listener; otherwise non-ASCII characters will be replaced by?. - PROFINET vs. Ethernet/IP on the 1214C. The 1214C has a single PROFINET interface; the TSEND_C connection runs on the standard TCP/IP stack and is independent of any PROFINET IO controller relationship.
- Factory reset does not clear the buffered tail. A MRES reset only clears the work memory; internal load memory is preserved for project retention. A reset, therefore, will not flush a half-written log file.
Best-Practice Checklist for S7-1200 Data Logging
- Fit a SIMATIC memory card whenever the application must keep more than 1 000 records or more than 50 KB of log per day.
- Always pair
DataLogCreatewith aDataLogCloseat the end of the log's life cycle — on STOP, on operator request, or before the nextDataLogCreate. - Use the Web server (PLC → Web server → enable data log) to download files. The Web server always returns the file with the most recently flushed page visible, so what you see is what is on the medium.
- When streaming to a PC, frame every record with
<...>and terminate with CR/LF. The framing is what makes the receiver tolerant of partial reads. - Log the CPU's
DTL(date-and-time) as the first field of every record. With a clean CR/LF the consumer can sort by that field; without it, the consumer is forced to guess. - Keep an eye on the diagnostic buffer for
Data Logevents. The S7-1200 raises an event on every open, close, and overflow; these events are the earliest signal that the flash is filling up.
References in the S7-1200 Documentation
- Working with data logs — Siemens TIA Portal documentation: TIA Portal S7-1200 manual collection — data logs
- SIMATIC S7-1200 Programmable Controller System Manual — Data Log section, extended instructions chapter.
- TIA Portal V11 SP2 release notes — Data Log extended instruction set (legacy).
Why does my S7-1214C data log stop at exactly 25 records?
The 25-record count is the size of the last fully flushed flash page in the CPU's internal load memory, not a firmware limit. Without a SIMATIC memory card, the trailing records stay in the write buffer and are lost on the next power cycle or project download. Fit a SIMATIC card or switch to a TSEND_C stream to bypass the limit.
Is the S7-1200 writing the data log backwards?
No. The CPU always appends records in the order they are written. The reverse-order display is produced by the consumer (MS-Word table view, TIA Portal online table, spreadsheet import wizard) when the file is missing its trailing CR/LF and the tool re-sorts the partial buffer by timestamp.
Why is the //End marker missing from my CSV?
The //End sentinel is written only when the Data Log is closed cleanly via DataLogClose or when the CPU enters STOP. If the CPU is power-cycled, restarted by TIA Portal, or the project is downloaded without a matching close, the file is truncated and the marker never reaches the medium. Add a DataLogClose call before every DataLogCreate or before every STOP transition.
Does a factory reset of the S7-1214C clear the corrupted log file?
No. A MRES factory reset clears the work memory but preserves the internal load memory that holds the project and the Data Log file. The corruption survives the reset. The only way to clear it is to delete the file via the Web server, remove the project, or fit a SIMATIC memory card and recreate the log on the new medium.
Is the TSEND_C approach reliable for long-term logging?
Yes, provided the PC listener is running whenever the CPU is producing records, and the partner acknowledges the TCP segments so the S7-1200 does not stall on a full send buffer. With an explicit CR/LF on every record and a <...> frame, the receiver can recover from any partial read, which is what makes the approach more robust than the on-CPU Data Log when no memory card is fitted.