Configuring S7-300 OB10-OB17 Time-of-Day Interrupts for Lighting Control
Automating a facility's lighting with a SIMATIC S7-300 or S7-400 PLC is one of the most common educational and field commissioning tasks for early-career automation engineers. The cleanest way to do it is to use the CPU's native Time-of-Day interrupt organization blocks (OB10 through OB17), which the operating system calls automatically at a configured date and time without any scan-time polling, RTU logic, or external timer. This reference walks through the full configuration, programming, verification, and fault-recovery procedure for a representative application: lights ON at 18:00 and OFF at 06:00 every day.
1. Why Use Time-of-Day Interrupts Instead of Cyclic Polling
A 6 AM/6 PM scheduler can be implemented four different ways on an S7-300:
| Method | Mechanism | Scan Load | Drift Risk | Notes |
|---|---|---|---|---|
| Time-of-Day OB (OB10-OB17) | CPU RT interrupt at configured DT | None (event-driven) | None (hardware RTC) | Preferred; up to 8 daily events per S7-300, 16 on S7-400 |
| SFC1 READ_CLK compare in OB1 | Compare current time to setpoints each cycle | ~50-200 µs per call | Up to one OB1 cycle (~10 ms) | Useful for time-window logic (e.g. dusk-to-dawn) |
| IEC timers (S_ODT, S_PULSE) | Free-running timers in OB1 | Constant | High (no RTC anchor) | Not recommended for absolute time-of-day |
| External astronomical clock + DI | Hardware clock feeds digital input | One DI scan | None | Adds hardware, defeats the purpose of a PLC |
The Time-of-Day interrupt family is built into the SIMATIC operating system and consumes zero OB1 cycle time. The CPU's buffered real-time clock (RTC) keeps the schedule accurate through power cycles as long as the backup battery is healthy (typical life 3-5 years; check BATF LED on the CPU front panel and OB82 diagnostic buffer entries).
2. Prerequisites
Before you begin, verify that your hardware, firmware, and software environment support the planned configuration.
- CPU model and firmware. S7-300 CPU 312/314/315/316/317/318 and S7-400 CPU 412/414/416/417. OB10-OB17 are supported on all S7-300/400 CPUs. For S7-300 CPUs prior to 314C-2 PN/DP with firmware V2.0, only OB10 is fully available; check the S7-300 CPU 31x Manual entry page for your specific order number.
- STEP 7 V5.5 SP4 or later (for legacy SIMATIC Manager workflow) or TIA Portal V13 SP1+ for the unified workflow. This article uses the SIMATIC Manager workflow; the TIA Portal equivalent steps are noted at the end.
- Programmed S7 project with the station already configured and downloadable.
- Date and time set correctly on the CPU (or set automatically via NTP/SNTP). Verify with PLC > Set Time of Day in SIMATIC Manager or read online via PLC > Diagnostic > Module Information > Time.
- Functionally safe access to the lighting contactor output module. A typical 6 AM/6 PM lighting contactor is wired to a 24 V DC DO module (e.g. 6ES7322-1BF01-0AA0 SM322) or to a relay output (6ES7322-1HF01-0AA0). Verify the coil voltage and inrush current of the contactor before sizing the DO.
- Available priority class for OB10/OB11. Default priority is class 2; confirm no higher-priority OB is already using this slot (OB35 cycle interrupt is the most common conflict).
3. Architecture Overview
The signal flow for a typical plant-lighting circuit controlled by an S7-300 is shown in the topology below. The PLC outputs a 24 V DC signal to an interposing relay or contactor coil, which in turn switches the AC lighting load. The PLC never sees the AC mains; isolation is mandatory.
4. Time-of-Day OB Family Reference
The S7-300/400 operating system provides eight Time-of-Day interrupt OBs. You can configure each one independently with a start date, a start time, and an execution period.
| OB | Default Priority | Default Assignment | Reconfigurable | Notes |
|---|---|---|---|---|
| OB10 | 2 | Time-of-Day | Yes | Most common choice for daily scheduling |
| OB11 | 2 | Time-of-Day | Yes | Second daily event (e.g. 6 AM / 6 PM pair) |
| OB12-OB17 | 2 | Time-of-Day | Yes | Reserved by user for additional daily/weekly events |
Key operating-system behavior to keep in mind:
- Configuration source. The OB's start date/time and period are stored in the CPU's system data (SDB). The configuration is downloaded as part of the hardware configuration, separate from the program blocks.
- Period options. Once (single shot), Every minute (rare), Every hour, Every day, Every week, Every month, End of month. The lighting application uses Every day.
-
Runtime modification. SFC28
SET_TINTwrites a new start date/time and period at runtime; SFC29CAN_TINTcancels a pending Time-of-Day interrupt; SFC30ACT_TINTre-arms a cancelled interrupt; SFC31QRY_TINTqueries its status. See the STEP 7 System Software manual for parameter details. -
Time format. The DT (date-and-time) data type is 8 bytes: BCD-encoded year (1990-2089), month, day, hour, minute, second, milliseconds-high nibble, and day-of-week (1=Sun). SFC1
READ_CLKreturns the current DT.
5. Step-by-Step Configuration in HW Config (SIMATIC Manager)
This is the primary configuration path for the classic S7-300/400 workflow. The same parameters must also exist in the STEP 7 program on the engineering station.
5.1 Open the CPU properties
- Open SIMATIC Manager and load your project (
.s7por.s7l). - Open the HW Config editor (double-click Hardware in the project tree, or right-click the station and select Open Object).
- Double-click the CPU symbol in the rack (slot 2 for S7-300, slot 3 for S7-400). The CPU Properties dialog opens.
5.2 Enable and parameterize OB10 (lights OFF at 06:00)
- In the left tree, select Time-of-Day Interrupts.
- The list shows OB10 through OB17. Tick the OB10 checkbox to Activate it.
- Set Start date to a date after the planned download (e.g. tomorrow). The operating system will not trigger the OB at a date in the past; if you set the start date in the past, the OB fires immediately on next STOP→RUN.
- Set Time to
06:00:00. - Set Execution to Every day.
- Leave the priority at the default class 2 unless you have a known conflict.
5.3 Parameterize OB11 (lights ON at 18:00)
- Tick the OB11 checkbox.
- Start date: same logic as OB10 (a future date).
- Time:
18:00:00. - Execution: Every day.
5.4 Save and compile the hardware configuration
- Click OK to close the CPU Properties dialog.
- From the menu, select Station > Save and Compile (or Ctrl+S). The compiler generates the SDBs and places them under Blocks > System Data.
6. Programming the OB Blocks in LAD/FBD/ST
6.1 Insert the OBs into the project
- In SIMATIC Manager, right-click Blocks in the S7 Program node.
- Select Insert New Object > Organization Block.
- Choose OB10, click OK. The OB opens in the LAD/FBD/ST editor.
- Repeat for OB11.
6.2 OB10 — Lights OFF at 06:00
The simplest implementation resets the lighting output. In LAD (Ladder Diagram):
// OB10 — Daily 06:00 event
NETWORK 1
TITLE = LIGHTS OFF
A M 0.0 // optional: hand-OFF-auto interlock
AN I 0.0 // emergency pushbutton (NC contact)
= Q 4.0 // lighting contactor command
R M 10.0 // status flag "lights commanded ON"
In Structured Text (SCL):
// OB10 — Daily 06:00 event
IF NOT "E_Stop" AND "Auto_Mode" THEN
"Light_Cmd" := FALSE; // Q4.0 = 0 → contactor drops out
"Light_On_Flag" := FALSE;
END_IF;
6.3 OB11 — Lights ON at 18:00
// OB11 — Daily 18:00 event
NETWORK 1
TITLE = LIGHTS ON
A M 0.0 // hand-OFF-auto in AUTO
AN I 0.0 // emergency pushbutton (NC contact)
AN M 11.0 // maintenance override (optional HOA switch)
= Q 4.0 // lighting contactor command
S M 10.0 // status flag "lights commanded ON"
The set/reset pair using a M (merker) flag gives you a one-bit memory of last commanded state and is useful for HMI faceplate indicators and for diagnostics on a power-cycle event.
6.4 (Optional) Day-of-week filter in OB1
If you want a different schedule for weekends (for example, lights OFF on Saturday/Sunday between 06:00 and 18:00), use SFC1 to read the date/time in OB1 and store the day-of-week into a byte, then add an interlock in OB11:
// OB1 — every scan
CALL SFC 1
RET_VAL := MW100 // returns DT in 8 bytes at MW100
CDT := DB1.DBD0 // target DT buffer (must be 8 bytes)
The day-of-week byte (the highest nibble of byte 7 of the DT) gives 1=Sun, 2=Mon, ..., 7=Sat. Use a BCD-to-int conversion to branch on it.
7. Runtime Modification with SFC28-SFC31
Hard-coded start times in HW Config are fine for fixed schedules. For a scheduler that needs to be changed from HMI (for example, a building manager pushes the lights-ON time from 18:00 to 19:00), use the Time-of-Day interrupt SFCs. The full SFC family is documented in the STEP 7 System and Standard Functions reference manual.
| SFC | Name | Function | Key Parameters |
|---|---|---|---|
| SFC28 | SET_TINT | Set start date/time + period for OB10-OB17 | OB_NR, SDT (Date_And_Time), PERIOD, RET_VAL |
| SFC29 | CAN_TINT | Cancel a Time-of-Day interrupt | OB_NR, RET_VAL |
| SFC30 | ACT_TINT | Re-arm a cancelled Time-of-Day interrupt | OB_NR, RET_VAL |
| SFC31 | QRY_TINT | Query status of a Time-of-Day interrupt | OB_NR, RET_VAL, STATUS |
Example: change the lights-ON time to 19:00 from an HMI tag:
// Called from OB1, edge-triggered on M50.0 (HMI command "Apply new schedule")
A M 50.0
FP M 50.1
JCN END
CALL SFC 28
OB_NR := 11
SDT := DB100.DBX0.0 BYTE 8 // DT built by HMI date/time picker
PERIOD := W#16#0001 // 0001 = every day
RET_VAL := MW200
END: NOP 0
The PERIOD parameter is a 16-bit WORD where the lowest 2 bits encode the period: W#16#0000=once, W#16#0001=every minute, W#16#0002=every hour, W#16#0003=every day, W#16#0004=every week, W#16#0005=every month, W#16#0006=end of month. (Refer to the official SFC reference for the full mapping.)
8. Verification and Commissioning
Download and test the configuration in this order to avoid the "CPU goes to STOP" trap.
- Online test before download. In SIMATIC Manager, select PLC > Accessible Nodes and confirm the CPU is reachable (PROFIBUS or PROFINET green LED, link LED on PG/PC interface).
- Set the time of day. PLC > Set Time of Day. The dialog shows CPU local time. Make sure the time zone is correct; many S7-300/400 projects use UTC internally and convert to local at the HMI layer.
- Download HW Config first. Mark the S7 station, then PLC > Download. The SDBs are now on the CPU; OB10 and OB11 are now configured but not yet programmed. The CPU will not call them until the OB blocks exist.
- Download the program blocks second. Right-click the Blocks folder, Download. The OB10 and OB11 source code is now in the CPU's load memory and work memory.
- Force the test trigger. To validate immediately without waiting for 06:00 or 18:00, open PLC > Diagnostic > Module Information > Time and either (a) set the start time to 1 minute in the future, or (b) call SFC28 from the variable table with a near-future SDT. Verify the output Q4.0 changes state and the contactor pulls in or drops out.
-
Reset to the production schedule. Re-parameterize OB10 to
06:00:00and OB11 to18:00:00, download HW Config again. - Monitor the diagnostic buffer. PLC > Diagnostic > Diagnostic Buffer. Each Time-of-Day event writes a "OB10 / OB11 entry / exit" event with timestamp. The buffer is the authoritative source if there is a dispute about whether the OB fired.
9. Troubleshooting Matrix
| Symptom | Likely Root Cause | Diagnostic Step | Remediation |
|---|---|---|---|
| CPU goes to STOP at first scheduled time | OB10/OB11 not loaded as program block; only configured in SDB | PLC > Diagnostic > Diagnostic Buffer → OB85 "OB not loaded" | Insert OB10/OB11 in the Blocks folder, download, perform STOP→RUN |
| OB fires once, then never again | Execution set to Once instead of Every day | Open CPU properties, check Execution field | Change to Every day, save, recompile, download HW Config |
| OB fires at the wrong time | CPU clock not set; project uses UTC but CPU is on local | Compare Module Information > Time with PG/PC clock | Use PLC > Set Time of Day; or set the time zone in HW Config > Diagnostics/Clock |
| OB does not fire at all | Time-of-Day interrupt disabled in HW Config; checkbox unticked | CPU properties > Time-of-Day Interrupts | Tick the activation box, save, recompile, download |
| OB fires correctly but the load does not switch | Output module channel fault, DO fuse blown, contactor coil wiring | Force Q4.0 in VAT; measure voltage at DO terminals | Replace fuse, check wiring, verify load |
| Time drifts by minutes per week | Battery low / removed; CPU running on capacitor backup only | Check BATF LED; diagnostic buffer battery warning |
Replace lithium backup battery (e.g. 6ES7971-0BA00 for most S7-300 CPUs) |
| SFC28 returns error 0x8090 | OB_NR is not a Time-of-Day OB | Verify OB_NR is 10-17 | Correct OB_NR and retry |
| SFC28 returns error 0x80A1 | Period parameter out of range | Inspect PERIOD WORD | Use the documented W#16#000x encodings |
10. Common Field Pitfalls and Best Practices
- Always co-download HW Config and program. An inconsistent state (SDB enabled, OB block missing) is the single most common reason for a Time-of-Day-related CPU STOP. Make this a documented step in your commissioning checklist.
- Keep OB priority at class 2 unless you have a reason. OB35 (cyclic interrupt) and OB82 (diagnostic) typically run at higher priority. Raising OB10/OB11 above them can starve diagnostic reporting.
-
Use a status flag, not the output directly. Reading
Q4.0after the OB writes it is fine, but for HMI faceplate and for diagnostic log, mirror the command into aMorDBflag. This survives a contactor-failure diagnostic alarm that may forceQ4.0=0 from a safety block. - Plan for DST. S7-300/400 do not auto-adjust for daylight savings. The recommended approach is to enable the Time synchronization slave mode and use an external NTP source via the CP (e.g. CP343-1 or CP443-1) — STEP 7's Time-of-Day synchronization under CPU properties > Diagnostics/Clock.
- Document the schedule in the program header. Add a comment block in OB10/OB11 with the scheduled time and the period so that a future engineer scanning the program with Reference Data > Cross-References understands the intent.
- Test the recovery path. During commissioning, deliberately delete OB10 from the CPU with the SDB still active, watch the CPU go to STOP on the next trigger time, then re-insert the OB and confirm STOP→RUN. This is the test that proves the engineer understands the failure mode.
- Use SFC1 (READ_CLK) only for window logic. If the requirement is "lights ON if it's between 18:00 and 06:00", OB10/OB11 edge events are the cleanest implementation. Polling with SFC1 in OB1 is acceptable for window logic that needs more than just two edges per day.
11. TIA Portal Equivalent (Quick Reference)
For projects being maintained in TIA Portal, the same OBs are used and the same SFCs apply. The path is:
- Project tree > Devices > [CPU] > Device configuration
- Select the CPU in the graphical view.
- In the Properties pane (Inspector window), choose Time of day interrupts.
- Add a new entry for OB10 and OB11, set start time and execution period, then compile and download.
- Add the OB10 and OB11 blocks via Program blocks > Add new block > Organization block.
- Use the same SFC28-SFC31 calls; TIA Portal's SFC block library is identical.
12. Frequently Asked Questions
What is the difference between OB10 and OB35 on an S7-300?
OB10 is a Time-of-Day interrupt that fires once at a configured date and time, optionally repeating (every minute/hour/day/week/month). OB35 is a cyclic interrupt that fires at a fixed scan period (default 100 ms) regardless of the wall-clock time. Use OB10 for absolute-time scheduling such as 6 AM / 6 PM, and OB35 for periodic tasks such as a 100 ms PID loop.
Why does my S7-300 CPU go to STOP the first time the scheduled time arrives?
The most common cause is that the OB10 or OB11 block was never inserted and downloaded as a program block. The CPU's SDB configured the trigger, but when it fires the operating system cannot find the corresponding OB and raises OB85, which transitions the CPU to STOP. Insert the OB block under Blocks, download it, and perform a STOP→RUN.
Can I change the scheduled time from the HMI without re-downloading HW Config?
Yes. Use SFC28 SET_TINT with a new DT value supplied from the HMI (for example, through a date/time picker faceplate). SFC29 CAN_TINT cancels a pending trigger, and SFC30 ACT_TINT re-arms it. The SDBs in HW Config set the initial schedule; SFC28 overrides it at runtime.
How do I make a "lights ON between 18:00 and 06:00" schedule, not just two edges?
You do not need a window — you only need the two edges at 18:00 (ON) and 06:00 (OFF) because the state is latched in the PLC's memory and the contactor stays in its last commanded position. If the PLC is power-cycled at 02:00, however, the output defaults to 0, so the lights would be off until 06:00. To restore state, use SFC1 READ_CLK in OB100 (warm restart) to set the initial output based on the current time of day.
How many Time-of-Day events can I configure on one CPU?
S7-300 supports OB10 through OB17 (8 events). S7-400 also supports OB10-OB17 (8 events), but it can be extended via additional OB blocks for some CPUs. For most facility-lighting applications two events (ON and OFF) are sufficient.
What happens to the schedule if the CPU battery dies?
The buffered real-time clock loses its time. After a power cycle the CPU boots with the clock at 00:00 on 01.01.1990. The Time-of-Day OB will not fire until the clock is set or the SDB's start date is in the past (in which case it fires immediately on the next STOP→RUN). Replace the lithium backup battery and re-set the time, or configure NTP synchronization through a CP module to avoid this failure mode.
Can I use SFC1 to do the whole job without OB10-OB17?
Yes. In OB1, call SFC1 READ_CLK, compare the returned DT to a stored schedule, and set the lighting output. The trade-off is scan-time load and a one-OB1-cycle timing jitter. For a simple two-event-per-day application, the OB10-OB17 approach is cleaner and consumes no OB1 time.