Overview
The Siemens S7-1200 and S7-1500 CPU families expose a system-defined PLC data type (SDT) called DataLog that backs the runtime file system used by the DataLogCreate, DataLogOpen, DataLogWrite, DataLogRead, DataLogClose, and DataLogDelete instructions. When an application needs more than one simultaneous log (for example, alarm history, recipe history, and batch history on the same CPU), the standard pattern of declaring a global DB per log quickly produces a large number of data blocks and a proliferation of wrapper functions, each tailored to one specific log ID.
Multi-instance data types solve this problem. By declaring DataLog as a Static tag of a function block (FB), the compiler allocates the structure inside the instance DB of the calling block, and the FB can be reused for as many logs as the program needs - each call carrying its own private log structure and its own private instance DB. This article documents the exact procedure for building a generic DataLog_FB in TIA Portal V17/V18/V19 with multi-instance DataLog tags, with the static tag spelling, the call syntax, the parameter mapping, and the verification steps that confirm a working deployment on the physical CPU.
Prerequisites
Before starting, verify the following:
- Siemens TIA Portal V17, V18, or V19 installed with the latest HSP (Hardware Support Package) that matches the target CPU order number. Earlier V16 builds also support the procedure, but the property dialogs differ.
- CPU firmware V4.4 or higher for S7-1200 (6ES7 2xx-1xxx), or V2.0 or higher for S7-1500 (6ES7 5xx-1xxx). Earlier firmware lacks the optimized
DataLogSDT and rejects multi-instance declarations. - A user program project with the target CPU configured in the device tree.
- Basic understanding of FB, FC, instance DB, and multi-instance concepts. Reference: SIMATIC S7 S7-1200/S7-1500 Programming Guideline (entry ID 81318674).
- Web server or SD card / SIMATIC memory card access to the CPU for runtime verification.
DataLog tag cannot be created inside an FC. If you attempt this in TIA Portal, the declaration table does not show the DataLog SDT in the type dropdown for an FC.DataLog System Data Type in TIA Portal
The DataLog SDT is a platform-defined structure that holds the metadata required to manage one log file on the CPU's memory card or internal flash. Its layout is opaque - the field list is hidden by the editor and managed by the firmware - but it occupies a fixed 64-byte footprint plus any internal bookkeeping the compiler adds. Because the SDT is an aggregate type, it can be embedded inside any user-defined structure, used as a multi-instance tag, or passed by reference (in/out) to other blocks.
Instructions that operate on a DataLog SDT require it to be supplied as the REQ or block input parameter that points to the structure. The system keeps the runtime state (file handle, current record number, error word, last written timestamp) inside the SDT itself, which is why the same SDT must always be passed to every instruction in the lifetime of a log - otherwise a new file handle is opened and the previous file becomes orphaned.
Multi-Instance Concept
Multi-instance means a block declares another FB (or system data type) as a Static tag. The compiler embeds the called block's instance memory inside the calling block's instance DB instead of generating a separate instance DB. Practical consequences:
- One FB can manage several independent
DataLoginstances by declaring severalDataLogstatic tags (e.g.Datalog1,Datalog2,Datalog3). - Each call to the FB from
OB1or another FB creates a new instance DB that contains all of those static tags. - No additional global
DB of DataLogis required, reducing the project symbol table by one entry per log. - Each instance DB has its own lifetime; the same FB can run in different priority classes without colliding on the same handle.
Reference: SIMATIC S7-1500 Motion Control - Function Block (FB) Multi-Instance Concept (entry ID 109751654). The same mechanism applies to any SDT, not just motion control blocks.
Step-by-Step: Creating a DataLog Multi-Instance FB
- Create a new FB in the project tree: Program blocks > Add new block > Function block. Name it
DataLog_FB(or a project-specific name). Leave the language as SCL or LAD, and set the "Number" automatically. - Open the FB editor and switch to the Interface section. In the Static section, declare a tag such as
Datalog1. For the data type, type the literal stringDataLogdirectly into the Data type column. Press Enter. TIA Portal validates the string and resolves it to the system PLC data type. - If the editor shows a red squiggle, the build is older than the firmware supports. Right-click the column and confirm that Show system data types is enabled in the column chooser. The
DataLogSDT is platform-supplied and should appear once the firmware is set on the CPU. - Declare additional static tags (
Datalog2,Datalog3, ...) using the same procedure. Each will be a separateDataLogSDT instance inside the parent instance DB. - Inside the FB code section, drop the
DataLogCreateinstruction. The block input that expects the log descriptor (sometimes labeledDBorLOG) is supplied by referencing one of the static tags, e.g.#Datalog1. TheDATAinput points to the data area to be written. - Repeat for
DataLogWrite,DataLogClose,DataLogOpen, andDataLogDelete, passing the same#Datalog1tag where the instruction expects the log descriptor. Never mix tags: the SDT passed toDataLogCreatemust be the exact same SDT that is later passed toDataLogWriteandDataLogClosefor the same logical log. - Add input parameters that allow the caller to choose which log to act on (e.g.
i_LogSelect : INT). Use a CASE or IF/ELSIF ladder to route the instruction's descriptor input between#Datalog1,#Datalog2, etc. - Compile the FB. The compiler should report zero errors. Open the generated instance DB (created automatically when an instance DB is added under the FB in the project tree) and confirm the
Datalog1,Datalog2tags appear with typeDataLog.
DB_any or to leave the data type field blank and try to typecast at runtime. The TIA Portal editor only accepts the literal string "DataLog" as the data type; nothing else will compile.Working Code Example (SCL)
FUNCTION_BLOCK "DataLog_FB"
TITLE = 'Generic DataLog Manager'
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
i_LogSelect : INT; // 1=Datalog1, 2=Datalog2, ...
i_Execute : BOOL; // rising edge triggers Create
i_FileName : STRING; // e.g. 'ALARM.LOG'
i_Record : VARIANT; // data to log
i_Close : BOOL; // close request
END_VAR
VAR_OUTPUT
o_Status : WORD; // STATUS output of the last instruction
o_Error : BOOL;
o_Busy : BOOL;
END_VAR
VAR
Datalog1 : DataLog; // multi-instance SDT #1
Datalog2 : DataLog; // multi-instance SDT #2
Datalog3 : DataLog; // multi-instance SDT #3
s_Instance : DWORD; // which SDT pointer is active
END_VAR
BEGIN
CASE i_LogSelect OF
1: s_Instance := DWORD#16#00000001; // routes to Datalog1 below
2: s_Instance := DWORD#16#00000002;
3: s_Instance := DWORD#16#00000003;
ELSE
o_Error := TRUE;
RETURN;
END_CASE;
IF i_Execute AND (i_LogSelect = 1) THEN
DataLogCreate(REQ := TRUE,
LOG := Datalog1,
NAME := i_FileName,
DATATYPE := VARIANT#VOID,
... );
ELSIF i_Execute AND (i_LogSelect = 2) THEN
DataLogCreate(REQ := TRUE,
LOG := Datalog2,
NAME := i_FileName,
... );
END_IF;
END_FUNCTION_BLOCK
When the FB is called from OB1 with a unique instance DB (DataLog_FB_DB_1, DataLog_FB_DB_2...), each call maintains its own private copies of Datalog1, Datalog2, Datalog3. The same FB call can therefore service any number of physical log files on the memory card, with the instance DB being the only piece of project data that grows per log.
Parameter Reference Table
| Instruction | Block input that consumes the SDT | Static tag binding | Notes |
|---|---|---|---|
| DataLogCreate | LOG / DB | #Datalog1 ... #DatalogN | Allocates the file; the SDT captures the handle. |
| DataLogOpen | LOG / DB | Same SDT used at Create | Reopens a previously closed file. |
| DataLogWrite | LOG / DB | Same SDT used at Create | Appends one record to the file. |
| DataLogClose | LOG / DB | Same SDT used at Create | Flushes buffers and releases the handle. |
| DataLogRead | LOG / DB | Same SDT used at Create | Reads the last N records into a target area. |
| DataLogDelete | LOG / DB | Same SDT used at Create | Removes the file from the memory card. |
Multi-Instance Naming and ID Selection at Runtime
To allow the caller to decide which DataLog SDT is in use, expose an integer input on the FB and route the descriptor to the matching static tag inside a CASE statement. This pattern keeps the FB callable for an arbitrary number of logs without duplicating code. A common approach is to also pass the file name as a string input, since each log has a unique name on the memory card. Avoid hard-coding the file name inside the FB; the multi-instance concept only saves effort if the same FB can be reused for different logs.
If the number of logs is determined dynamically (loaded from a recipe), consider using an array of DataLog instances. TIA Portal supports arrays of SDTs as Static tags; declare arr_Logs : ARRAY[1..32] OF DataLog; and index it with a runtime variable. Watch the instance DB size: each DataLog SDT contributes roughly 64 bytes plus a small overhead per element.
Verification and Testing
- Compile the project. The compile buffer must not report Unknown datatype 'DataLog'. If it does, the project is bound to a CPU whose firmware is older than V4.4 (S7-1200) or V2.0 (S7-1500) - update the device configuration.
- Download the project to the CPU. Open the instance DB in online mode and confirm that the
DataLogstatic tags are present and have valid offsets. - From the CPU's Web server, navigate to File Browser > Data Logs and verify that the file name you supplied appears after a Create call. The S7-1200 stores them under /DataLogs/, the S7-1500 under /DataLogs/ as well.
- Force
i_Execute := TRUEfrom a watch table, then confirmo_Status = 0(no error) and that the file grows by one record peri_Recordupdate. - Power-cycle the CPU (STOP/RUN) and call
DataLogOpenon the same SDT. The handle should be recovered and writes should resume at the previous record number.
Troubleshooting Matrix
| Symptom | Likely cause | Fix |
|---|---|---|
| Editor rejects "DataLog" as a data type | FC selected instead of FB | Convert the block to a Function Block; multi-instance is FB-only. |
| Compile error: Unknown datatype 'DataLog' | CPU firmware older than V4.4 / V2.0 | Update the device firmware or replace the CPU with a current order number. |
| STATUS returns 16#80B1 on DataLogCreate | File already exists with a different layout | Issue DataLogDelete first or generate a unique file name with a timestamp suffix. |
| DataLogWrite appends garbage records | Multiple FBs passed the same SDT, or two Create calls on the same SDT | Ensure each Create call uses a fresh SDT or a one-shot rising edge; never call Create twice on the same SDT without an intervening Delete. |
| File size grows unbounded | DataLogClose never called | Add a Close call on a controlled edge (e.g. on a recipe end event or on STOP transition). |
| Web server does not show the file | Memory card not present or path is wrong | Insert a SIMATIC memory card; confirm the user program is configured to store logs on the card, not in internal load memory. |
Field-Proven Caveats
Three practical points collected from repeated deployments:
-
SDT identity matters. A
DataLogSDT is a runtime resource. If the program uses two different FBs and both write to the same SDT pointer, the firmware will interleave the records and corrupt both files. Always route a single SDT to a single log. -
Optimized access. Set the FB and the instance DB to optimized access (
S7_Optimized_Access := 'TRUE'). Symbolic access is required for the SDT to be visible in HMI tag lists and Web server diagnostics. -
STOP/RUN behaviour. The SDT is held in the instance DB and is therefore retained across STOP/RUN only if the instance DB is configured as Non-retain by default and the file is reopened after a power cycle. Add a
DataLogOpencall on the first scan ofOB100for each log that should survive a power cycle.
FAQ
Can I use the DataLog datatype inside an FC instead of an FB?
No. The DataLog SDT requires a Static tag, and only a function block can carry Static tags. Create the FB, declare the static DataLog tag, and call the FB from OB1 with a unique instance DB.
How do I type the DataLog datatype so TIA Portal accepts it?
In the Static section of the FB interface, click the Data type column and type the literal text DataLog. Press Enter - the editor resolves the string to the system PLC data type. Do not type DB or DB_any.
What is the maximum number of DataLog SDTs I can embed in one FB?
Limited only by the instance DB size budget. Each SDT uses roughly 64 bytes. On an S7-1500 with 1 MB of work memory, more than ten thousand instances are theoretically possible, but the practical limit is the number of physical files the memory card can hold (typically a few hundred).
Do I need to call DataLogCreate on every STOP/RUN transition?
No. Create only when the file does not yet exist on the card. For a warm restart, use DataLogOpen on the same SDT to recover the previous handle. Add DataLogOpen to OB100 (warm restart) to recover persistent logs.
Can an array of DataLog SDTs replace a CASE statement?
Yes. Declare arr_Logs : ARRAY[1..N] OF DataLog; as a Static tag, then route the LOG input of the instruction through the array element. Use a runtime index in the array bounds (1..32) to keep the FB generic.