Siemens TIA Portal Weekly Timer Programming and PLCSIM Simulation

David Krause15 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

This technical reference addresses two distinct but related engineering requirements on a Siemens SIMATIC S7-1200 or S7-1500 controller programmed with SIMATIC STEP 7 Basic (TIA Portal) V13 SP1 or newer:

  1. Implement a deterministic weekly timetable that drives a generator with a continuous output level and a turbine with a 2-second pulse, with optional per-cycle variations such as different irrigation valves or staggered start times.
  2. Validate the schedule offline inside the engineering tool, equivalent in concept to the LOGO!Soft Comfort V8.0 simulator, before downloading to a real CPU.

Both goals are reachable with stock TIA Portal building blocks: RD_SYS_T for the wall-clock read, IEC TP / TON / TOF for time-base timing, and S7-PLCSIM (bundled with the STEP 7 install package) for offline code verification. The remainder of the article covers the architecture, the SCL source, the actuator pulse design, and a methodical PLCSIM commissioning sequence.

Prerequisites

  • STEP 7 Basic V13 SP1 or higher (V15, V15.1, V16, V17, V18, V19 are field-supported as of writing). V13 SP1 is the lower bound because the DTL accessors (DTL_GET_MONTH, DTL_GET_DAY, ...) shipped with that update.
  • S7-PLCSIM installed in the matching version. PLCSIM is bundled in the STEP 7 V13 SP1 media and exposed as the project target SIMATIC S7-PLCSIM in the Devices & Networks view.
  • CPU with an internal real-time clock:
    • S7-1200 CPU 1211C, 1212C, 1214C, 1215C, 1217C - super-capacitor backup from V2.0 onward (typical 6 to 20 h).
    • For multi-day backup, install one of the following:
      - Signal Board battery 6ES7297-1AA00-0AA0 (vertical slot).
      - Battery board 6ES7297-1BA00-0AA0 (horizontal slot, CPU 1214C and above).
    • S7-1500 - integrated real-time clock hardware standard; retention from a CR2032 in CPU 1510-1518, drift ±60 ppm max (10 min/year).
  • PC running Windows 7 SP1 / Windows 10 (build 1607+) / Windows 11. PLCSIM V13 SP1 supports Windows 7; PLCSIM V18/V19 require Windows 10 64-bit minimum.

Reference the project setup that ships with the controller on the S7-1200 Programmable Controller System Manual (chapter 4 - Basic functions).

Time Architecture and Build Layers

Build the weekly application in three decoupled time layers. Keeping the layers separate prevents the scheduler from doing arithmetic on absolute time while a sequence is running, and it localises changes - swapping from Monday-only to Monday+Wednesday only touches the configuration DB.

Layer Question answered Tool Range
1. Weekly scheduler Is the wall clock inside the window right now? RD_SYS_T plus SCL compare block Years
2. Edge trigger Has this week's window fired yet? Retentive DB latch + compare Per ISO week
3. Sub-sequence How long should the actuator be held? IEC TP / TON / TOF 1 ms to ~24 d 20 h 31 m 23 s 647 ms (TIME data type)

The TIME data type covers all sub-sequence needs. Stretches that exceed one day still fit; any branch beyond ~25 days should be implemented as multiple TON instances stacked in SCL.

Reading the Hardware Clock with RD_SYS_T

The instruction RD_SYS_T is the only standardised, version-stable way to obtain the CPU wall-clock as a DTL tag (Date_And_Time). It lives under Extended instructions > Date and time > Clock in the program editor.

Input / Output Data Type Description
OUT DTL (Date_And_Time) Output in CPU local time zone
RET_VAL (implicit) INT 16#0000 = success, 16#80C1 / 16#80C3 = clock not available

Ladder / FBD placement in OB1:


// OB1 - Network 1
   RD_SYS_T  EN    ENO
              CURRENT_DT   // tag, type DTL, global DB

The instruction must be called cyclically - placing it inside a time-of-day interrupt (OB10) is also valid and means the wall clock is read only on interrupt. The DTL tag fields are then individually addressable. SCL excerpt to break the timestamp into integers for arithmetic:


   // dbSchedule - tag area
   iYear      : INT;
   iMonth     : INT;
   iDay       : INT;
   iHour      : INT;
   iMin       : INT;
   iSec       : INT;
   iWeekday   : INT;        // 1 = Sunday ... 7 = Saturday
   diMinuteOfWeek : DINT;   // 0..10079

   // SCL fragment
   iYear       :=  INT_TO_WORD(CURRENT_DT.YEAR);
   iMonth      :=  INT_TO_INT(CURRENT_DT.MONTH);
   iDay        :=  INT_TO_INT(CURRENT_DT.DAY);
   iHour       :=  INT_TO_INT(CURRENT_DT.HOUR);
   iMin        :=  INT_TO_INT(CURRENT_DT.MINUTE);
   iSec        :=  INT_TO_INT(CURRENT_DT.SECOND);
   iWeekday    :=  INT_TO_INT(CURRENT_DT.WEEKDAY);
   diMinuteOfWeek := ((INT_TO_DINT(iWeekday) - 2 + 7) MOD 7) * 1440
                     + (INT_TO_DINT(iHour) * 60)
                     + INT_TO_DINT(iMin);
S7-1200 vs S7-1500 DTL access: On S7-1200 firmware V2.0+, DTL fields are accessible directly on the tag symbol (CURRENT_DT.MONTH, CURRENT_DT.WEEKDAY). On S7-1500, use either direct field access or the DTL_GET_* IEC library functions, which both produce identical result.

RD_SYS_T returns the CPU clock in local time zone after daylight-saving adjustment if the project has not configured time zones or DST rules; for projects spanning DST transitions, configure the time zone on the CPU properties page and re-evaluate WEEKDAY via the local-time view of the timestamp.

Pulse vs. Continuous Output - Choosing the IEC Timer

Each actuator in the application has a different electrical signature; selecting the wrong IEC timer type causes either a relay failure or an over-pulse.

Output Behaviour required Suitable timer PT preset Latch strategy
Diesel generator Continuous TRUE from 06:00 to 07:00 (level, hold) None - direct from scheduler tag n/a Self-hold contactor, drop on bWindowActive = FALSE
Turbine start button 2-second pulse both to start and to stop the turbine through the pushbutton loop TP (pulse generator) T#2s500ms Buffered relay TP drives both Start and Stop terminals simultaneously
Irrigation master pump Hold TRUE for the 40-minute active window plus a 2-minute run-in delay TON (on-delay) + TP (start pulse) Delay TON: T#2m; Latch TP: T#2s TP primes an auxiliary relay; TOF drops if bWindowActive falls to FALSE
Irrigation valve #1 TRUE only inside the 40-minute window TP driven by window tag T#2s Solenoid - TP repeats each cycle of the timer

TP ladder fragment for the turbine latch:


   |    TP                          |
   |    Turbine_Pulse               |
   |    IN  : "sched".bTurbineStart |
   |    PT  : T#2s500ms             |
   |    Q   : Turbine_Latch         |
   |    ET  : Turbine_Pulse_Rem     |

Why T#2s500ms instead of T#2s: physical relays on the start button need pull-in time plus contact bounce; T#2s guarantees drop well inside the pushbutton detector but T#2s500ms tolerates degraded contacts.

SCL Scheduler Block

Create a function block fbScheduler with one instance per cycle. The block reads the system clock into a DTL and converts to a minute-of-week integer (0..10079) for cheap comparison against configuration values stored as integer constants in a DB.


FUNCTION_BLOCK "fbScheduler"
VAR_INPUT
   iStartMinOfWeek : INT;     // e.g. Monday 06:00 = 1*1440 + 360 = 1800
   iEndMinOfWeek   : INT;     // e.g. Monday 07:00 = 2160
   iBitMask        : BYTE;    // reset / unused flags
END_VAR
VAR_OUTPUT
   bActive         : BOOL;
   bEdgeStart      : BOOL;   // single-cycle TRUE at start
   bEdgeEnd        : BOOL;   // single-cycle TRUE at end
END_VAR
VAR STAT
   diNow           : DINT;
   diLastStart     : DINT;   // latched previous start minute
   bInit           : BOOL;
END_VAR
BEGIN
   // Pull the timestamp set in OB1
   diNow := ((INT_TO_DINT("dbTime".iWeekday) - 2 + 7) MOD 7) * 1440
            + (INT_TO_DINT("dbTime".iHour) * 60)
            + INT_TO_DINT("dbTime".iMin);

   // Window compare - closed-open
   IF (diNow >= iStartMinOfWeek) AND (diNow < iEndMinOfWeek) THEN
       bActive := TRUE;
   ELSE
       bActive := FALSE;
   END_IF;

   // Rising edge detect (start of window)
   IF bActive AND (diNow > diLastStart) AND (NOT bInit OR (diLastStart < iStartMinOfWeek)) THEN
       bEdgeStart := TRUE;
   ELSE
       bEdgeStart := FALSE;
   END_IF;

   // Falling edge detect (end of window)
   IF (NOT bActive) AND (diLastStart >= iStartMinOfWeek) AND (diLastStart < iEndMinOfWeek) THEN
       bEdgeEnd := TRUE;
   ELSE
       bEdgeEnd := FALSE;
   END_IF;

   IF bActive THEN
       diLastStart := diNow;
       bInit := TRUE;
   END_IF;
END_FUNCTION_BLOCK

The DB dbTime is populated once per scan by the OB1 RD_SYS_T + extraction code shown earlier. bEdgeStart is the pulse that triggers the turbine TP and the irrigation master TP exactly at the configured minute boundary; bEdgeEnd triggers graceful shutdown logic - useful to log a cycle-completion event.

Time zone and DST: If the project respects DST, add a 60-minute correction around the transition Sunday. A common technique is to disable scheduling for the affected two-hour window by forcing iEndMinOfWeek := iStartMinOfWeek for that week only, or to read a DST active flag from the CPU online properties.

Handling a Power-Cycle in the Middle of a Cycle

Field reality: the CPU often loses power during storms exactly when the irrigation system is on. The PLC must not attempt to re-run missed cycles. Implement a "do not re-trigger" latch on a retentive data block.

  1. On each rising edge of bEdgeStart, write the current ISO week into the retain DB dbRetain.dwLastFireWeek.
  2. On PLC startup (OB100), read dwLastFireWeek and compare against the current ISO week. If dwLastFireWeek equals the current week, force diLastStart := 0 in the scheduler to suppress the start edge.
  3. If dwLastFireWeek is older than the current week, clear the suppression and let the next scan perform the normal compare.

ISO 8601 week-number routine compatible with TIA Portal V13 SP1 SCL (algorithm published by Siemens Support):


FUNCTION "ISO_Week_Of_Year" : INT
VAR_INPUT
   iYear   : INT;
   iMonth  : INT;
   iDay    : INT;
END_VAR
VAR_TEMP
   y : DINT;
   d : DINT;
   dow : DINT;
   week : DINT;
   jan1Day : DINT;
   daysInYear : DINT;
END_VAR
BEGIN
   // Zeller-style day-of-week: 0 = Saturday, 1 = Sunday ... 6 = Friday
   y := INT_TO_DINT(iYear);
   IF iMonth <= 2 THEN
       y := y - 1;
   END_IF;
   // ... (full algorithm per Siemens FAQ 109768956)
   // Output week 1..53 with iYear 1900..2099 supported
   ISO_Week_Of_Year := INT_TO_INT(week);
END_FUNCTION

Reference the canonical implementation on Siemens Support FAQ 109768956 - Calculating the calendar week in SCL.

Real-Time Clock and Battery Options

Without any backup, the S7-1200 super-capacitor maintains the clock for roughly 6 to 20 hours depending on ambient and CPU load. The diagnostic buffer writes Event ID 16#0277 "Clock not set" when the CPU powers up with a discharged super-capacitor. For longer retention, install a battery option module:

Part Number Type Where it fits Retention
6ES7297-1AA00-0AA0 Signal Board battery Vertical Signal Board slot (any S7-1200 CPU) ~1 year typical
6ES7297-1BA00-0AA0 Battery board Horizontal slot of CPU 1214C / 1215C / 1217C ~1 year typical
6ES7297-1GA00-0AA0 Set of 4x CR2032 replacement cells For 6ES7297-1BA00-0AA0 board n/a
6GK7243-1BX30-0XE0 CP 1243-1 communications processor, NTP client capable Left-comm-port expansion N/A - keeps CPU clock synced via NTP

For unattended irrigation generators the most reliable solution is NTP. The CP 1243-1 firmware V3.2 or higher is a TCP / NTP client; once configured, the communication processor writes WR_SYS_T at user-configured intervals and the CPU clock stays accurate for the entire product lifetime.

Implementing Pulse Patterns for Generator vs Turbine

The two outputs (generator and turbine) have to be wired and timed differently on the terminal block. The PLC code, however, only manipulates Boolean tags.

Cycle element Sched tag Logic in code Wire to field
Generator / set Monday 06:00-07:00 bGenRun := bActive (direct, no timer) Hold contactor coil Q0.0 (DO module)
Turbine start/stop pushbutton latches 06:05-06:55 (only the START edge matters) TP with PT T#2s500ms, triggered by bEdgeStart Turbine TP output Q0.1 wired to both Start and Stop momentary push-button legs in parallel through buffer relays
Irrigation master pump 06:10 (2-minute delay before run) TON T#2m on bEdgeStart, TP T#2s to latch pump contactor Pump contactor coil Q0.2
Irrigation valve #1 06:10-06:50 bValve := TP(IN := bActive, PT := T#2s).Q Solenoid valve terminal block Q0.3

Designing the pulse at 2 s is necessary to guarantee that PLC scan time does not drop the pulse below relay pick-up time. TP uses the configured PT regardless of scan jitter, so a T#2s500ms pulse always looks like 2.5 s to the field, even on a CPU under heavy scan load.

S7-PLCSIM Offline Simulation

STEP 7 Basic V13 SP1 ships with the matching PLCSIM V13 SP1. The simulator is a software PLC that runs in the development PC and is selected as the target device in the TIA Portal project tree. There is no separate simulator runtime to download - the PLCSIM IS integrated in the project download flow.

Activating PLCSIM

  1. In TIA Portal project tree expand SIMATIC S7-PLCSIM.
  2. Click the icon Start simulation (light bulb in the toolbar).
  3. PLCSIM opens with a project window showing the loaded CPU image.
  4. Right-click the CPU image and choose Download or use the project command Online > Download to device > SIMATIC S7-PLCSIM.
  5. The PLCSIM tool bar shows the operating mode - default is STOP; click the RUN button to start execution.

Driving the simulated clock

  1. Open the Tools menu in the PLCSIM window.
  2. Choose Options > Settings > CPU clock.
  3. Tick Use simulated clock - selects between Set time of day and Use real-time clock.
  4. Enter the desired date (YYYY-MM-DD) and time (HH:MM:SS).
  5. Toggle Run simulation continuously to advance time automatically; or pause it and click Trigger clock event to step by user-set intervals (1 s, 1 min, 1 h).
  6. Inspect the running program via the same watch tables / online view used on a real CPU.

Forcing inputs and observing outputs

  • Add a watch table from Watch & force tables in the project tree.
  • Click Modify to 1 on the input tag bIOStart_Manual (a separate operator-input tag used to bypass scheduler for commissioning).
  • Verify Generator, Turbine_Latch, Pump, and Valve_1 react according to the configured masks.
  • Use Project trace to record a 24-hour cycle in compressed time and zoom into the 06:00 to 07:00 window for an audit trail.

Reference the operational details in the STEP 7 V13 SP1 SIMATIC STEP 7 Basic V13 SP1 Manual.

Differences from LOGO!Soft Comfort V8.0: LOGO!Soft has a graphical WEEKLY TIMER widget and TIMER widget placed onto the schematic - you wire inputs and outputs by dragging. TIA Portal has neither widget; you build the same logic with IEC blocks. PLCSIM also does not include a visualisation panel matching LOGO!'s screens. To compensate: build a SIMATIC WinCC Basic screen with a few status indicators and download it together with the PLC project - the runtime renders the same simulated tags.

Verification Procedure

  1. Confirm RD_SYS_T is called every cycle. In OB1, mark the network and observe CURRENT_DT in the watch table - it must equal the host PC clock within ±1 s.
  2. Set PLCSIM clock to Monday 05:59:30. Step the clock forward in 5-second intervals. Confirm bActive transitions TRUE at 06:00:00 and FALSE at 07:00:00 (boundary inclusion).
  3. Step clock to 06:04:59. After the next scan past 06:05:00, confirm Turbine_Latch is TRUE for exactly T#2s500ms. Use the trace ET pin to compare pulse width against the preset.
  4. Step clock past 07:00:00, confirm all pulse tags roll down within one PLC scan and the generator contactor drops.
  5. Set PLCSIM clock to Tuesday 06:05. Confirm only the Tuesday cycle tags fire - Monday's dbRetain.dwLastFireWeek must not match Tuesday's ISO week.
  6. Set PLCSIM clock to 04:00 then 09:00 on Monday. Confirm the PLC does not fire the missed cycles - it only fires the next scheduled window.
  7. Drop PLCSIM clock to a previous day and confirm the retain DB correctly suppresses a re-trigger of the past window.
  8. Stop PLCSIM, disconnect from the simulator, download to the real CPU, and repeat the verification with the hardware clock and a single physical output.

Troubleshooting Matrix

Symptom Likely cause Verification Remediation
Output never goes TRUE RD_SYS_T not called, or wrong DB referenced Online > Monitor OB1 - CURRENT_DT shows 1970-01-01 Place RD_SYS_T in a cyclic OB and ensure DB is global
Output stays TRUE indefinitely bActive set TRUE but never reset Watch bActive in watch table Add ELSE branch in SCL or R coil in LAD
Schedule fires twice in one week dbRetain.dwLastFireWeek not retentive Open DB properties and observe Retain checkbox Set the retain attribute in DB properties or via tag declaration RETAIN PERSISTENT
PLC loses time after power cycle Super-capacitor discharged or no battery Read Event ID 16#0277 "Clock not set" from diagnostic buffer Install Signal Board 6ES7297-1AA00-0AA0 or wire CP 1243-1 to NTP
TP stays high forever PLCSIM not in RUN Online > CPU operator panel - state STOP Click RUN on PLCSIM toolbar
Pulse too short to drive relay TP PT below mechanical pick-up Inspect ET in watch table - drops inside 1 s Increase PT to T#2s500ms
DST rolls clock back one hour Project time zone not configured CPU properties > Time of day - rules not set Enable DST rules on the CPU configuration page
RD_SYS_T returns error 16#80C1 Clock unit has lost configuration Diagnostic buffer entry Run online > Set time of day; on S7-1200 reset the clock master

Field Commissioning Tips

  • Place the cycle-entry DB on a separate, named data block per cycle - this makes scope-of-change plumbing simple and reduces cross-talk between cycles.
  • Tag every TP preset as a global constant symbol (e.g., uPt_turbine_pulse). Machine setters can change the pulse length from the HMI without a re-build.
  • Configure the PLCSIM clock to step at 30-minute intervals overnight for a full audit trail; record a 24-hour trace of every actuator tag, then export the trace CSV to a folder that can be diffed against future releases.
  • For fail-safe scenarios (e.g., fire pump, air-fan pre-start) wrap the scheduler output through the F-CPU telegram - use F-runtime group call in OB35; the IEC TP block is safe-side compatible.
  • When running on an S7-1500, allocate the scheduler block in the Program execution level "Cyclic interrupt OB30..OB38". Cyclic interrupt execution keeps deterministic scan-to-scan latency.

Frequently Asked Questions

How is a weekly timer built in TIA Portal V13 SP1 without a graphical weekly-scheduler widget like LOGO!Soft Comfort?

Read the CPU wall clock with RD_SYS_T in a cyclic OB, extract WEEKDAY / HOUR / MINUTE, and compare against minute-of-week integers stored in a global DB. Drive continuous outputs from the comparison result and pulse outputs from IEC TP instances.

What is the maximum preset duration for an IEC TON/TOF/TP on S7-1200?

The TIME data type covers -24 d 20 h 31 m 23 s 647 ms to +24 d 20 h 31 m 23 s 647 ms. For longer runs, use multiple cascaded TON instances or DTL subtraction in SCL.

Can the S7-1200 keep real time during long power-downs without a battery?

The integrated super-capacitor retains the hardware clock for 6 to 20 hours depending on ambient and load. For multi-day retention, install Signal Board battery 6ES7297-1AA00-0AA0 or the horizontal battery board 6ES7297-1BA00-0AA0 - both deliver approximately one year typical retention.

How do you simulate the program offline with TIA Portal V13 SP1?

Select SIMATIC S7-PLCSIM as the target in the Devices & Networks view, click Start simulation, then download the project. In PLCSIM open Tools > Settings > CPU Clock, enable Use simulated clock, and enter a starting date - ticks the clock forward by your chosen interval without disturbing the host PC clock.

How should the PLC behave when it was powered off during a scheduled window?

On restart the scheduler must detect that the configured start minute has already passed, mark the cycle as already fired in a retentive DB, and not queue missed events. Re-running skipped cycles back-to-back can stall actuators, blow fuses, or flood the irrigation main.

Back to blog