Configuring S7-300 OB10-OB17 Time-of-Day Interrupts for Lighting

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

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.

Scope: This document targets the classic STEP 7 V5.x environment (SIMATIC Manager, HW Config) used with S7-300 (CPU 31x) and S7-400 (CPU 41x/416). TIA Portal uses the same OB numbers and the same SFCs (SFC28-SFC31) but the configuration path is under Device Configuration > Properties > Time-of-Day Interrupts. CPU firmware V2.x and newer is assumed.

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.

  1. 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.
  2. 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.
  3. Programmed S7 project with the station already configured and downloadable.
  4. 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.
  5. 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.
  6. 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).
Safety caveat. If the lighting feeds egress paths, ensure the design complies with local code (e.g. NEC 700 in the US, IEC 60364-5-56) and that the PLC is not the sole means of emergency lighting control. A hardware bypass contactor or fireman's switch must remain functional independent of the PLC.

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.

S7-300 CPU OB10 (06:00 daily) OB11 (18:00 daily) Q4.0 → OFF Q4.0 → ON SM322 DO 8x24V 6ES7322-1BF01 Channel 0 = Q4.0 Relay K1 24V DC coil 10A/250VAC Lights L1 L2 L3 ... Plant mains → branch CB → contactor K1 → lighting load Coil: 24VDC from SM322; contacts: AC3 duty 10A, 400V Hand-OFF-Auto selector bypasses PLC in maintenance

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_TINT writes a new start date/time and period at runtime; SFC29 CAN_TINT cancels a pending Time-of-Day interrupt; SFC30 ACT_TINT re-arms a cancelled interrupt; SFC31 QRY_TINT queries 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_CLK returns 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

  1. Open SIMATIC Manager and load your project (.s7p or .s7l).
  2. Open the HW Config editor (double-click Hardware in the project tree, or right-click the station and select Open Object).
  3. 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)

  1. In the left tree, select Time-of-Day Interrupts.
  2. The list shows OB10 through OB17. Tick the OB10 checkbox to Activate it.
  3. 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.
  4. Set Time to 06:00:00.
  5. Set Execution to Every day.
  6. Leave the priority at the default class 2 unless you have a known conflict.

5.3 Parameterize OB11 (lights ON at 18:00)

  1. Tick the OB11 checkbox.
  2. Start date: same logic as OB10 (a future date).
  3. Time: 18:00:00.
  4. Execution: Every day.

5.4 Save and compile the hardware configuration

  1. Click OK to close the CPU Properties dialog.
  2. From the menu, select Station > Save and Compile (or Ctrl+S). The compiler generates the SDBs and places them under Blocks > System Data.
Critical sequence: The hardware configuration (with the SDBs) must be downloaded before the OB10/OB11 program blocks are inserted. If the CPU encounters a Time-of-Day trigger with the OB block missing, it raises OB85 (organizational-block-not-loaded error) and may transition to STOP. See section 8 for the recovery procedure.

6. Programming the OB Blocks in LAD/FBD/ST

6.1 Insert the OBs into the project

  1. In SIMATIC Manager, right-click Blocks in the S7 Program node.
  2. Select Insert New Object > Organization Block.
  3. Choose OB10, click OK. The OB opens in the LAD/FBD/ST editor.
  4. 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.

  1. 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).
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. Reset to the production schedule. Re-parameterize OB10 to 06:00:00 and OB11 to 18:00:00, download HW Config again.
  7. 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.
Test caveat: The diagnostic buffer's time stamps are in CPU time (usually local time). Cross-check against the engineering station's clock. A 1-hour discrepancy typically indicates daylight-savings time was not handled in the project.

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

  1. 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.
  2. 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.
  3. Use a status flag, not the output directly. Reading Q4.0 after the OB writes it is fine, but for HMI faceplate and for diagnostic log, mirror the command into a M or DB flag. This survives a contactor-failure diagnostic alarm that may force Q4.0=0 from a safety block.
  4. 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.
  5. 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.
  6. 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.
  7. 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:

  1. Project tree > Devices > [CPU] > Device configuration
  2. Select the CPU in the graphical view.
  3. In the Properties pane (Inspector window), choose Time of day interrupts.
  4. Add a new entry for OB10 and OB11, set start time and execution period, then compile and download.
  5. Add the OB10 and OB11 blocks via Program blocks > Add new block > Organization block.
  6. 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.

Back to blog