TIA Portal DataLog Multi-Instance Configuration in FBs

David Krause11 min read
SiemensTIA PortalTutorial / 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

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 DataLog SDT 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.
A function block (FB) is required. A function (FC) cannot carry static instance data, so the multi-instance 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 DataLog instances by declaring several DataLog static tags (e.g. Datalog1, Datalog2, Datalog3).
  • Each call to the FB from OB1 or another FB creates a new instance DB that contains all of those static tags.
  • No additional global DB of DataLog is 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

  1. 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.
  2. 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 string DataLog directly into the Data type column. Press Enter. TIA Portal validates the string and resolves it to the system PLC data type.
  3. 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 DataLog SDT is platform-supplied and should appear once the firmware is set on the CPU.
  4. Declare additional static tags (Datalog2, Datalog3, ...) using the same procedure. Each will be a separate DataLog SDT instance inside the parent instance DB.
  5. Inside the FB code section, drop the DataLogCreate instruction. The block input that expects the log descriptor (sometimes labeled DB or LOG) is supplied by referencing one of the static tags, e.g. #Datalog1. The DATA input points to the data area to be written.
  6. Repeat for DataLogWrite, DataLogClose, DataLogOpen, and DataLogDelete, passing the same #Datalog1 tag where the instruction expects the log descriptor. Never mix tags: the SDT passed to DataLogCreate must be the exact same SDT that is later passed to DataLogWrite and DataLogClose for the same logical log.
  7. 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.
  8. 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, Datalog2 tags appear with type DataLog.
A common mistake is to declare the static tag with the data type 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

  1. 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.
  2. Download the project to the CPU. Open the instance DB in online mode and confirm that the DataLog static tags are present and have valid offsets.
  3. 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.
  4. Force i_Execute := TRUE from a watch table, then confirm o_Status = 0 (no error) and that the file grows by one record per i_Record update.
  5. Power-cycle the CPU (STOP/RUN) and call DataLogOpen on 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 DataLog SDT 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 DataLogOpen call on the first scan of OB100 for 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.

Back to blog