Problem Description
An S7-1217C DC/DC/DC (6ES7217-1AG40-0XB0) running TIA Portal V16 exhibits a persistently energized output Q0.0 immediately after download. The project contains a single OB30 cyclic interrupt with a configured phase of 2000 ms. Inside OB30, network 1 is a normally-open contact driven by constant TRUE, terminated on coil Q0.0:
// OB30 - Cyclic Interrupt (phase = 2000 ms)
------| |-----------------( )
TRUE Q0.0
Expected behavior: a 2-second blink (or any alternating pattern). Observed behavior: Q0.0 latches high immediately after RUN and never returns low. The diagnostic buffer shows no errors. PLCSIM produces the same latched output. The fault is reproducible on every download.
The fault is not OB30, not the phase, not the firmware, and not TIA Portal V16. The fault is the rung logic combined with how the S7-1200 process image output (PIQ) retains its last written value. This article dissects the root cause, contrasts S7-1200 and S7-1500 cyclic interrupt behavior, and provides four ladder logic / SCL patterns that produce a true 1 Hz / 50% duty blink on Q0.0 from OB30.
Root Cause: Process Image Output Latching
The S7-1200 stores output values in a process image output (PIQ) area in system memory. The PIQ is a 4 KB (CPU 1217) bit-addressable region where each bit retains its last written value until something writes a new value to it. When OB30 evaluates the rung --| |--( ) Q0.0 with constant TRUE on the contact, the bit Q0.0 in the PIQ is set to 1. The bit then stays at 1 for the entire 2000 ms gap until the next OB30 execution. On the next execution, the rung is energized again, the bit is set to 1 again (it was already 1, so the visible state does not change), and the cycle repeats.
A coil in a ladder diagram does not pulse the physical output. The rung evaluates in microseconds; the bit is written to the PIQ; the CPU transfers the PIQ to the digital output module at the end of the OB cycle. The output bit stays latched in the PIQ for the inter-OB interval because the CPU never writes FALSE back to it. This is correct S7-1200 behavior — it is documented in the S7-1200 system manual and the TIA Portal help, and applies equally to S7-1500.
The NC-contact trick --|/| Q0.0 --( ) Q0.0 often suggested on forums does not toggle either on the S7-1200, because once Q0.0 = TRUE the NC contact opens and the rung never re-energizes. The PIQ retains TRUE indefinitely. To actually toggle, the program must contain explicit state that changes between executions — a flip-flop, a counter, or an XOR pattern.
Process Image Architecture on S7-1200
Every S7-1200 CPU maintains two process image regions:
- PII (Process Image Inputs) — a snapshot of physical input states copied at the start of OB1 and refreshed at the start of each cyclic / hardware interrupt OB. Reading
%I0.0returns the PII bit, not the live wire state. - PIQ (Process Image Outputs) — a holding buffer for output states. Writing to
%Q0.0updates the PIQ bit. The PIQ is transferred to the physical output modules at the end of the OB cycle that wrote it.
For CPU 1217, the default PII size is 1024 bytes and the default PIQ size is 1024 bytes. You can shrink these in the device configuration under Properties > I/O addresses. Bits outside the configured PII/PIQ size are not auto-refreshed and behave like direct I/O — they read the live state on read, write immediately on write, but bypass the PIQ retention model.
| Address type | Read behavior | Write behavior |
|---|---|---|
%I0.0 (in PI) |
Returns PII bit set at OB start | Not writable |
%I0.0:P (direct) |
Returns live wire state | Not writable |
%Q0.0 (in PIQ) |
Returns PIQ bit | Updates PIQ, transfers at OB end |
%Q0.0:P (direct) |
Returns PIQ bit | Writes directly to module immediately |
For a blink pattern that uses PIQ retention (Pattern A-C below), you must write to the PIQ address Q0.0, not the direct address Q0.0:P. Writing directly bypasses retention and you must write TRUE and FALSE explicitly every OB30 tick.
How OB30 Execution Actually Works on S7-1200
OB30 belongs to the cyclic interrupt class of organization blocks. The CPU scheduler maintains a hardware timer (or a software timer driven by a system tick) for each configured cyclic OB. When the timer elapses, the scheduler executes the following sequence:
- The scheduler preempts the currently running OB if that OB is at a lower priority than OB30 (OB30 default priority on S7-1200 is 12).
- If OB30 has the same priority as the OB currently running (e.g. a previous OB30 instance still queued), the new instance is queued. Only one queued instance per priority is allowed.
- The PII is refreshed for I/O points assigned to OB30's process image partition (PIP). If you do not assign a PIP, the default OB1 PIP is used.
- OB30 executes from network 1 to the end. Execution time is logged and added to the cycle-time histogram.
- The PIQ for OB30's PIP is transferred to the output modules.
- Control returns to the interrupted OB (or OB1 if nothing was running).
The effective interval between OB30 firings is therefore:
- Configured phase (2000 ms in the failing example)
- Plus drift from OB30 execution time
- Plus delay if a higher-priority OB is currently running
- Plus delay if OB1 holds the CPU long enough to push OB30 past its scheduled fire time
If OB30 itself takes longer than its configured phase, the next instance is queued. The S7-1200 only queues one late instance per priority. If a second late instance becomes due, the CPU calls OB80 (time error) and, in default behavior without an OB80 handler, transitions to STOP.
OB30 Time Bases and Phase Configuration
The S7-1200 and S7-1500 cyclic interrupt OBs share the same numbering (OB30 to OB38) and the same default phase values. The available OBs and their default phase times on firmware V4.4 and later are:
| OB | Default phase | Minimum phase (S7-1200 FW V4.4+) | Minimum phase (S7-1500) | Increment |
|---|---|---|---|---|
| OB30 | 5 ms | 1 ms | 1 ms | 1 ms |
| OB31 | 2 ms | 1 ms | 1 ms | 1 ms |
| OB32 | 1 ms | 1 ms | 1 ms | 1 ms |
| OB33 | 500 µs | 500 µs | 500 µs | 100 µs |
| OB34 | 200 µs | 200 µs | 200 µs | 100 µs |
| OB35 | 100 µs | 100 µs | 100 µs | 50 µs |
| OB36 | 50 µs | 50 µs | 50 µs | 50 µs |
| OB37 | 20 µs | 20 µs | 20 µs | 10 µs |
| OB38 | 10 µs | 10 µs | 10 µs | 10 µs |
The minimum phase for OB30 through OB32 is firmware-dependent. CPU 1217 (6ES7217-1AG40-0XB0) ships with firmware V4.4 or later; the table above applies. On older firmware (V4.0-V4.3), OB30 minimum is typically 5 ms. Check the firmware version under Online > Accessible devices in TIA Portal V16 before assuming 1 ms resolution.
The maximum phase on every OB30-OB38 is 60000 ms (60 s). For a 2000 ms blink on Q0.0 the choice of OB does not matter — any of OB30-OB38 will accept the phase. Use OB30 because its default 5 ms is closest to the target and least likely to collide with a high-speed task.
S7-1200 vs S7-1500 Cyclic Interrupt Differences
| Feature | S7-1200 (CPU 1217, FW V4.4+) | S7-1500 (e.g. CPU 1515-2 PN) |
|---|---|---|
| Number of cyclic OBs | OB30 to OB38 | OB30 to OB38 |
| Minimum phase | 1 ms (OB30-OB32) | 100 µs (OB35) |
| Maximum phase | 60000 ms | 60000 ms |
| Phase resolution | 1 ms above 1 ms | 1 µs in fast OBs |
| Queued instances per priority | 1 | 1 |
| Phase offset (start delay) | Not supported | Supported (in OB properties) |
| Late-execution handling | Triggers OB80 if overrun repeats | Triggers OB80; later instance discarded |
| Watchdog during OB | Active (configurable) | Active (configurable) |
| Process image partition (PIP) | Supported, OB1 default | Supported, OB1 default |
The S7-1500 lets you set a phase offset so that two cyclic OBs do not collide at startup. On S7-1200, the first OB30 instance is scheduled relative to the most recent CPU restart, and you cannot directly stagger it. The behavior is documented in the Siemens TIA Portal V20 cyclic interrupt OB reference and in the S7-1200 system manual at Siemens support entry 109772940.
Configuring OB30 in TIA Portal V16
- Open the project in TIA Portal V16 (V16 Update 7 or later recommended for CPU 1217 firmware V4.4).
- In the project tree, expand the S7-1217 station and double-click Program blocks.
- Double-click Add new block. Select Organization block, set type to Cyclic interrupt, set number to OB30. Click OK.
- Open the OB30 properties (right-click OB30 > Properties). Under the General section, set Phase (ms) to
2000. Leave Priority at the default (12 on S7-1200 firmware V4.4+). - Compile (Ctrl+B) and download to the CPU. After download, TIA prompts whether to restart the OB — confirm if you want the new phase to take effect immediately.
If you do not see OB30 in the Add new block dialog, your CPU may be on firmware older than V4.0, or your TIA installation may lack the OB30-OB38 support package. Update TIA to V16 Update 7 or later and verify the CPU article number.
Correct Blink Pattern Implementations
Four patterns produce a 1 Hz / 50% duty blink on Q0.0 from a 2000 ms OB30. Choose one based on the rest of your program style.
Pattern A: XOR Toggle in Ladder
// OB30 - 2000 ms phase
// Network 1: toggle Q0.0
Q0.0
------|/|----------+-----( )--
|
Q0.0 |
------| |------------+
Walkthrough: on the first entry, Q0.0 is FALSE (PIQ default). The NC branch conducts, the rung is energized, the coil writes 1 to Q0.0. On the second entry 2000 ms later, Q0.0 is TRUE, the NO branch conducts, the rung is energized, the coil writes 1 again — the bit stays at 1 and the pattern stalls. This is the exact failure mode from the original report.
The correct XOR toggle uses two markers, not the output itself:
// OB30 - 2000 ms phase
// Network 1: write the inverted state of M0.0 to Q0.0
M0.0
------|/|----------------( ) Q0.0
// Network 2: toggle M0.0 every OB30 tick
M0.0
------|/|----------+-----( )--
|
M0.1 |
------| |------------+
Where M0.1 is a marker initialized TRUE in OB100 startup. M0.0 toggles every OB30 tick. Q0.0 is the inverse of M0.0. This produces a clean 1 Hz / 50% duty blink.
Pattern B: Set/Reset Flip-Flop
// OB30 - 2000 ms phase
// Network 1: set Q0.0 on rising M_phase
M_phase
------| |--------------(S) Q0.0
// Network 2: reset Q0.0 on falling M_phase
M_phase
------|/|--------------(R) Q0.0
// Network 3: toggle M_phase
M_phase
------|/|----------+-----( )--
|
M_phase |
------| |------------+
The flip-flop pattern uses an XOR-style toggle on M_phase (M0.0) and then drives set/reset on Q0.0 from the same marker. M_phase flips every 2000 ms. Q0.0 follows: 2 s TRUE, 2 s FALSE. This is the cleanest pattern when other parts of the program also need to read Q0.0.
Pattern C: Counter with Threshold
// OB30 - 2000 ms phase
// Network 1: increment counter
TRUE
------| |------------(INC) MW10
// Network 2: compare and reset
MW10 > 1
------| |-------------(S) M0.1
MW10 > 1
------| |-------------(MOV) MW10 := 0
// Network 3: drive output
M0.1
------| |--------------( ) Q0.0
MW10 increments on every OB30 tick. After two ticks, M0.1 latches and Q0.0 turns on. MW10 then resets and the cycle repeats. This produces a 2-ON / 2-OFF blink at 2000 ms granularity. Adjust the comparison threshold (1, 2, 3) to change the duty cycle.
Pattern D: SCL Equivalent (TIA V16)
// OB30 - Cyclic Interrupt, 2000 ms phase
// SCL implementation
IF "OB30_EDGE" THEN
"OB30_EDGE" := FALSE;
ELSE
"OB30_EDGE" := TRUE;
END_IF;
IF "OB30_EDGE" THEN
%Q0.0 := TRUE;
ELSE
%Q0.0 := FALSE;
END_IF;
The SCL pattern uses an explicit IF/ELSE to write either TRUE or FALSE every OB30 tick. This is the most readable pattern and works identically in PLCSIM and on a real CPU. Compile OB30 with the SCL source attached so that subsequent edits do not break the toggle.
Verifying OB30 Execution in PLCSIM and on Real CPU
PLCSIM V16 Path
- Start Start > Simulation > PLCSIM (S7-1200/S7-1500).
- Download the project to the simulated instance.
- Open the OB30 editor. Right-click the network and select Monitor with trigger.
- Add Q0.0 to the trigger condition. Set the sample rate to 500 ms.
- Run the simulation. Q0.0 should toggle every 2000 ms.
PLCSIM ignores I/O module delays and most scan-time jitter. A pattern that works in PLCSIM should also work on real hardware, but the inverse is not always true — a pattern that fails on hardware (e.g. due to OB80 firing) may run in PLCSIM because the simulator does not enforce strict cycle timing.
Real CPU Path
- Connect to the S7-1217 via Ethernet. Go online.
- Open Online > Diagnostics > Cycle time. Confirm OB30 entry count and total execution time.
- Open Online > Diagnostics > Diagnostic buffer. Look for OB80 entries (time error) — none should appear under normal load.
- Use the trace function (CPU 1217 firmware V4.4+ supports trace). Configure a trace on Q0.0 with a 5-second recording. You should see a square wave at 1 Hz / 50% duty.
If the trace shows Q0.0 toggling but the physical LED on the digital output module is steady, the issue is the wiring or the output module, not OB30. Verify the output module address and the device configuration.
Priority Classes and OB Preemption
Cyclic interrupt OBs use fixed default priority classes on the S7-1200 (firmware V4.4+):
| OB | Default priority | Class |
|---|---|---|
| OB1 (main) | 1 | Cyclic main |
| OB10 | 2 | Time-of-day |
| OB20 | 4 | Delay |
| OB30 | 12 | Cyclic interrupt |
| OB31 | 13 | Cyclic interrupt |
| OB32 | 14 | Cyclic interrupt |
| OB33 | 15 | Cyclic interrupt |
| OB34-OB38 | 16-20 | Cyclic interrupt |
| OB40 | 16 | Hardware interrupt |
| OB80 | 26 | Time error |
| OB82 | 9 | Diagnostic interrupt |
| OB85 | 9 | Start event |
| OB121 | Same as offending OB | Programming error |
| OB122 | Same as offending OB | I/O access error |
OB30 preempts OB1 immediately. If two cyclic OBs share a priority, the second instance is queued. If a higher-priority OB is still running when OB30 should fire, OB30 is delayed but not skipped on S7-1200. On S7-1500 the S7-1500 family allows multiple late instances up to a configurable count via the OB properties — see the Siemens cyclic interrupt OB documentation for the late-instance parameter.
If you change the priority of OB30 to a value below OB1 (priority 1), OB30 will not preempt OB1 and may never run. TIA Portal V16 rejects priorities below 2 with a compile error, but if you are migrating a project from an older TIA version, verify the priority manually.
Diagnostics: OB80, OB85, OB121 When OB30 Is Overrun
If OB30 repeatedly takes longer than its phase, the S7-1200 calls OB80 (time error). The diagnostic buffer entry looks like:
Event ID : 0x3501
OB that caused error : OB30
Priority class : 12
Requested OB : 0x30
Event : Time error - exceeded cycle time
If OB30 tries to access a non-existent I/O point or a DB that is not loaded, OB121 (programming error) fires synchronously inside OB30. OB85 (start event) fires when an OB is registered but cannot start (e.g. OB30 is configured but not downloaded, or the OB number is out of range). If OB30 reads %IW100:P on a CPU that only has 64 bytes of input, OB122 (I/O access error) fires.
| Event | Cause | Resolution |
|---|---|---|
| OB80 (0x3501) | OB30 exceeds its phase | Shorten OB30 code or increase the phase |
| OB80 (0x3502) | OB30 call still pending, second instance due | Increase phase or remove cyclic OB |
| OB121 | DB not loaded, syntax error, divide by zero | Check DB number, instruction parameters |
| OB122 | Direct I/O access to missing module | Verify hardware configuration matches rack |
| OB85 (0x350A) | OB30 not downloaded but referenced | Download OB30 with the project |
Insert empty OB80, OB82, OB85, OB121, OB122 handlers in the program blocks if you want to handle these gracefully; otherwise the CPU transitions to STOP on the first error. Adding empty handlers does not change the underlying fault — it only prevents the STOP transition so that the diagnostic buffer can be read.
Best Practices and Common Mistakes
| Mistake | Symptom | Fix |
|---|---|---|
| Output coil with no reset | Q stays latched | Use XOR toggle or SR flip-flop (Patterns A-D) |
| Two cyclic OBs at same priority firing simultaneously | One is queued, slow response | Use different priority classes or stagger phases (S7-1500) |
| Phase too short for CPU load | OB80 fires, CPU STOP | Increase phase, or move code to OB1 |
| Accessing non-PI I/O in OB30 with PII update disabled | Stale inputs | Use direct I/O access %I0.0:P or assign OB30 a PIP |
| Calling FB that contains a TON with long PT | Q0.0 only changes once | Reset the timer on each OB30 entry |
| Using marker bit instead of PIQ address in SCL | Output never updates | Assign to %Q0.0 not to M0.0
|
| Modifying phase online without restart | OB30 keeps old phase | Perform OB30 restart via TIA or power cycle |
| Confusing PIQ bit with physical output | Q0.0 latched but LED off | Check module wiring, fuse, address mapping |
Best practices checklist for cyclic interrupt OBs:
- Keep OB30 short. Move bulk logic to OB1 or a task at lower priority. A typical OB30 should execute in well under its phase.
- Use XOR or SR flip-flop patterns for blink / alternation. Do not rely on PIQ persistence without an explicit reset.
- Always provide OB80, OB82, OB85, OB121, OB122 empty handlers when cyclic OBs interact with I/O or DBs.
- Document the configured phase of each cyclic OB in the project header comments. Phase drift is hard to debug without a reference value.
- Avoid direct I/O access (
:P) inside high-rate cyclic OBs — it bypasses the process image, increases bus load, and removes the consistency guarantee that PII/PIQ provide. - Verify cyclic OB execution with the trace function before sign-off. A 30-second trace recording Q0.0 with sample period 100 ms confirms the effective cycle time on the real CPU.
- On TIA V16 and older, export the diagnostic buffer after every commissioning to a CSV. Cycle-time histogram and OB count must be archived.
- If you observe OB30 firing once at startup and not again, check the diagnostic buffer for OB80 (time error) and confirm that the phase is not being overwritten by online edit.
FAQ
Why does my Q0.0 stay ON after I add OB30 with a TRUE contact?
OB30 sets Q0.0 in the process image output (PIQ) to TRUE on every execution and never writes FALSE. The PIQ bit stays at 1 between OB30 invocations because the CPU never resets it. Replace the network with an XOR toggle, an SR flip-flop, or an SCL IF/ELSE pattern (see Patterns A-D above).
Does OB30 fire once or continuously every 2000 ms?
OB30 fires continuously every 2000 ms (the configured phase). The single execution time is in microseconds, but the scheduler re-arms the timer and calls OB30 again on each elapsed phase. To verify, monitor the cycle-time histogram in TIA Portal V16 under Online > Diagnostics > Cycle time.
Can I configure OB30 below 1 ms on an S7-1217?
Yes, on firmware V4.4 and later the minimum phase of OB30 is 1 ms. For sub-millisecond phases use OB35 (100 µs), OB36 (50 µs), OB37 (20 µs), or OB38 (10 µs). Older firmware (V4.0-V4.3) on the S7-1200 may not support 1 ms OB30; upgrade the CPU firmware via TIA Portal V16 Update 7 or later.
Why does my blink pattern work on PLCSIM but not on the real S7-1217?
PLCSIM ignores I/O module delays and most scan-time jitter, and it does not enforce strict OB80 triggering. If your real CPU behaves differently, check the diagnostic buffer for OB80 entries (time error) and confirm the firmware is at least V4.4. A pattern that fires OB80 on real hardware may still run in PLCSIM because the simulator is more forgiving.
What happens if OB30 takes longer than its phase?
The next OB30 instance is queued. The S7-1200 only allows one queued instance per priority. If a third instance becomes due before the previous one finishes, OB80 fires and the CPU transitions to STOP unless an OB80 handler is present. Either shorten the OB30 code or increase the configured phase.