Creating Files on CF Card with SIMOTION Scout Runtime Functions

David Krause13 min read
Motion ControlSiemensTutorial / 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

Creating Files on CF Card with SIMOTION Scout Runtime Functions

Engineer's field reference for the SIMOTION Scout runtime file system library (available since Scout V4.4). Covers CF card file creation, CSV writing, the full set of _file* system functions, error handling with _getStateOfFile, and downstream TCP transport to a PC or Excel. Use this document when you need to log axis states, recipe data, or any 2D array of process values to a non-volatile medium on a SIMOTION D4x5 / C240 / P320 platform.

Verification note: Function signatures, mode strings, and return-code values shown here are derived from the SIMOTION system function library documentation. Always cross-check against the F1 online help of the exact Scout version installed on the engineering station. The library was first released in Scout V4.4 and has been retained (with minor extensions such as _directoryPathCreate) in V4.5 through V5.7.

1. When to Use the Runtime File API

SIMOTION controllers expose a DOS-like file system on the CompactFlash card (D4x5) or the SSD/HDD storage (C240, P320, P350). The runtime file API is the right tool when:

  • You need a low-level, programmatic CSV/TXT writer inside the controller, with no extra HMI or WinCC tag logging required.
  • You want to capture data only on the controller and pull it later (replacement recipes, fault snapshots, axis traces).
  • You are building a small to medium data set (a few hundred kB up to tens of MB). For very high-rate streaming, prefer the trace or a buffered Ethernet producer instead.

If the goal is real-time visualisation, use WinCC / TIA Portal HMI tags. If the goal is continuous 1 kHz data acquisition, use the SIMOTION trace and export via SCOUT. The runtime file API is best for event-driven logging, history archives, and recipe management.

2. Prerequisites and Compatibility

Item Requirement
SIMOTION Scout version V4.4 SP1 or higher (V4.5, V5.0, V5.1, V5.2, V5.3, V5.4, V5.5, V5.6, V5.7 supported)
Controller SIMOTION D410 / D425 / D435 / D445 / D445-1 / D455 (CF slot), SIMOTION C240 PN (CF or SSD), SIMOTION P320 / P350 (internal storage)
Storage Siemens-approved CF card, minimum 2 GB, formatted FAT16/32 by SIMOTION. Industrial-grade cards strongly recommended.
Project language Structured Text (ST) or Motion Control Chart (MCC) with ST call sites. LAD/FBD supported for invocation only.
Runtime version Must match the Scout version's RT build. Mixed versions are not supported.
Library Standard SIMOTION system library (no extra install on V4.4+). For TIA-based projects, integrate via SIMOTION SCOUT TIA.
File system layout. On a SIMOTION D4x5 the CF card is mounted under the path /CF_CARD/ in the runtime API. On C240/P320 the root is typically /USER/ (CF) or /SSD/ (SSD). Confirm the mount point via the controller's online diagnostic in SCOUT under Target system → File system.

3. The File System Function Library

The library exposes the following system functions. All are declared in the SIMOTION system library and may be called from any cyclic or sequential task with the correct priority.

Function Direction Purpose Typical Return
_fileOpen opens handle Opens or creates a file in modes r, w, a, r+, w+, a+. Mode string is a literal. DINT handle (>0) or error code (<0)
_fileClose closes handle Flushes and closes a previously opened handle. Always call after every successful _fileOpen. DINT 0 on success, error code on failure
_fileRead reads bytes Reads N bytes from current position into a BYTE buffer. Bytes actually read or error
_fileReadLn reads line Reads until CR/LF or buffer full into a STRING variable. Bytes read or error
_fileWrite writes bytes Writes N raw bytes from a buffer at the current position. Bytes written or error
_fileWriteLn writes line Writes a STRING followed by a CR/LF sequence. Use this for CSV row generation. Bytes written or error
_fileSetPosition seek Moves the file pointer for random-access read/write. 0 or error
_filehandle query Returns the handle of a previously opened file (or 0 if closed). DINT
_fileDelete delete Removes a single file. 0 or error
_fileRename rename Renames a file in place (same directory only). 0 or error
_fileCopy copy Copies a file to a new path. Overwrite behaviour depends on the implementation; check the help for your RT version. 0 or error
_getStateOfFile query Probes the state of a file or directory. Used for robust error handling before opening. State code (see Section 7)
_directoryPathDelete delete Removes an empty directory. Use _fileDelete first to clear contents. 0 or error

For directory creation, the related _directoryPathCreate function is available in V4.5+.

4. Project Setup in Scout

  1. Open the SIMOTION project in Scout, select the controller in the project tree.
  2. Add a new program source (ST) under Programs → Sources, for example fb_FileLogger.
  3. Declare an FB instance, for example instFileLogger, in the unit's data block.
  4. Insert the FB call into a suitable task. The BackgroundTask is the safe default for low-rate logging. For sub-millisecond determinism, use a synchronous IPO task (only if writing is rare and bounded).
  5. Compile and download. Verify the device's CF card is recognised in Target system → Diagnostics → File system.
Task safety. Never perform a _fileOpen / _fileClose cycle in a fast cyclic task (< 4 ms) without bounding the cycle count. A CF card write may take several milliseconds; if the task blocks you risk an IPO overrun alarm on SIMOTION D controllers.

5. Writing a CSV File: Step-by-Step

Typical use case: capture a 6-column by 500-row process matrix on a state change (for example, a recipe change or a fault) and persist it as DATA.CSV on the CF card for offline analysis. The approach is identical for a 1-D array or a struct-of-arrays, only the loop body changes.

5.1 Declaration block

FUNCTION_BLOCK fb_CsvLogger
VAR
    hFile        : DINT;        // file handle
    sPath        : STRING[255]; // full path incl. filename
    sLine        : STRING[255]; // single CSV row buffer
    nRow         : DINT;        // loop index
    nCol         : DINT;        // column index
    nBytes       : DINT;        // bytes written per line
    nState       : DINT;        // return of _getStateOfFile
    bBusy        : BOOL;
    bDone        : BOOL;
    bError       : BOOL;
    nErrorCode   : DINT;
END_VAR
VAR CONSTANT
    ROWS         : DINT := 500;
    COLS         : DINT := 6;
    SEPARATOR    : STRING[1] := ';';
    CRLF         : STRING[2] := '$R$N';  // CR LF, depends on locale
END_VAR

5.2 Open and write header

// Compose path: /CF_CARD/LOG/<timestamp>.CSV
sPath := '/CF_CARD/LOG/DATA.CSV';

// Probe: do not overwrite an existing file in append mode without checking
nState := _getStateOfFile(sPath := sPath);

IF (nState = 0) THEN
    // file does not exist - create new and write header
    hFile := _fileOpen(sPath := sPath, nMode := 'w');
ELSIF (nState = 1) THEN
    // file exists - append
    hFile := _fileOpen(sPath := sPath, nMode := 'a');
ELSE
    bError := TRUE;
    nErrorCode := nState;
    RETURN;
END_IF;

IF (hFile <= 0) THEN
    bError := TRUE;
    nErrorCode := hFile;
    RETURN;
END_IF;

bBusy := TRUE;
_fileWriteLn(hFile := hFile, sString := 'Col1;Col2;Col3;Col4;Col5;Col6');

5.3 Write the 6 × 500 data block

FOR nRow := 1 TO ROWS DO
    sLine := '';
    FOR nCol := 1 TO COLS DO
        sLine := CONCAT(sLine, REAL_TO_STRING(aData[nRow, nCol]));
        IF (nCol < COLS) THEN
            sLine := CONCAT(sLine, SEPARATOR);
        END_IF;
    END_FOR;
    nBytes := _fileWriteLn(hFile := hFile, sString := sLine);
    IF (nBytes < 0) THEN
        bError := TRUE;
        nErrorCode := nBytes;
        EXIT;
    END_IF;
END_FOR;

5.4 Close and signal completion

_fileClose(hFile := hFile);
bBusy := FALSE;
IF (NOT bError) THEN
    bDone := TRUE;
END_IF;

5.5 State machine overview

Trigger: write event _getStateOfFile exists? _fileOpen("w") _fileOpen("a") _fileWriteLn loop Error path _fileClose bDone = TRUE

6. Reading and Appending

To resume a previous log or pre-load parameters, use _fileOpen with mode "r" and a sequential _fileReadLn loop until the function returns 0 or a negative code.

hFile := _fileOpen(sPath := '/CF_CARD/LOG/PARAMS.CSV', nMode := 'r');
IF (hFile > 0) THEN
    WHILE (_fileReadLn(hFile := hFile, sString := sLine) > 0) DO
        // parse sLine, populate variables
    END_WHILE;
    _fileClose(hFile := hFile);
END_IF;

For random access (for example, patching one record out of 10,000), use _fileSetPosition to seek to an absolute byte offset, then _fileWrite / _fileRead. Records must be fixed length or the position must be computed from an index table.

7. Error Handling and State Codes

Always wrap file operations in a state machine and check return values. The exact numeric codes returned by _getStateOfFile and the file functions are version-dependent; treat the categories below as canonical:

Category Typical cause Recommended action
0 - OK / exists file is present, or operation succeeded proceed
1 - not present file or path missing create the file or fall back to defaults
2 - access denied write-protect tab on CF; missing rights; file currently open by another handle check medium, close orphan handles
3 - I/O error card pulled, FAT corruption, end of medium set bError, log to retentive variable, raise an HMI alarm
4 - invalid path illegal character, path too long (>255), directory does not exist call _directoryPathCreate first, normalise path
5 - invalid mode typo in mode string check the mode literal against the help

Mirror every _fileOpen with a guaranteed _fileClose in a finally-like state, otherwise the next open will fail because of the leaked handle. A simple pattern is to use a state variable eStep with cases IDLE, OPEN, WRITE, CLOSE, DONE, ERROR.

8. File Size, Performance, and Power Loss

  • CF card write latency on a D4x5 is typically 1 to 8 ms per block, but can spike to >100 ms on heavily fragmented or near-full cards. Buffer a 4 kB block in ST and call _fileWrite once per block, not per row.
  • File system type is FAT16 or FAT32 (per SIMOTION). Maximum single file size is 2 GB (FAT16) or 4 GB - 1 B (FAT32). 500 rows of 6 doubles with header is well under 100 kB.
  • On power loss the FAT may be inconsistent. Add a small header record (sequence number, checksum) and an integrity stamp written after _fileClose in a separate marker file (e.g. DATA.CSV.OK) so the PC importer can detect partial writes.
  • Do not log at the IPO/IPO_2 task level. Use BackgroundTask (default 1× or 8× base) or a slow ServoSynchronousTask to avoid overruns.

9. TCP Transfer to a PC or Excel

The runtime file API stores the data locally. To move it to a PC:

  1. Direct read via Scout. Open the controller online, navigate to Target system → File system, browse the CF card, and copy the file to the engineering station.
  2. FTP or SMB share. SIMOTION D controllers with the appropriate firmware option support FTP; consult the controller manual for the exact firmware function block. Mount a shared folder on the engineering PC and use _fileCopy to push the file across.
  3. Custom TCP. Program a TCP server on the SIMOTION side (using the TCP / UDP system function blocks) and a client on the PC (a .NET, Python, or LabVIEW application). Stream the file in 1 kB chunks after _fileOpen with mode "r". The PC client writes the stream directly to .csv and opens it in Excel without any format conversion - Excel interprets the ; separator when launched with the right locale, or via Data → From Text/CSV.
  4. Web server / OPC UA. On SIMOTION D455-2 with OPC UA server option, expose the latest log file as a method that returns a ByteString.

For a robust upload, send a small JSON or CSV header containing the file name, size, and a CRC, then the raw bytes. The PC can then verify integrity before deleting the file on the controller via the same TCP channel.

10. Diagnostics and Field-Proven Caveats

Symptom Likely root cause Remedy
_fileOpen returns negative immediately after a previous open handle not closed (exception path skipped _fileClose) centralise the close in a final state, always execute it on bError
CSV opens in Excel with all data in one column locale expects comma, file uses semicolon change the separator, or use Data → From Text/CSV with explicit separator
File present in Scout browser but PC cannot find it scanned under /CF_CARD/ on the controller, but missing on the engineering station's drive mapping use Scout's Read from CF to download, then map to a network share for the PC
Write blocks for 100+ ms, IPO alarm CF card full, fragmented, or low-grade replace with Siemens-approved industrial card; rotate files; check free space in _getStateOfFile
Strings truncated to 80 chars STRING variable dimensioned too small declare STRING[255] for path and row buffer
Folder does not exist error no implicit mkdir on _fileOpen call _directoryPathCreate first, or pre-create the directory via Scout
Real numbers written with locale decimal comma REAL_TO_STRING returns 1,234 on German locale force REPLACE_STR of , with . before writing, or build the string manually

11. Integration with WinCC and TIA Portal

When the project is part of a TIA Portal V17 / V18 build with the SIMOTION SCOUT TIA add-in, the file system functions remain identical. The CF card appears as a node of the SIMOTION device. Recommended integration:

  • Expose a trigger tag (BOOL) from WinCC that calls the FB instance via the connection configured in Device configuration → Communication.
  • Display the resulting file size as an HMI tag by reading FILE_SIZE via the standard diagnostics screens.
  • After upload to the PC, archive the file under a WinCC Audit or a SQL-backed tag logging database, in line with the plant's compliance regime.

12. Quick-Reference Checklist

  • [ ] Scout version ≥ V4.4 installed and matched to the controller's RT version.
  • [ ] Target directory created (use _directoryPathCreate or the Scout file browser).
  • [ ] Industrial-grade CF card inserted, write-protect tab off, <80% full.
  • [ ] STRING buffers declared as STRING[255] or larger.
  • [ ] Mode string spelled correctly ("r", "w", "a", with the leading and trailing quotes in the literal).
  • [ ] _getStateOfFile called before _fileOpen when overwriting is undesirable.
  • [ ] Every _fileOpen is paired with a _fileClose on a dedicated state.
  • [ ] Logging task is the BackgroundTask or a slow synchronised task, never the fast Servo.
  • [ ] Integrity stamp file written after _fileClose to detect power-loss truncation.
  • [ ] TCP/FTP transfer path tested end-to-end before the first production shift.

For a complete cross-reference of the function block set, open the Scout F1 help, navigate to System functions → File system. The Siemens Industry Online Support entry SIMOTION communication & programming (entry 102754925) is the umbrella document for related runtime libraries and is regularly updated when new Scout versions ship.

Frequently Asked Questions

Which Scout version first introduced the runtime file system functions (_fileOpen, _fileWriteLn, ...)?

Scout V4.4. The library is preserved in every subsequent release (V4.5 through V5.7) and the function signatures remain backward-compatible, with minor additions such as _directoryPathCreate in V4.5+.

What is the maximum file size I can create on the SIMOTION CF card?

Up to 2 GB on FAT16 or 4 GB minus 1 byte on FAT32 - the formats SIMOTION uses. For a 6-column by 500-row CSV you will use well under 100 kB, so size is not a practical limit; performance and fragmentation are.

Can I call _fileOpen from a fast ServoSynchronousTask?

No, not for the open/close cycle. CF card write latency can exceed 8 ms and will cause an IPO overrun. Use the BackgroundTask or a slow MotionTask, and buffer rows in an array before flushing with a single _fileWrite call.

How do I detect a power-loss that left a partial CSV on the card?

Write an integrity stamp file (for example DATA.CSV.OK) only after a successful _fileClose. The PC importer must check for the stamp before reading DATA.CSV; if the stamp is missing, treat the CSV as truncated and rename it to DATA.CSV.PARTIAL for manual recovery.

What is the best way to get the CSV onto a PC for Excel?

For ad-hoc transfer, use Scout's Target system → File system → Read. For automated transfer, run a TCP server on the SIMOTION that streams the file in 1 kB chunks to a PC client (Python, .NET, or LabVIEW) which writes it to disk and opens it in Excel. FTP is available on SIMOTION D controllers that have the matching firmware option.

Back to blog