S7-1200/1500 FTP Client File Format: CSV, TXT, XML Setup Guide
The Siemens S7-1200 (firmware 4.0 and higher) and S7-1500 CPUs support native FTP client operations through the TCP/FTP instructions in the TIA Portal communication palette. A common commissioning question concerns the on-disk file format the CPU writes when an FTP_WRITE or FTP_UPLOAD block is executed: the CPU does not perform any implicit format conversion. The file written to the FTP server is a byte-for-byte copy of the SendString you pass into the instruction. This reference documents the string syntax, delimiter conventions, project setup, and verification steps required to produce valid .csv, .txt, and .xml payloads from an S7-1200 or S7-1500 FTP client.
1. Overview of FTP Client Operation on S7-1200/1500
The FTP client functionality on S7-1200/S7-1500 is implemented as a set of extended instructions shipped with TIA Portal V13 SP1 and later. The relevant instruction set is found in Instructions > Communication > TCP/FTP. The reference application is documented in Siemens Support entry 81367009 - FTP Client Communication with S7-1200/1500.
The instruction family consists of:
-
FTP_CONNECT— opens the control connection (port 21 by default) and authenticates the user. -
FTP_OPEN— opens a passive data channel for read or write transfers. -
FTP_READ— pulls a file from the server into a PLC string/variant tag. -
FTP_WRITE— pushes a PLC string/variant tag to a file on the server. -
FTP_CLOSE— terminates the data channel and logs out.
The file format on the FTP server is defined entirely by the application program. The CPU never renames a file, swaps delimiters, converts encodings, or appends line terminators unless the user code explicitly does so. The file extension (e.g. .csv, .txt, .xml) is a free-text string passed to the instruction and is not validated by the PLC.
2. Prerequisites
Before commissioning the FTP client, verify the following:
| Item | Requirement |
|---|---|
| S7-1200 CPU | Firmware 4.0 or higher (FTP client added in V4.0) |
| S7-1500 CPU | Firmware 1.5 or higher recommended (V2.0 adds TLS/FTPES support) |
| TIA Portal | V13 SP1 minimum; V15.1 / V16 / V17 recommended for current library versions |
| CPU communication interface | PROFINET port configured with valid IPv4 address, subnet mask, gateway |
| FTP server | RFC 959 compliant server (see File Transfer Protocol (Wikipedia)); passive mode strongly recommended |
| Network | TCP port 21 (control) and dynamic high ports (passive data) reachable bidirectionally |
| User account | Read/Write/Append permissions on the target directory |
| Data block layout | A global DB with String or Variant tags for connection parameters and payload |
FTPES (explicit TLS) or wrap the traffic in a VPN. S7-1200 does not support FTPES natively.3. TIA Portal Project Setup
- Create or open your TIA Portal project containing the S7-1200/S7-1500 station.
- In the device configuration, open the CPU Properties > Ethernet addresses and assign a fixed IPv4 address. Disable DHCP unless your infrastructure is built around it.
- Open the project tree, right-click Program blocks > Add new block > Data block (DB). Create a global DB (e.g.
DB_FtpInterface) and disable optimized block access only if the legacyFTPxinstructions are used. - Define the following tags in the DB:
| Tag | Type | Example Value | Purpose |
|---|---|---|---|
| ipServer | String[15] | '192.168.0.50' | FTP server IPv4 address |
| userName | String[32] | 'plcuser' | FTP login |
| passWord | String[32] | 'secret123' | FTP password |
| fileName | String[64] | 'data.csv' | Target file name on server |
| SendString | String[1000] | (see Section 5) | Payload to upload |
| connectionId | UInt | 1 | FTP connection handle |
| busy | Bool | FALSE | Status output |
| error | Bool | FALSE | Error flag |
| status | Word | 16#0000 | Detailed status/error word |
- Ensure Connection mechanisms > Permit access via PUT/GET communication is enabled on the CPU only if external clients require it; FTP does not use this setting.
- If you are using the S7-1500 with TLS, configure the certificate store under CPU Properties > Security > Certificates and protocols and import the server CA.
4. The FTP_WRITE Call
The FTP_WRITE instruction is the instruction responsible for actually writing the payload to the server. The call signature (TIA Portal V16+) is:
FTP_WRITE(REQ := startTrigger,
CONNECTION_ID := 1,
FILENAME := 'data.csv',
APPEND := FALSE,
DATA := SendString);
FTP_WRITE_BUSY := busy;
FTP_WRITE_ERROR := error;
FTP_WRITE_STATUS := status;
Key parameters:
- FILENAME — Any string, including the dot extension. The CPU does not check the suffix.
-
APPEND —
FALSEoverwrites the file;TRUEappends. WithAPPEND := FALSEthe previous content is discarded at the next write. -
DATA — Either a
String,DInt,Real,Byte-array (Array of Byte) or aVariantpointing to a struct. The CPU sends the raw bytes of the tag up to the current length (for strings) or array size (for byte arrays).
5. CSV File Format Construction
CSV files are the most common target format for FTP uploads from PLCs. Because the CPU has no built-in CSV encoder, the application program must compose the entire file in a single String tag (or a Char array) before invoking FTP_WRITE.
The S7-1200/1500 string literal syntax supports escape sequences that are translated at compile time:
| Escape | Meaning | Use Case |
|---|---|---|
| $R | Carriage return (0x0D) | Line terminator (CR) |
| $L | Line feed (0x0A) | Line terminator (LF) |
| $N | New line (CR + LF, 0x0D 0x0A) | Windows-style line break |
| $T | Tab (0x09) | Tab-separated values |
| $' | Single quote | Embedded apostrophe |
| $$ | Dollar sign | Embedded dollar |
Example CSV payload assembled in a static initial value or via CONCAT/CHAR_TO_STRING logic:
// Single string literal - up to 254 chars in classic String, longer in String[1000]
MyCSVPayload := 'Value1;5;Quality;Good$R' +
'Value2;3;Quality;Bad$R' +
'Value3;7;Quality;Good$R';
When written to a file named File.csv on the server, the resulting file contains exactly:
Value1;5;Quality;Good
Value2;3;Quality;Bad
Value3;7;Quality;Good
Important formatting rules for the receiving application:
-
Separator: Semicolon (
;) is the European convention; comma (,) is required by RFC 4180. PLC program chooses what the consumer expects. -
Line terminator: Use
$N(CR+LF) for Windows consumers (Excel),$L(LF) for Linux/Unix pipelines. -
Decimal separator: Some PLCs emit a comma for the decimal point (German locale). To avoid CSV column-shift bugs, replace
'.'with','inReal-to-string conversion or vice versa with a smallREPLACEroutine before upload. - Header row: The PLC has to write the header row the first time the file is created; it is not generated automatically.
6. Plain Text and XML File Formats
For simple logging, the payload can be a raw text string:
SendString := 'Alarm 4711 triggered at 12:34:56$R' +
'Motor 2 stopped, code 0x0001$R';
With FILENAME := 'alarmlog.txt' the FTP server will store a plain ASCII log that any text editor can open.
For XML output, the application code must build a well-formed XML document manually. Example payload for a SCADA historian:
SendString := '<?xml version="1.0" encoding="UTF-8"?>$N' +
'<ProcessData timestamp="2024-05-12T10:00:00">$N' +
' <Tag name="TankLevel" value="78.4" unit="%" />$N' +
' <Tag name="Pressure" value="2.31" unit="bar" />$N' +
'</ProcessData>';
FILENAME := 'snapshot.xml';
Notes on XML:
- The S7 string type stores ISO 8859-1 / Windows-1252 bytes by default. To produce UTF-8, build the bytes in a
Array of Bytetag and pass that as theDATAVariant. - Watch the 254-character limit of the classic
Stringtype. For longer documents, useString[n]with n up to 2046, or use anArray of Bytetag. - The PLC will not validate the XML; malformed payloads are stored as-is.
7. Step-by-Step: First CSV Upload from an S7-1200
- Install TIA Portal V15.1 or higher and open/create the project.
- Add the S7-1200 CPU (firmware 4.0+) and a PROFINET subnet with a fixed IP address on the CPU.
- Create
DB_FtpInterfacewith the tags listed in Section 3. - Insert
FTP_CONNECT,FTP_OPEN,FTP_WRITE,FTP_CLOSEfrom the Instructions > Communication > TCP/FTP palette into a cyclic OB (e.g. OB1) or a time-driven OB (e.g. OB35). - Wire
REQofFTP_CONNECTto a one-shot trigger (rising edge of aStartUploadBOOL). - Use the Siemens example code from Support entry 81367009 as a template. Replace the example file name with
File.csv. - Assign the CSV payload to
SendStringusing the$R/$L/$Nsyntax shown in Section 5. - Compile the project (Ctrl+B) and download hardware and software to the CPU (Ctrl+L).
- Set the CPU to RUN.
- From any PC on the same network, open a command prompt and type
ftp 192.168.0.50(replace with your server IP), log in with the FTP user, and verify the file appears in the user's home directory. - Open the file in Notepad++, Excel, or a hex viewer and confirm the byte sequence matches the
SendStringpayload exactly.
8. Verification Procedure
After the first upload, perform these checks before signing off the commissioning:
| Check | Method | Pass Criteria |
|---|---|---|
| File present on server |
ls -la over FTP, or SFTP/SCP shell |
File.csv listed with current timestamp |
| File size | Compare to LEN(SendString) reported by the CPU |
Size matches payload length in bytes |
| Line terminators | Hex dump (xxd File.csv | head) |
0x0D 0x0A (CRLF) if $N used, 0x0A (LF) if $L used |
| Encoding | Open in Notepad with encoding set to ANSI/UTF-8 | No replacement characters; German umlauts intact |
| Decimal separator | Search file for , or . in numeric fields |
Matches consumer expectation |
| No truncation | Compare last bytes of file to last bytes of SendString
|
Identical |
| No BOM or extra header | Inspect first 3 bytes (BOM is EF BB BF) | File starts with expected payload character |
9. Common Status and Error Words
The STATUS output of each FTP instruction follows the standard Siemens protocol. Typical values seen during FTP write operations:
| Status (hex) | Meaning | Remediation |
|---|---|---|
| 16#0000 | No error / idle | None |
| 16#7000 | No job active | None |
| 16#7001 | First call after REQ rising edge | None |
| 16#7002 | Subsequent call, job running | None |
| 16#80C3 | FTP server returned error 5xx | Inspect server log; check file name and permissions |
| 16#80C4 | Local resource error (no free connection) | Close prior connections, increase connectionId pool |
| 16#80C8 | Authentication failure (FTP code 530) | Verify user/password; check server allow list |
| 16#8188 | File not found (FTP code 550 on read) | Check filename and case sensitivity on Linux server |
| 16#80A1 | Connection aborted / timeout | Check network, firewall, server status |
10. Troubleshooting Matrix
| Symptom | Likely Cause | Action |
|---|---|---|
| No file on server, BUSY never goes low | FTP_CONNECT failed, server unreachable | Test with Windows ftp.exe or Linux ftp client from the engineering station; ping server IP |
| File empty (0 bytes) |
SendString length is 0; FILENAME overwritten by next call |
Check LEN() before write; ensure APPEND := FALSE for new run |
| File shows characters like $R or $L literally | String escape was sent in a runtime-concatenated variable, not a literal | Use the literal form in DB initial value, or pre-allocate 0x0D/0x0A bytes in a Array of Byte
|
| CSV columns misaligned in Excel | Decimal point vs. decimal comma mismatch | Adjust regional settings or convert in PLC before upload |
| Status 0x80C8 every cycle | Server does not allow the PLC's user | Create the user on the FTP server; check chroot / home directory |
| Successful on first call, fails afterwards | Connection not closed, server hits max-connections limit | Always call FTP_CLOSE in a state machine terminal state |
| Upload OK, file has stray NUL (0x00) at end |
String tag max length is 254/2046; unused bytes are 0x00 |
Use LEFT() to trim to actual length, or use Array of Byte with exact size |
| Error on S7-1500 with TLS server | Certificate not trusted | Import CA into CPU certificate store; match common name (CN) |
| Random transfers in passive mode hang | Firewall blocking high data ports | Restrict server passive port range and open those ports explicitly |
11. Performance and Timing Considerations
An S7-1200 CPU 1214C writing a 1000-character payload over a 100 Mbit/s PROFINET link typically completes an FTP_WRITE cycle in 200–400 ms. The S7-1500 CPU 1515 is roughly twice as fast. Because the FTP instructions are asynchronous and CPU-bound only at the moment the TCP/IP stack is being serviced, the recommended pattern is a state machine in OB1 that:
- State 0 — Idle, waiting for trigger.
- State 10 — Call
FTP_CONNECTon rising edge ofStart. - State 20 — Wait for
BUSY := FALSEandERROR := FALSE. - State 30 — Call
FTP_OPENin write mode. - State 40 — Call
FTP_WRITEwith theSendStringtag. - State 50 — Call
FTP_CLOSE. - State 60 — Done; reset and wait for next trigger.
For file sizes above ~50 kB, use an Array of Byte tag as the DATA parameter and consider switching to FTPUT-style block transfer if available in your library version.
12. Field-Proven Tips
-
Filename timestamps: Build the file name in the PLC using
CONCAT(e.g.'log_' + DTL_TO_STRING(Now, 'YYYY-MM-DD_HH-mm-ss') + '.csv') to avoid overwriting previous data on the FTP server. -
Atomic writes: Write to
temp.csvfirst, then send a rename command (viaFTP_CMDif your library version includes it) tolog.csv. Downstream consumers never read a half-written file. -
Watch the time-out: The default TCP keep-alive on the S7-1200 is short. If the FTP server is slow, the control connection may drop before
FTP_WRITEcompletes. Increase the keep-alive in the CPU's Ethernet properties if your network has high latency. -
Localization: Strings in TIA Portal are 8-bit. To preserve non-ASCII characters in a
String, pre-encode them as UTF-8 bytes in a separateArray of Bytetag and concatenate.
FAQ
What firmware does the S7-1200 need for FTP client support?
Firmware V4.0 or higher. Earlier firmware versions (V1.0–V3.0) do not include the FTP instructions in the TIA Portal library. S7-1500 CPUs support FTP client from firmware V1.5 onward, with TLS (FTPES) added in V2.0.
Does the PLC automatically convert the file to CSV when I name it .csv?
No. The file extension passed in FILENAME is a literal string. The CPU writes the exact bytes of the DATA parameter to the server. To produce a valid CSV you must build the header row, delimiters, and line terminators ($R, $L, or $N) in the application code.
How do I embed a carriage return in a TIA Portal string literal?
Use the escape sequence $R for carriage return (0x0D), $L for line feed (0x0A), or $N for the Windows CRLF combination (0x0D 0x0A). These are translated by the compiler at download time, so they work in DB initial values and in code String literals.
What is the maximum file size the S7-1200/1500 can write via FTP?
With a String[n] tag the maximum is 2046 bytes. For larger payloads use an Array of Byte tag (the practical limit is the free work memory of the CPU; an S7-1214C can handle a few hundred kB per call). For multi-megabyte files, segment the upload across multiple FTP_WRITE calls using the APPEND := TRUE parameter.
Why is my CSV file showing extra spaces or NUL bytes at the end?
The S7 String type has a fixed maximum length; unused bytes are 0x00. When the CPU writes the string, the actual transmitted length is governed by the current length field, not the maximum length, so NUL bytes should not appear. If they do, trim the string with LEFT(SendString, LEN(SendString)) or use a CHAR_TO_STRING conversion that returns an exact-length string.