Converting S7-300/400 IEC Timer Output to HH:MM:SS in SCL

David Krause15 min read
HMI ProgrammingSiemensTutorial / 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

1. Problem Statement and Design Goal

Many PCS 7 and STEP 7 applications drive a count-down using SFB 3 "TP", SFB 4 "TON", or SFB 5 "TOF" and need to show the remaining time on a WinCC or PCS 7 OS faceplate as HH:MM:SS, not as a raw 32-bit millisecond value. The IEC 61131-3 TIME data type that the three SFBs expose at output ET is a signed double integer in milliseconds; it is not a structured record with hours, minutes, and seconds, and the PCS 7 OS has no built-in conversion that renders it in human-readable form. The clean, reusable solution is a single SCL function block — typically called TimeSplit — that lives in the project's master data library at an unused FB number ≥ 2500, takes a TIME input, and produces three INT outputs (hours, minutes, seconds) for binding to the HMI. Once compiled once, the block can be instanced in every CFC chart that needs a count-down without re-coding the math.

This reference walks through the timer internals, the SCL source, the SIMATIC Manager authoring steps, the CFC wiring, the WinCC display configuration, the verification procedure, and a TIA Portal equivalent. The result is a portable building block that survives PCS 7 version upgrades and library re-imports.

2. Time and IEC Timer Internals on S7-300/400

On S7-300 and S7-400, TIME is a 32-bit signed value in milliseconds. The largest positive duration the type can hold is 2,147,483,647 ms, which is 24 d 20 h 31 min 23 s 647 ms. A count-down of one hour is internally the hex value 0x0036_EE80 or the literal T#1h; the same value read from a TP's ET output on a live CPU is 3,600,000.

The three IEC timer SFBs all share the same ET semantics for the time-related output. They differ in how that value evolves relative to the input edge:

SFB Name ET behaviour Typical use for a count-down
SFB 3 TP — pulse Rises with the rising edge of IN from 0 to PT, then counts down to 0 while Q is 1 Direct read of ET as the remaining pulse time
SFB 4 TON — on-delay Counts up from 0 to PT while IN is 1; remaining = PT − ET Compute PT − ET and feed the result into TimeSplit
SFB 5 TOF — off-delay Holds PT while IN was 1; counts down to 0 after IN falls to 0 Direct read of ET while Q is 1

Because the math is identical regardless of which SFB is used, TimeSplit can be paired with any of them. The SFBs and their parameter sets are described in the System Software for S7-300/400 System and Standard Functions reference manual available on the Siemens Industry Online Support portal.

SFB 3 "TP" IN ── TP ── Q PT ─────── ET Pulse generator ET (TIME, ms) FB 2500 "TimeSplit" i_TimeIn o_Hours o_Minutes o_Seconds HMI HH:MM:SS

3. Prerequisites: Toolchain, Project Setup, FB Number Allocation

  • SIMATIC PCS 7 V8.x / V9.x or STEP 7 V5.5 SPx project targeting an S7-300 (CPU 31x, CPU 31xC, ET 200S) or S7-400 (CPU 41x, CPU 41xH) AS. S7-1200 and S7-1500 use a different timer architecture and require the TIA Portal variant covered in §9.
  • STEP 7 V5.5 with the S7-SCL option package installed. The SCL source discussed here compiles cleanly against S7-SCL V5.3 SP1 through V5.5 as listed in the SCL manual.
  • CFC V8.x or V9.x for chart-level wiring and download.
  • WinCC V7.x or PCS 7 OS Runtime V8.x / V9.x for visualisation. The split INTs work on any WinCC I/O field; no faceplate library is required.
  • Free FB number ≥ 2500 in the CPU's symbol table. The Siemens Compendium Part A (creating user-defined technological blocks) reserves 0..2299 for the PCS 7 APL, 2300..2499 for vendor and standard libraries, and 2500+ for project-specific blocks. Picking a number in that window avoids clashes when the APL is re-imported.
  • For PLCSIM-based testing: S7-PLCSIM V5.4 SPx or later, with the same SCL option installed on the simulation host.
CPU firmware. SFB 3, 4, 5 are present in the operating system of every standard S7-300 and S7-400 CPU. On the very oldest S7-300 CPUs (firmware V1.x with order numbers 6ES7313-1AD00-0AB0 and similar) some optional SFBs are not loaded; verify the CPU's technical data sheet on the Siemens support portal before commissioning.

4. The TimeSplit Function Block: Interface and SCL Source

TimeSplit takes one TIME input and produces three INT outputs. The internal arithmetic uses 32-bit DINT registers to keep the modulo/divide chain free of 16-bit overflow on countdowns that approach the 24-day TIME ceiling. The o_Hours, o_Minutes, and o_Seconds outputs are 16-bit signed integers; a one-day countdown yields 86,400 seconds, which is well inside the INT range of −32,768..32,767. For a count-down longer than ~24 days promote the outputs to DINT.

FUNCTION_BLOCK FB2500 "TimeSplit"
// Splits a TIME duration in milliseconds into H, M, S integers.
// Place this FB in the master data library (FB number >= 2500).
// Reference: PCS 7 Compendium Part A, "Creating user-defined
// technological blocks". Compiles with S7-SCL V5.3 SP1 and later.

VERSION : '1.0'

VAR_INPUT
  i_TimeIn   : TIME;   // Remaining or elapsed time in ms
END_VAR

VAR_OUTPUT
  o_Hours    : INT;    // 0..n hours (n <= 596 for max TIME)
  o_Minutes  : INT;    // 0..59 minutes
  o_Seconds  : INT;    // 0..59 seconds
  o_MsRemain : INT;    // 0..999 residual ms (sub-second display)
END_VAR

VAR
  s_TotalMs   : DINT;  // Working register, raw ms
  s_TotalSec  : DINT;  // Working register, whole seconds
  s_Remainder : DINT;  // Seconds left over after hours
END_VAR

BEGIN
  s_TotalMs   := TIME_TO_DINT(i_TimeIn);
  s_TotalSec  := s_TotalMs / 1000;
  s_Remainder := s_TotalSec MOD 3600;

  o_Hours    := DINT_TO_INT(s_TotalSec / 3600);
  o_Minutes  := DINT_TO_INT(s_Remainder / 60);
  o_Seconds  := DINT_TO_INT(s_Remainder MOD 60);
  o_MsRemain := DINT_TO_INT(s_TotalMs MOD 1000);
END_FUNCTION_BLOCK

Variant for countdowns that may receive a negative TIME (e.g. when a TON-based subtraction overshoots zero at the end of the run):

VAR_TEMP
  t_Clamped  : TIME;
END_VAR
BEGIN
  IF i_TimeIn < T#0ms THEN
    t_Clamped := T#0ms;
  ELSE
    t_Clamped := i_TimeIn;
  END_IF;
  // ... same arithmetic with t_Clamped ...
END_FUNCTION_BLOCK
Signed TIME. TIME on S7-300/400 is signed, and PT − ET from a TON can go negative for one OB1 cycle after the count-up reaches PT. Either clamp at the input (as above) or promote the three outputs to DINT and let the OS handle the negative case with a 99-style format.

5. Authoring TimeSplit in the Master Data Library

  1. Open SIMATIC Manager and load the PCS 7 / STEP 7 project.
  2. In the project tree, expand the master data library that holds the project's technological blocks. The default name is the project name; PCS 7 templates use Master Data Library or a project-specific equivalent. Right-click S7 program → Source and select Insert New Object → External Source.
  3. Name the file TimeSplit.scl. Confirm the dialog. A new source object is added to the Source folder.
  4. Open the new SCL source (right-click → Open Object). The SCL editor launches.
  5. Select Options → Symbol Table and add an entry:
    • Symbol: TimeSplit
    • Address: an unused FB number ≥ 2500 (FB 2500 is conventional)
    • Comment: Splits a TIME value into H/M/S integers for the OS
  6. Save and close the symbol table.
  7. Paste the SCL source from §4 into the editor. Click File → Compile (or the Compile button in the toolbar). The SCL compiler writes FB 2500 and an instance-DB template into the master data library's Blocks folder.
  8. Close the editor. The block is now available to every CFC in the project under <Master Data Library> → S7 program\blocks → MyBlocks → TimeSplit.
Compile diagnostics. If the SCL compiler returns "FB 2500 already exists", a stale offline block is in the way: delete the old FB 2500 from the offline Blocks folder, recompile. If the error is "Untyped constant in expression", the symbol table was not saved before the compile — save and retry. If the error references a missing system function, the S7-SCL option is not installed on the engineering station.

6. Inserting and Wiring TimeSplit in CFC

  1. Open the CFC chart that owns the timer (typical name: CNT_DOWN, TIMER, or similar). The chart must already contain an instance of SFB 3/4/5 with the input wiring in place.
  2. In the CFC catalog pane, navigate to <Master Data Library name> → S7 program\blocks → MyBlocks → TimeSplit. Drag TimeSplit onto the sheet. A new instance DB (e.g. DB 4100) is created automatically by the CFC compiler.
  3. Wire the input i_TimeIn to the timer's ET output:
      TP_DB.ET  ---->  TimeSplit_DB.i_TimeIn
  4. For a TP-driven countdown, no further computation is needed — ET already decays from PT to 0 while Q is 1.
  5. For a TON-driven countdown, insert a SUB block (or compute inline) for PT − ET and feed that into i_TimeIn:
      TON_DB.PT  --SUB--
      TON_DB.ET  -----/-->  TimeSplit_DB.i_TimeIn
  6. Click Chart → Compile in the CFC editor. The SCL-generated block is compiled with the chart's other FBs.
  7. Download the program to the AS (PLC → Download in SIMATIC Manager, or Target System → Download in the CFC editor). The AS must be in STOP for the first download, RUN-P for subsequent ones.

7. Displaying HH:MM:SS on the PCS 7 OS and WinCC

After the CFC download, the three INT tags TimeSplit_DB.o_Hours, TimeSplit_DB.o_Minutes, and TimeSplit_DB.o_Seconds are visible to WinCC through the standard AS-OS connection (configured by PCS 7 OS — Compile OS). Two display strategies are common:

7.1 Three I/O fields with static colons

Field Tag WinCC I/O field format Sample
Hours o_Hours 9999 (decimal, zero-padded to four digits) 0001
Separator — Static text : :
Minutes o_Minutes 99 (zero-padded to two digits) 23
Separator — Static text : :
Seconds o_Seconds 99 (zero-padded to two digits) 45

Set the Output/Input property of each I/O field to Output and the Data format to Decimal with the width shown above. The three fields must be aligned with monospaced typography so the colons line up across screen updates.

7.2 Single concatenated string

To produce a single HH:MM:SS string tag (useful for a small operator panel that has only one text field), extend the SCL block with a fourth output:

VAR_OUTPUT
  o_TimeString : STRING[8];   // "HH:MM:SS"
END_VAR

VAR_TEMP
  s_H : STRING[4];
  s_M : STRING[2];
  s_S : STRING[2];
END_VAR

BEGIN
  // ... existing H/M/S assignments ...
  s_H := INT_TO_STRING(o_Hours);
  s_M := INT_TO_STRING(o_Minutes);
  s_S := INT_TO_STRING(o_Seconds);
  o_TimeString := CONCAT(STR:=s_H, IN2:=':');
  o_TimeString := CONCAT(STR:=o_TimeString, IN2:=RIGHT(STR:=s_M, LEN:=2));
  o_TimeString := CONCAT(STR:=o_TimeString, IN2:=':');
  o_TimeString := CONCAT(STR:=o_TimeString, IN2:=RIGHT(STR:=s_S, LEN:=2));
END_FUNCTION_BLOCK
Update rate. The three tags update on the OB1 cycle. With an OB1 of 100 ms the seconds value visibly ticks faster than wall time. To produce a 1-Hz tick, drive the splitter from a 1-Hz clock tag (TP with PT = T#1s) and update the OS only on the rising edge, using a WinCC C-action with the On change trigger. The PCS 7 OS faceplate editor supports this pattern via the Update property of the I/O field.

8. Verification, Commissioning, and PLCSIM Tests

  1. Offline compiler check. In the SCL editor, set a watchpoint on the Monitor/Modify dialog and force i_TimeIn = T#23h59m59s999ms. Expect o_Hours = 23, o_Minutes = 59, o_Seconds = 59, o_MsRemain = 999.
  2. Edge case: zero. Force i_TimeIn = T#0ms. Expect all four outputs = 0. Verifies that the DIV and MOD chain handles the lower boundary.
  3. Edge case: 1 ms. Force i_TimeIn = T#1ms. Expect o_Seconds = 0, o_MsRemain = 1. Catches a missing MOD 1000 in the millisecond residue.
  4. Edge case: 24 days. Force i_TimeIn = T#24d (= 2,073,600,000 ms). Expect o_Hours = 576, o_Minutes = 0, o_Seconds = 0. Confirms that the DINT intermediate is wide enough.
  5. PLCSIM online test. In S7-PLCSIM, load the SCL program and the CFC chart. Open the CFC online view and watch the three outputs decrement when a TP is triggered. Set the OB1 cycle to 1 s via PLCSIM → CPU → Cycle Time to verify the seconds tick matches wall time.
  6. OS faceplate check. Trigger the timer from the OS and confirm the text on the faceplate matches the PLC values to the second. Use the WinCC tag diagnosis (WinCC Explorer → Tools → Tag Diagnosis) to confirm the three tags are updating on the configured update cycle.
  7. Failure-mode test. Force TP_DB.PT = T#0ms and trigger the TP. The faceplate should show 00:00:00 with no negative values, confirming the clamp or the natural zero handling works as designed.

9. TIA Portal Equivalent (S7-1500) and Migration

When the project is migrated to TIA Portal, the same arithmetic applies with two changes: the IEC timer is a system-FB instance (no SFB number) and the time data type is LTime (64-bit nanoseconds) on S7-1500 / ET 200SP. The SCL source becomes:

FUNCTION_BLOCK "TimeSplit_TIA"
{ S7_Optimized_Access := 'TRUE' }
VERSION : '1.1'
VAR_INPUT
  i_TimeIn : LTime;   // nanoseconds on S7-1500
END_VAR
VAR_OUTPUT
  o_Hours    : DInt;
  o_Minutes  : DInt;
  o_Seconds  : DInt;
END_VAR
VAR
  s_TotalSec : LReal;
END_VAR
BEGIN
  s_TotalSec := LREAL_TO_DINT(
                  LTime_TO_LReal(i_TimeIn) / 1.0E9);
  o_Hours    := DINT_TO_DINT(s_TotalSec / 3600.0);
  o_Minutes  := DINT_TO_DINT(
                  DINT_TO_DINT(s_TotalSec) MOD 3600 / 60);
  o_Seconds  := DINT_TO_DINT(
                  DINT_TO_DINT(s_TotalSec) MOD 60);
END_FUNCTION_BLOCK

On S7-1200 the time type is TIME (32-bit milliseconds) and the source from §4 works unchanged. WinCC Comfort/Advanced on TIA Portal also accepts a TIME tag directly in an I/O field with a format string such as %d:%02d:%02d, which removes the need for a split block on a stand-alone Comfort panel — but the PCS 7 OS faceplate path still needs the explicit split because the OS only formats raw INT and REAL tags.

10. Alternative Approaches: APL Blocks, Batch_Time, Vendor Libraries

Before authoring a custom SCL block, check whether an existing library block already meets the requirement:

  • PCS 7 APL "TIMER_P" / "TIMER_TP". The Advanced Process Library includes timer blocks with extended diagnostics, but the output is still raw TIME — a separate split step is required for a human-readable HMI display.
  • PCS 7 Batch "Batch_Time". For batch-driven countdowns, the Batch Control Center renders a recipe parameter of type Batch_Time as HH:MM:SS automatically. This is the path of least resistance if the countdown is the batch step duration; it is not applicable to free-running timers.
  • Open-source SCL blocks. Several SCL "HMS" and "DTSplit" blocks are available; verify the licence and the input-type compatibility (S7-300/400 TIME vs TIA Portal LTime) before importing.
  • Formatting in the HMI only. Comfort/Advanced panels and some third-party SCADA packages accept a TIME tag with a format string. The PCS 7 OS V8.x and V9.x do not.

11. Troubleshooting Matrix

Symptom Likely cause Fix
HMI shows 00:00:00 while ET is non-zero CFC chart not downloaded; OS-AS connection down; AS in STOP Re-download the CFC; check the WinCC channel diagnosis; switch the AS to RUN-P
Seconds tick twice per second on the HMI Two instances of TimeSplit driving the same tags; or the OB1 cycle is faster than the OS update cycle and the tag refresh is doubled Search the program for duplicate instance DBs; or freeze the display with a 1-Hz enable tag from a TP(T#1s)
Hours wrap to a negative value at the end of the run Negative TIME fed in (PT − ET < 0 at the end of a TON) Clamp i_TimeIn to T#0ms with a SEL or LIMIT_2 block, or promote outputs to DINT and add a 0-floor in the OS
SCL compile error: "FB 2500 already exists" Stale block in the offline program Delete FB 2500 from the offline Blocks folder, recompile the source
SCL compile error: "Untyped constant in expression" Symbol table entry not saved before compile, or FB number conflict Save the symbol table, verify the FB number is unique in the S7 program
Display flickers between two values CFC cycle < OS update rate; the three INT tags update out of step across the AS-OS link Concatenate into a single STRING tag in the AS and bind one I/O field, or add a 1-Hz enable tag
Wrong colon positions on the HMI I/O fields are not in a fixed-width font Switch the I/O field font to a monospaced family (e.g. Courier New) and align the fields on a 5-px grid
TimeSplit instance not in the CFC catalog Master data library not registered in the project Right-click the project, Master Data Library → Assign, browse to the library that holds FB 2500

FAQ

What SFB do I read the remaining-time value from on S7-300/400?

Use SFB 3 "TP" for a self-decaying pulse, SFB 4 "TON" for a count-up that you then subtract from PT, or SFB 5 "TOF" for an off-delay. All three expose the current value at output ET as a TIME (DINT milliseconds) and are described in the System Software for S7-300/400 System and Standard Functions reference manual on the Siemens support portal.

Why does my OS show raw milliseconds instead of HH:MM:SS?

The PCS 7 OS does not auto-format TIME tags. Split the millisecond value into three INT fields on the AS (using TimeSplit or a comparable block) and bind each I/O field to one of those INTs with a zero-padded format, separated by static colons.

Can I avoid creating a custom FB and use a library block?

Yes. The PCS 7 APL timer blocks (TIMER_P, TIMER_TP) handle diagnostics but do not split time. The PCS 7 Batch library's Batch_Time parameter type produces HH:MM:SS in the Batch Control Center, but only for recipe-driven batch step times. A custom SCL block is the standard approach for free-running countdowns on S7-300/400.

Why is the SCL block recommended to live at FB 2500 or higher?

FB 0..2299 is reserved by the PCS 7 APL on the master data library side, and FB 2300..2499 is typically taken by Siemens and vendor add-on libraries. Placing your own technological blocks at FB 2500+ avoids accidental overwrite by a library update or re-import.

What is the largest countdown I can display with this block?

TIME in S7-300/400 is a signed 32-bit DINT in milliseconds. The maximum positive value is 2,147,483,647 ms, roughly 24 days 20 hours. The 16-bit INT outputs of TimeSplit saturate at 24 hours of whole-seconds output (86,400), so promote the outputs to DINT if the countdown is expected to exceed one day.

Does the same approach work on S7-1500 in TIA Portal?

Yes. The arithmetic is identical; the only changes are the IEC timer (now a system-FB instance with output ET of type LTime, 64-bit nanoseconds) and the data type of the input. A TIA Portal SCL variant is given in §9. WinCC Comfort/Advanced panels on TIA Portal can also accept a TIME tag with a format string and skip the split block entirely, but the PCS 7 OS still requires the explicit split.

Back to blog