Overview: From IEC 61131 Tasks to Siemens OBs
The IEC 61131-3 standard defines a task as the binding between program organization units and their execution trigger. Triggers fall into three broad classes: cyclic (period-driven), event-driven (hardware interrupts, alarms), and system-driven (startup, fault). On Siemens S7-300, S7-400, S7-1200, and S7-1500 controllers, this concept is implemented as the Organization Block (OB). Each OB is the entry point invoked by the CPU's operating system when a specific event occurs.
OBs differ from FCs, FBs, and DBs in one critical way: they are not called from user code. Instead, the firmware dispatches them when the configured trigger condition fires. When the OB finishes, control returns to the dispatcher. Multiple OBs may be active concurrently at different priority levels, and a higher-priority OB may preempt the currently running OB, which is then resumed at the point of interruption once the higher-priority work completes.
OB Priority Model and Preemption
Every OB carries a fixed or configurable priority class that determines preemption behavior. When two OBs are eligible to run, the one with the higher priority class executes first. The currently running OB is interrupted only by OBs of strictly higher priority; equal-priority OBs are queued.
| Priority Class | Typical OBs | Default Class |
|---|---|---|
| 1 | OB1 (main cyclic) | Free cycle |
| 2 to 24 | OB10 to OB17 (time-of-day), OB20 to OB23 (delay), OB30 to OB38 (cyclic interrupt) | Configurable |
| 25 / 26 | OB121, OB122 (programming / I/O access errors) | Same priority as the OB that caused the fault |
| 27 | OB80 (cycle time overrun) | Fixed |
| 28 | OB82 (diagnostic interrupt) | Fixed |
| 25 to 26 / 27 to 28 | OB121/OB122 / OB80/OB82 | Inherited or fixed |
The full mapping of OB number to priority is documented in the Siemens S7-1500 / ET 200MP System Manual and the STEP 7 programming guideline.
OB1: The Main Cyclic Program
OB1 is the default cyclic entry point. After the firmware updates the process image (inputs read from modules, outputs written from the previous cycle), OB1 is dispatched. On completion, the output process image is flushed to the physical outputs and the cycle restarts.
Cycle time depends on:
- Number and execution time of instructions executed in OB1 (and in any lower-priority OBs that ran since the last cycle).
- Communication load (PN/Profibus acyclic services, HMI polling, S7 communication).
- Operating system overhead (process image update, self-diagnostics).
- Interrupt activity from higher-priority OBs.
Because the OB1 cycle is non-deterministic in duration (commonly 10-20 ms on a moderately loaded CPU, but variable by tens of milliseconds under load), it is the wrong place for time-sensitive algorithms.
OB1 Start Information
The 20 bytes of OB1 start info contain the system time at cycle start, the cycle counter, and the elapsed time since the last warm restart. The relevant temporary tags are accessible by symbolic name in TIA Portal once the OB is inserted:
| Tag | Type | Meaning |
|---|---|---|
| OB1_EV_CLASS | BYTE | Event class (always B#16#11 for OB1) |
| OB1_STRT_INFO | BYTE | Startup information |
| OB1_PRIORITY | BYTE | Priority class (default 1) |
| OB1_OB_NUMBR | BYTE | OB number (1) |
| OB1_RESERVED_1 | BYTE | Reserved |
| OB1_RESERVED_2 | BYTE | Reserved |
| OB1_PREV_CYCLE | TIME | Previous cycle execution time |
| OB1_MIN_CYCLE | TIME | Minimum cycle time since last restart |
| OB1_MAX_CYCLE | TIME | Maximum cycle time since last restart |
| OB1_DATE_TIME | DATE_AND_TIME | OB dispatch timestamp |
Reading OB1_PREV_CYCLE from inside OB1 is the only reliable way to obtain the actual cycle time on older S7-300/400 CPUs. On S7-1500, the equivalent is exposed through the RUNTIME instruction in the extended instructions library.
OB35: Cyclic Interrupt for Periodic Execution
The cyclic interrupt OBs (OB30 to OB38 on S7-300/400, OB30-OB38 on S7-1500 with different availability per CPU) are dispatched on a fixed period regardless of OB1's progress. The period is configured in the OB's properties:
| OB | Default Period (S7-300/400) | Use Case |
|---|---|---|
| OB30 | 5 s | Slow processes (e.g., tank level averaging) |
| OB32 | 1 s | Slow control loops |
| OB33 | 500 ms | Temperature regulation |
| OB34 | 200 ms | Generic fast control |
| OB35 | 100 ms | Default PID loop (most common) |
| OB36 | 50 ms | Fast motion / hydraulic |
| OB37 | 20 ms | High-speed control |
| OB38 | 10 ms | Reserved / special applications |
On S7-1200 and S7-1500, only OB30 (configurable 1 ms - 60 s) is available. The hardware-specific limits are listed in the respective S7-1500 system manual.
Configuration steps in TIA Portal V12:
- Project tree → Program blocks → Add new block → Organization block → select Cyclic interrupt.
- Choose the OB number (OB35 is the de-facto default for PID).
- Open the new block's Properties. Under General > Cycle time, enter the period in milliseconds.
- Under General > Phase offset, enter an offset in milliseconds to stagger multiple cyclic OBs so they do not fire simultaneously.
- Confirm priority class is at least 8 if the cyclic work must preempt OB1.
When OB35 fires, OB1 (if currently running) is suspended. OB35 runs to completion, then OB1 resumes at the exact instruction that was interrupted. Because the dispatch is time-driven, the elapsed time between two consecutive OB35 calls equals the configured period plus any jitter caused by higher-priority OBs (such as OB82 on a Profibus fault).
OB8x: Error and Diagnostic OBs
OB80 to OB87 fire when the firmware detects a specific class of error. Each OB carries start info that pinpoints the fault source. Programming these OBs prevents the CPU from going to STOP on a recoverable fault.
| OB | Trigger Event | Default Priority |
|---|---|---|
| OB80 | Cycle time exceeded (OB1 ran longer than the configured maximum) | 26 |
| OB81 | Battery fault / power supply fault (legacy S7-300/400) | 26 (configurable 2-24) |
| OB82 | Diagnostic interrupt (module channel fault, wire break, overflow) | 26 (configurable 2-24) |
| OB83 | Module plug / pull during RUN | 26 (configurable 2-24) |
| OB84 | CPU hardware fault | 26 (configurable 2-24) |
| OB85 | Process image update error (module missing or faulty) | 26 (configurable 2-24) |
| OB86 | Profibus / Profinet slave failure | 26 (configurable 2-24) |
| OB87 | Communication error (incorrect frame, ID conflict) | 26 (configurable 2-24) |
Programming Pattern for OB82 (Wire Break)
The simplest application is suppressing an alarm and writing a status word for the HMI:
// SCL in OB82 (S7-1500)
#iOB82_Module_Fault := OB82_MDL_STATE; // 1 = fault present
#iOB82_Channel := OB82_CHANNEL; // affected channel (DWORD bit field)
#iOB82_IO_Type := OB82_IO_FLAG; // 0 = input, 1 = output
#iOB82_Event := OB82_FLT_ID; // fault identifier per system manual
// Push a structured entry to a global DB so the HMI can render it
"dbDiagnostics".fault_active := TRUE;
"dbDiagnostics".module_address := OB82_MDL_ADDR;
"dbDiagnostics".event_id := OB82_FLT_ID;
"dbDiagnostics".last_event_time := OB82_TIMESTAMP;
If OB82 is not programmed, the CPU enters STOP the moment a diagnostic interrupt is raised.
OB100 to OB102: Startup OBs
Startup OBs run once after power-up or after a STOP-to-RUN transition, before OB1 begins cycling. They are mutually exclusive: only one of OB100 (warm restart), OB101 (hot restart, S7-400 only), and OB102 (cold restart) runs per start, depending on the CPU mode selected and the type of restart.
Typical use cases:
- Initializing non-retentive tags that the firmware does not zero automatically.
- Pre-loading recipe data.
- Synchronizing the system clock via
WR_SYS_Tafter NTP failure. - Triggering a one-shot handshake to peripheral stations on Profinet.
OB90: Background OB
OB90 is dispatched only when OB1 finishes in less than the configured minimum scan time. It is used for low-priority housekeeping tasks that should never delay the main cycle. Because OB90 may not run for seconds at a time on a fully loaded CPU, it is reserved for diagnostics, statistics accumulation, and watchdog refresh, not control.
OB90's priority class is 29 (the lowest) on legacy S7-400. On S7-1500, OB90 is supported only with the relevant firmware option enabled.
PID Control in OB35
The PID compact block (PID_Compact on S7-1200/1500, FB41 CONT_C on S7-300/400) is implemented as a discrete-time algorithm. Internally it integrates the error term using the trapezoidal rule and differentiates it with the backward-difference approximation. These calculations only produce the correct transfer function if the algorithm is called at a fixed interval and that interval is passed in as CycleTime.
Why OB1 Is Wrong for PID
OB1's cycle time is a moving target: 12 ms at idle, 27 ms when Profibus acyclic traffic surges, 18 ms when the HMI polls hard. If you call the PID in OB1, the integrator's discrete time step Ts fluctuates. The block's anti-windup, bumpless transfer, and derivative filter all assume a constant Ts. Result: overshoot under load, sluggish response at idle, and tuning parameters (Kp, Ti, Td) that behave differently from bench calculations.
If you must call the PID in OB1 (because the cyclic interrupt is already committed to another task), feed the actual measured cycle time:
// SCL, inside OB1
"fbPID".CycleTime := OB1_PREV_CYCLE / 1000.0; // seconds
"fbPID"();
This still does not match the behavior of a fixed-period controller, but it removes the worst-case error when the cycle stretches.
Correct PID Wiring in OB35
- Add OB35 to the project with a period that matches the process. 200 ms is a common starting point for thermal loops; 100 ms for pressure; 50 ms for hydraulic positioning.
- Instantiate PID_Compact (or FB41 / FB58) in OB35.
- Wire Input_PER or Input from the analog input channel.
- Wire Setpoint from the HMI or a fixed value.
- Leave CycleTime at its default; PID_Compact reads the calling OB's configured period automatically on S7-1500 (Input Retain.CycleTime.Source = OB35).
- Wire Output_PER or Output to the analog output channel.
Sample Time Versus Process Bandwidth
A rule of thumb: choose the cycle such that Ts < Td / 10, where Td is the dominant time constant of the plant. Sampling a furnace at 20 ms when its thermal time constant is 4 minutes (240,000 ms) wastes CPU time and provides no control benefit. Sample at 200 ms or 500 ms instead.
Unprogrammed OB Behavior and STOP Conditions
The general rule on every S7-300/400/1200/1500 firmware is:
- If the event fires and the matching OB does not exist, the firmware raises a second, higher-priority error event.
- If that second OB is also missing, the CPU transitions to STOP and the diagnostic buffer logs the unrecoverable fault.
For programming errors (e.g., dividing by zero, accessing a DB that is not loaded, writing outside an array bounds), the firmware calls OB121. For I/O access errors (e.g., reading a missing Profinet slot), the firmware calls OB122. These two OBs inherit the priority of the OB that caused the fault, which keeps the diagnostic information consistent with the call stack.
Troubleshooting Matrix
| Symptom | Likely Missing OB | Resolution |
|---|---|---|
| CPU in STOP, diagnostic buffer reports "OB not loaded" | OB matching the raised event | Add the OB, download, RUN |
| Wire-break error on AI8 module, CPU stays RUN | OB82 present | Verify OB82_MDL_STATE in DB to confirm |
| Profibus slave disappears, CPU in STOP | OB86 missing | Add OB86, program a fault flag, download |
| OB1 cycle overruns, CPU in STOP | OB80 missing | Add OB80, increase OB1 max cycle time in CPU properties, or split work into OB35 |
| PID output oscillates wildly when HMI is online | PID called in OB1 instead of cyclic OB | Move PID instance to OB35 |
| PID I-term never resets after a setpoint step | Cycle time passed as constant 0 | Wire CycleTime to OB35 period or to OB1_PREV_CYCLE |
| OB35 fires late by tens of ms | Higher-priority OB preemption | Raise OB35 priority class, or reduce work in OB82/OB86 |
OB Start Information in TIA Portal
In TIA Portal V12 and later, the OB's start info appears automatically in the block's interface under Temp with names matching the symbols documented in the manual. To read them in SCL:
// Inside OB35
#sCycleTime_ms := DWORD_TO_REAL(OB35_CYCLIC_TIME); // not available on all CPUs
#sCycleCount := OB35_PHASE_OFFSET;
The exact start info layout differs by OB number. The S7-1500 system manual, chapter on organization blocks contains the complete table.
Programming Recommendations
- Reserve OB35 for PID and other periodic control. Never mix one-shot recipes with a high-frequency PID inside the same cyclic interrupt.
- Program OB80, OB82, OB86, OB121, and OB122 on every project. Even a 5-line block that simply sets a flag and writes to the diagnostic buffer prevents random STOP transitions on field wiring faults.
- Keep OB1 lean. Logic that does not need sub-50 ms response belongs in OB1; logic that does needs OB30-OB38.
- Use phase offset to spread multiple cyclic OBs across the cycle.
- Match PID cycle to process. Sample thermal loops at 200-500 ms; sample hydraulic valves at 10-20 ms.
- Never rely on OB90 for time-critical work. Treat it as a low-priority drain.
- For S7-200 migration: the S7-200 has no OBs. Analog scaling and PID live directly in the main scan. Migration to S7-1200/1500 means designing an OB35 around the old scan period, otherwise tuning parameters from the S7-200 will not transfer.
Documentation and Reference Material
- S7-1500 / ET 200MP System Manual — OB priority classes, start info, and startup behavior.
- STEP 7 Professional V18 Programming Guideline — Best-practice OB usage.
- S7-1200 Programmable Controller System Manual — OB30 on S7-1200 and its period limits.
- PID_Compact V2 Function Manual — Cycle time handling and tuning.
- IEC 61131-3:2013, clause 4.7 — Task definition.
What happens if I call PID_Compact inside OB1 instead of OB35?
The PID will function, but its integrator and derivative use a non-constant sample time. Tuning parameters (Kp, Ti, Td) will not match bench calculations and the loop will overshoot under load and oscillate at idle. Move the instance to OB35 and ensure CycleTime matches the OB period.
Why does my CPU go to STOP when a Profinet slave drops out?
OB86 handles rack / station failure. If OB86 is not loaded, the firmware cannot pass the event to user code and the CPU transitions to STOP. Add OB86 and program a fault flag, then download to the device.
How do I find the current OB1 cycle time inside the program?
Read the temporary tag OB1_PREV_CYCLE on S7-300/400, or call the RUNTIME instruction on S7-1500. Both return the elapsed time of the previous OB1 cycle in TIME format.
Can I use OB30 through OB38 on S7-1500 like on S7-300?
Only OB30 is supported on S7-1200 and S7-1500, with a configurable period of 1 ms to 60 s. The other OB numbers (OB31-OB38) are not present in the firmware image.
What is the difference between OB121 and OB122?
OB121 handles programming errors detected while user code executes (division by zero, illegal DB number, range violations). OB122 handles I/O access errors (reading from a missing module or a Profinet slot that is not assigned). Both inherit the priority of the OB that triggered them; if either is missing, the CPU enters STOP.