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:
- 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.
- 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);
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.
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.
- On each rising edge of
bEdgeStart, write the current ISO week into the retain DBdbRetain.dwLastFireWeek. - On PLC startup (OB100), read
dwLastFireWeekand compare against the current ISO week. IfdwLastFireWeekequals the current week, forcediLastStart := 0in the scheduler to suppress the start edge. - If
dwLastFireWeekis 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
- In TIA Portal project tree expand SIMATIC S7-PLCSIM.
- Click the icon Start simulation (light bulb in the toolbar).
- PLCSIM opens with a project window showing the loaded CPU image.
- Right-click the CPU image and choose Download or use the project command Online > Download to device > SIMATIC S7-PLCSIM.
- The PLCSIM tool bar shows the operating mode - default is STOP; click the RUN button to start execution.
Driving the simulated clock
- Open the Tools menu in the PLCSIM window.
- Choose Options > Settings > CPU clock.
- Tick Use simulated clock - selects between Set time of day and Use real-time clock.
- Enter the desired date (YYYY-MM-DD) and time (HH:MM:SS).
- 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).
- 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, andValve_1react 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.
Verification Procedure
- Confirm
RD_SYS_Tis called every cycle. In OB1, mark the network and observeCURRENT_DTin the watch table - it must equal the host PC clock within ±1 s. - Set PLCSIM clock to Monday 05:59:30. Step the clock forward in 5-second intervals. Confirm
bActivetransitions TRUE at 06:00:00 and FALSE at 07:00:00 (boundary inclusion). - Step clock to 06:04:59. After the next scan past 06:05:00, confirm
Turbine_Latchis TRUE for exactly T#2s500ms. Use the trace ET pin to compare pulse width against the preset. - Step clock past 07:00:00, confirm all pulse tags roll down within one PLC scan and the generator contactor drops.
- Set PLCSIM clock to Tuesday 06:05. Confirm only the Tuesday cycle tags fire - Monday's
dbRetain.dwLastFireWeekmust not match Tuesday's ISO week. - 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.
- Drop PLCSIM clock to a previous day and confirm the retain DB correctly suppresses a re-trigger of the past window.
- 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.