Configuring S7-1200 Date/Time: DTL, RD_LOC_T, and KTP400 HMI Sync

David Krause13 min read
S7-1200SiemensTutorial / 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

Configuring S7-1200 Date/Time: DTL, RD_LOC_T, and KTP400 HMI Sync

Field-tested procedure for capturing event timestamps in an S7-1200 data block and synchronizing the CPU real-time clock to a KTP400 Basic Panel via the TIA Portal area pointer. Includes the DTL byte layout, RD_LOC_T and SET_TIMEZONE usage, and a troubleshooting matrix for the most common clock-mismatch faults.

1. Overview

The SIMATIC S7-1200 CPU maintains a battery- or capacitor-backed real-time clock (RTC) that continues running across power cycles. The clock is exposed to user programs as a DTL (Date and Time, Long) value, an eight-field structure that occupies 12 contiguous bytes. Three system instructions form the core date/time API in the S7-1200 instruction set:

  • RD_LOC_T (Read local time) — returns the current CPU local time as a DTL.
  • WR_LOC_T (Write local time) — writes a DTL value to the CPU clock.
  • SET_TIMEZONE (extended instruction) — configures the local time zone and DST rules (firmware V4.2 and later).

For an HMI such as the KTP400 Basic, the panel maintains its own RTC. Without explicit synchronization the panel clock drifts relative to the CPU, producing the symptom reported most often: the HMI displays a date and time that does not match the controller. TIA Portal resolves this through the Area Pointer for Date/Time on the HMI connection, which points to a DTL tag in the PLC that the panel reads on startup and on each user request to refresh the clock. The mechanism is documented in the official S7-1200 System Manual and the FAQ How do you synchronize the time between an S7-1200 and a SIMATIC Panel? on the Siemens support portal.

Compatibility note: The S7-1200 does not support the legacy DATE_AND_TIME (DT) data type or the older SFC0/SFC1 clock functions from the S7-300/400 world. All new code on S7-1200 and S7-1500 should use DTL. KTP400 Basic, KTP400 Comfort, and all TP panels support the DTL-based area pointer.

2. Prerequisites

  • STEP 7 Basic / Professional V15.1 or later (V16, V17, or V18 recommended for current firmware).
  • S7-1200 CPU, firmware V4.2 or later. DTL and the area pointer require V4.0 minimum; SET_TIMEZONE requires V4.2.
  • KTP400 Basic (6AV2 123-2DB03-0AX0) or KTP400 Comfort firmware V12.00.xx or later.
  • HMI connection configured in TIA Portal over PROFINET with a valid IP address on the panel.
  • CPU battery (where applicable) installed and healthy; otherwise the clock resets to 01.01.2011 00:00:00 after a power off long enough to discharge the retention capacitor.
  • Project consistency check passes (right-click PLC > Compile > Software (rebuild all blocks)) before downloading.

3. DTL Data Type Structure

DTL is a structured data type with eight fields. When declared in a DB the total length is 12 bytes:

Size(DTL) = 2 (YEAR, UINT) + 1 (MONTH) + 1 (DAY) + 1 (WEEKDAY) + 1 (HOUR) + 1 (MINUTE) + 1 (SECOND) + 4 (NANOSECOND, UDINT) = 12 bytes

Byte offset Field Data type Range Notes
0..1 YEAR UINT 1970..2554 Calendar year, big-endian
2 MONTH USINT 1..12 1 = January, 12 = December
3 DAY USINT 1..31 Day of month
4 WEEKDAY USINT 1..7 1 = Sunday, 2 = Monday, … 7 = Saturday
5 HOUR USINT 0..23 Local time hour
6 MINUTE USINT 0..59
7 SECOND USINT 0..59
8..11 NANOSECOND UDINT 0..999 999 999 Sub-second resolution
Field note: RD_LOC_T on the S7-1200 returns the NANOSECOND field as zero. The sub-second granularity exposed by the S7-1500 high-precision time functions (RD_SYS_T) is not available on the S7-1200. For millisecond event logging, combine the DTL second with an IEC timer (TP / TON) started at the same instant, or migrate to an S7-1500 with firmware V2.0 or later.

4. Step 1 — Create a Global DB for RTC and Event Timestamps

In the project tree, expand Program blocks > Add new block > Data block. Name it DB_RTC and uncheck Instance data block. Inside the DB declare the following variables:

Symbol Data type Address (non-optimized) Initial value Comment
LiveClock DTL DBB0 DTL#1970-01-01-00:00:00 Continuously updated CPU local time
EventStamp DTL DBB12 DTL#1970-01-01-00:00:00 Latched timestamp of the last event
EventID DINT DBD24 0 Source tag that triggered the event
EventTrigOld BOOL DBX28.0 FALSE Edge-detect memory for EventTrig

Decide deliberately between Optimized block access and standard access. Both layouts support DTL; however, the area pointer on KTP Basic panels historically resolves only by absolute byte address. If you plan to use the area pointer mechanism and you may recompile the project in older TIA Portal versions, choose a non-optimized DB with manually addressed symbols. TIA Portal V14 SP1 or later resolves symbolic names in the area pointer, so optimized access is acceptable in modern projects. If in doubt, keep "Optimized block access" disabled for the clock DB.

5. Step 2 — Implement RD_LOC_T to Read the Local Time

Open OB1 (or any cyclic OB) and insert the Date and time-of-day > RD_LOC_T instruction. The OUT parameter must point to the LiveClock DTL tag you just created.

SCL example (preferred for readability):

// Cyclic OB — update LiveClock every scan
"DB_RTC".LiveClock := RD_LOC_T();

Ladder equivalent:

  1. Drag RD_LOC_T from the instructions catalog (Extended Instructions > Date and time-of-day).
  2. Click the OUT operand placeholder and type "DB_RTC".LiveClock.
  3. Compile the program and download to the CPU.

To verify the tag is being written, open an online watch table and add "DB_RTC".LiveClock. The YEAR, MONTH, DAY, HOUR, MINUTE, and SECOND fields should change each second. If the values are frozen, check that OB1 is actually being executed (CPU is in RUN, not STOP) and that the tag is fully qualified with the DB name. RD_LOC_T is non-blocking; you do not need to evaluate a status word unless you want to detect a CPU-in-STOP condition.

6. Step 3 — Latch an Event Timestamp with Edge Detection

To capture the time of an event rather than a continuously running value, add a small edge-detect block that latches LiveClock into EventStamp on a rising edge of an event trigger (e.g., a start pushbutton, an alarm condition, or a recipe-loaded bit).

// SCL — rising-edge latch in OB1
IF "EventTrig" AND NOT "DB_RTC".EventTrigOld THEN
    "DB_RTC".EventStamp := "DB_RTC".LiveClock;
    "DB_RTC".EventID    := "SourceTag";
END_IF;
"DB_RTC".EventTrigOld := "EventTrig";

This pattern is preferable to a direct MOVE of LiveClock to EventStamp, which would over-write the captured value on every scan. The single DTL assignment in SCL compiles to a block copy of 12 bytes; the compiler can typically map it to a single CPU instruction, so the cycle-time impact is negligible. For an array of events, use an SCL FOR loop with a sliding buffer:

// Shift a 16-entry event log on every new event
IF "EventTrig" AND NOT "DB_RTC".EventTrigOld THEN
    FOR #i := 15 TO 1 BY -1 DO
        "DB_RTC".EventLog[#i] := "DB_RTC".EventLog[#i - 1];
    END_FOR;
    "DB_RTC".EventLog[0] := "DB_RTC".LiveClock;
END_IF;
"DB_RTC".EventTrigOld := "EventTrig";

7. Step 4 — Configure the KTP400 HMI Area Pointer

The area pointer is the mechanism that tells the HMI where the PLC's DTL clock value lives. Without it the panel reads its own internal RTC only and the time will drift. The Siemens FAQ 39182145 covers this configuration in detail.

  1. In the project tree, expand HMI > Connections and double-click the S7-1200 connection.
  2. Select the Area pointer tab.
  3. Activate Date/Time by checking the checkbox.
  4. In the PLC tag field, click the selector and pick DB_RTC > LiveClock.
  5. Click OK and recompile the HMI.
  6. Download the HMI project to the panel and restart the runtime.
Critical: The area pointer for Date/Time must reference a DTL tag. Pointing it at a BOOL, INT, or STRING will fail at compile time or cause the panel to log "Area pointer invalid" in the HMI diagnostic buffer. If the symbol selector refuses to let you pick a non-DTL tag, that is the editor enforcing the type rule.
S7-1200 CPURD_LOC_T (cyclic) DB_RTC.LiveClockDTL (12 bytes) Area PointerDate/Time (HMI conn.) KTP400HMI RTC DB_RTC.EventStampDTL latch on edge HMI Tag PLC_ClockType Date/Time Clock data flow: CPU RD_LOC_T -> DB tag -> Area Pointer -> HMI

8. Step 5 — Bind HMI Tags for Date and Time Display

The HMI's internal time/date display on the system screen, and the time/date field on any user screen, is fed from the area pointer. To show the PLC time on a custom screen:

  1. Create an HMI tag named PLC_Clock, type Date/Time.
  2. Set PLC connection to the S7-1200 connection and PLC tag to DB_RTC.LiveClock.
  3. Drag an Output field onto the screen, switch its display mode to Date/Time, and bind it to PLC_Clock.
  4. Format the display in the Properties > Appearance > Format dialog (for example yyyy-MM-dd HH:mm:ss).

The system clock at the bottom-right of the HMI runtime is driven from the same area pointer. If the screen shows the correct PLC time after step 4, the system clock will follow suit on the next refresh cycle. To force a manual write from the HMI to the PLC (for example, to push an operator-entered time back to the controller), add a button with the SetPLCDateTime system function on the HMI side; it will write through the same area pointer.

9. Time Zone and Daylight Saving Configuration

By default the S7-1200 reports local time without DST adjustment. SET_TIMEZONE lets you declare the offset from UTC and the DST rules. The instruction is found under Extended Instructions > Date and time-of-day > SET_TIMEZONE.

// Configure UTC+1 with European DST rules, called once on startup
#Status := SET_TIMEZONE(
    TimeZone            := WSTRING#'CET-1CEST,M3.5.0,M10.5.0/3',
    Dst                 := TRUE,
    TimeZoneHourOffset  := 1
);
IF #Status <> 0 THEN
    // Log error to diagnostic buffer or alarm
END_IF;

The string CET-1CEST,M3.5.0,M10.5.0/3 follows POSIX TZ syntax: standard time CET is UTC-1 (i.e., 1 hour ahead of UTC), DST is CEST, DST starts on the last Sunday of March (month 3, week 5, day 0) and ends on the last Sunday of October, switching at 03:00 local time. Adjust the string to match your local convention (e.g., EST5EDT,M3.2.0,M11.1.0/2 for US Eastern Time, or <-03>3<-02>,M10.1.0/0,M2.3.0/0 for Argentina, which does not observe DST). Place the call in OB100 (warm restart) so it runs every time the CPU returns to RUN.

Field note: SET_TIMEZONE was added in firmware V4.2. CPUs running V4.0/V4.1 will reject the call with a "FB not found" compile error. Either upgrade firmware via TIA Portal (Online > Diagnostics > Firmware Update) or implement manual DST handling in user code: compare the MONTH and DAY fields on the transition dates and add 3600 s to a UTC DTL via a hand-coded conversion. The official S7-1200 System Manual contains the SET_TIMEZONE parameter list and TZ-string grammar.

10. Diagnostics and Verification

Use the following checks to confirm the clock chain is healthy after commissioning:

  1. Online > Diagnostics > Time: the CPU's online diagnostic page shows the current local time and time zone. Compare it to a reference (laptop NTP-synced time). A difference greater than 2 seconds indicates a missed refresh in the HMI area pointer or a stalled OB1.
  2. HMI diagnostic buffer: connect with WinCC to the panel and read Diagnostics > Buffer. Entries containing Area pointer confirm whether the panel found the DTL tag on startup. Persistent "Area pointer invalid" entries mean the wrong tag was selected or the DB is not reachable from the HMI connection.
  3. Watch table cross-check: with the HMI online, the DB_RTC.LiveClock value on the HMI tag monitor should match the PLC online view within 1 second.
  4. Power-cycle test: shut the CPU down for 5 minutes and power back up. The clock should resume within ±10 s of the original time. If it resets to 01.01.2011, the battery is dead or absent.
  5. PROFINET diagnostics: from the PLC side, look at Online > Online & Diagnostics > PROFINET interface > Port statistics. Excessive CRC errors on the HMI port will prevent the area pointer handshake from completing.

11. Troubleshooting Matrix

Symptom Most likely cause Fix
HMI shows 01.01.2011 00:00:00 CPU battery dead; clock lost on power-down Replace CR2032 on supported CPUs. On capacitor-backed CPUs (some 1212C variants), keep power off < 20 days or fit a BB 1297 battery board
HMI time differs from PLC by hours Time zone or DST not applied Configure SET_TIMEZONE in OB100 startup, or manually apply UTC offset in user code
HMI time frozen at compile time Area pointer not configured or wrong tag type Check HMI connection > Area pointer; ensure referenced PLC tag is DTL
"Area pointer invalid" in HMI diagnostic buffer DB is optimized and pointer resolves by absolute address, or pointer points to a non-DTL tag Disable "Optimized block access" on the DB, or recreate the pointer using the symbolic name (TIA Portal V14 SP1+)
RD_LOC_T status returns non-zero CPU in STOP, or no time set Run CPU; set time once via TIA Portal online > "Set time"
EventStamp never updates Edge detection not implemented; LiveClock copied directly into a tag already in use Add an edge bit as shown in section 6; verify the trigger tag is pulsing in the watch table
KTP400 shows "–" or "Invalid date" on system clock HMI has not completed area pointer handshake Restart HMI runtime; check PROFINET cable diagnostics; verify the HMI connection is in "Reachable" state in the project
DTL write returns out-of-range YEAR field set below 1970 or above 2554, or MONTH outside 1..12 Validate the source DTL before WR_LOC_T; clamp YEAR to [1970..2554] and MONTH to [1..12]
Time drifts after DST transition SET_TIMEZONE string has wrong month/week token Verify TZ string with a POSIX reference; remember that "M3.5.0" means last Sunday of month 3, not the 5th Sunday
Compile error "DB_RTC.LiveClock not a DTL" Tag declared as Date_And_Time (DT) by mistake Change the data type of the DB tag to DTL, not DATE_AND_TIME; recompile

12. Frequently Asked Questions

What is the difference between DTL and the legacy DT (DATE_AND_TIME)?

DTL is a 12-byte structured type used on S7-1200 and S7-1500 with explicit fields (YEAR, MONTH, DAY, WEEKDAY, HOUR, MINUTE, SECOND, NANOSECOND). DATE_AND_TIME is the older 8-byte BCD-encoded type used on S7-300/400. They are not interchangeable; a DTL tag cannot be assigned to a DT operand and vice versa.

How often does the HMI refresh its clock from the PLC?

The area pointer is read on HMI startup and on every user action that displays a time/date field. Comfort panels poll the area pointer once per second by default; Basic panels poll on demand. For sub-second accuracy on the HMI, drive the display from a separate event-based tag rather than the system clock.

Can I synchronize the PLC clock from the HMI instead of the other way around?

Yes. If the panel has internet/NTP access or a manual time entry, you can set the PLC clock using WR_LOC_T in OB1 or from a script. The DB_RTC.LiveClock tag will then update with the panel's time on the next RD_LOC_T call. Use a one-shot boolean to avoid a feedback loop and to keep the PLC from being overwritten every scan.

Why does SET_TIMEZONE fail on my S7-1200?

SET_TIMEZONE requires firmware V4.2 or later. If the FB is missing from the instructions catalog, your CPU firmware is older. Upgrade via TIA Portal (Online > Firmware Update) or perform DST adjustments manually in user code by comparing MONTH and DAY fields and adding 3600 s to the clock once a year on the transition date.

What battery is used for the S7-1200 RTC backup?

Most S7-1200 CPUs (1211C, 1214C, 1215C, 1217C, and the fail-safe variants 1214FC/1215FC) accept a CR2032 lithium coin cell inserted into the removable battery holder on the front. Some 1212C variants are capacitor-backed for approximately 20 days; for longer retention, add a BB 1297 battery board to the CPU's signal board slot. A dead or absent battery causes the clock to reset to 01.01.2011 00:00:00 on every power cycle.

Why does the area pointer compile only when the DB is non-optimized?

KTP Basic panels (firmware V12 and earlier) resolve the area pointer by absolute DB byte address and cannot walk the optimized-block symbol table. Comfort panels and TIA Portal V14 SP1+ support symbolic pointers, so optimized access works. To keep the project portable across panel firmware versions, leave the clock DB non-optimized.

Back to blog