Resolving S7-PLCSIM OB33 OB80 Error 16#3502 Cyclic Interrupt

David Krause15 min read
S7-300SiemensTroubleshooting
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

Problem Overview

When a working STEP 7 program is downloaded into S7-PLCSIM (versions 5.x for SIMATIC Manager, or S7-PLCSIM V13/V14/V15/V16 inside TIA Portal) the simulated CPU can drop into STOP mode on the first scan and emit a cluster of diagnostic-buffer events that all stem from a single cyclic-interrupt overflow. The typical diagnostic buffer sequence looks like this:

Event # Event ID (hex) Meaning Triggered By
1 16#530D New startup information in STOP mode (warm restart prevented) CPU operating system
2 16#4541 STOP caused by priority class system (OB1 free-cycle overrun) OB1 scheduler
3 16#3502 OB request error – requested OB missing or OB error during execution OB33 (cyclic interrupt) overflowed and called OB80 (timing error)

The accompanying coding word in the buffer entry is the standard Siemens 8-byte event structure:

Event 3: 16# 3502 1A50 C358 0000 1134 0A21
  Byte 0-1 : Event ID       = 16#3502  (OB request error)
  Byte 2-3 : Identifier 1   = 16#1A50  (no relevance for user / internal)
  Byte 4-5 : OB-number pkg  = 16#C358  (causing OB 33, prio 10)
  Byte 6   : Requested OB   = 16#34    (OB80 - Timing Error)
  Byte 7   : Prioclass req. = 16#0A    (priority 26 of OB80)

The full chain means: the simulated CPU attempted to start OB33 on its scheduled time, OB33 either was missing, took longer than its configured period, or threw an internal exception, and the operating system tried to call the timing-error OB (OB80) – which is also missing – so the CPU transitioned to STOP with priority-class error 16#4541. On a real S7-300/S7-400 CPU the same program typically runs because the real hardware scheduler and instruction timings differ from PLCSIM's cycle model.

Important: PLCSIM is a behavioural simulator, not a cycle-accurate emulator. It cannot reproduce every runtime characteristic of an S7-CPU – especially interrupt scheduling, encrypted S7-Block Privacy blocks, and forced variables behave differently. Always validate the same project on the physical target before field deployment.

Affected Products and Versions

The fault pattern has been observed on the following software/hardware combinations:

Product Version Status
S7-PLCSIM V5.4 + SP5 (SIMATIC Manager) V5.4.5.0 Reproduction confirmed by user report
S7-PLCSIM V5.4 + SP4 V5.4.4.0 Same behaviour
S7-PLCSIM V13 (TIA Portal V13) V13.0 Improved but still possible
S7-PLCSIM V14/V15/V16 V14–V16 Same OB80 path; resolved only by code fix
CPU 315-2 PN/DP, CPU 317-2, CPU 319-3 PN/DP Firmware 3.x Target hardware – runs without OB80 on identical code
CPU 416-3 PN/DP Firmware 6.x Target hardware – runs without OB80 on identical code

Reference: S7-PLCSIM V5.4 Manual (entry ID 54667828) and S7-PLCSIM Application Limitations (entry ID 36462014) in the Siemens Industry Online Support portal.

Root Cause Analysis

The 16#3502 event is a generic "OB request error" generated by the SIMATIC CPU operating system when it tries to start a system OB that the user program has not loaded. In the sequence above the operating system followed this decision tree:

  1. The cyclic-interrupt clock generator for phase 4 (OB33) fired at its scheduled time.
  2. OB33 either (a) was not present in the downloaded SDB, (b) ran longer than the configured phase time, or (c) raised a programming error that the OS escalated to OB80.
  3. OB80 (timing error) was also not present in the project, so the OS entered the priority-class stop path.
  4. The OB1 free-cycle watchdog detected the cascading OB failure and produced 16#4541.
  5. The startup attempt was aborted with 16#530D – STOP request exists, warm restart required.

The decisive information is encoded in bytes 4-7 of the event-coding word:

1A 50 C3 58 00 00 11 34 0A 21
                ^----OB33,  ^--OB80, ^--Prio 26

Three sub-causes are typically responsible:

Sub-Cause 1 – OB33 Not Downloaded

If the cyclic-interrupt OB exists in the offline project but is not in the active SDB, or if a different cyclic OB (e.g., OB35) is referenced, the OS still tries to call OB33 because the cyclic-interrupt configuration in HW Config is fixed at build time. Verify with: STEP 7 → Blocks → right-click → Object Properties → "Download to target device".

Sub-Cause 2 – OB33 Exceeds Its Phase Time

Each cyclic-interrupt OB (OB30-OB38) has a fixed base period. The default values on an S7-300 CPU are:

OB Default Phase (ms) Default Priority Use Case
OB30 5000 7 Free cycle
OB31 2000 8 Free cycle
OB32 1000 9 Free cycle
OB33 500 10 Free cycle
OB34 200 11 Free cycle
OB35 100 12 Free cycle (most common)
OB36 50 13 Free cycle
OB37 20 14 Free cycle
OB38 10 15 Free cycle

If OB33 contains a heavy block, multiple SFB/SFC calls, indirect addressing, or a loop that scales with array size, its execution time can exceed 500 ms. PLCSIM's instruction-timing model is conservative; many blocks that complete in <100 ms on a real CPU 315-2 can exceed 500 ms in PLCSIM V5.4, which is exactly the OB33 phase budget.

Sub-Cause 3 – Missing OB80 (Timing-Error OB)

Even when the overrun is the real culprit, the user can keep the CPU in RUN by simply loading OB80 into the project. The default OB80 supplied by STEP 7 (Libraries → Standard Library → System Function Blocks → OB80) only acknowledges the time error and continues execution. This is the standard Siemens recommendation and the workaround that resolves the 16#3502/16#4541 cluster immediately.

Diagnostic Procedure

Follow this ordered procedure to isolate the OB33 / OB80 root cause.

  1. Open the diagnostic buffer. In SIMATIC Manager: PLC → Diagnostic/Setting → Diagnostic Buffer. In TIA Portal: Online → Diagnostics → Diagnostic buffer. Note the order of events, not just the latest one.
  2. Read the event-coding word. Bytes 6-7 of the 16#3502 entry identify the requested OB and its priority. Here: 16#34 = OB80, priority 16#1A = 26. Confirm OB80 is absent from the project offline.
  3. List all cyclic OBs in the offline project. In SIMATIC Manager: Blocks → right-click → Show → OB. Verify whether OB30-OB38 exist and which are loaded in the SDB.
  4. Measure the cycle time of OB33 in PLCSIM. In OB33, insert:
    L #OB33_EXC_FREQ // load configured time base in ms
    L #OB33_TIME_LOAD // load actual measured time
    -D
    T #DB_CYCLE_SLACK // store delta

    With OB33_STARTTIME, OB33_EXC_FREQ, OB33_PHS_OFFSET, and the SFC78 OB_RT / SFC79 SET_OB_RT you can profile the time. The relevant temporary variables are exposed automatically in the OB's interface declaration.
  5. Run the same program on a physical CPU. Connect a CPU 315-2 DP, place it in RUN, and watch the diagnostic buffer. If 16#3502 does not appear, the issue is PLCSIM-specific and you can use the real PLC to verify the fix.
  6. Check for unsupported constructs. PLCSIM does not execute encrypted S7-Block Privacy blocks, SFC109 / SFC110 protection calls, or some SFCs that depend on hardware (SFC51, SFC52, SFC187). See S7-PLCSIM application limitations.

Solution Path A – Load OB80 (Quick Mitigation)

This is the fastest fix and is appropriate when the overrun is benign (e.g., known loop bounded by data size). Steps:

  1. Open SIMATIC Manager and the S7 project.
  2. Insert a new OB: Blocks → right-click → Insert New Object → Organization Block.
  3. In the dialog, change the type to OB80 – Time-of-Day Error / Timing Error.
  4. Open the OB and copy the standard content from Libraries → Standard Library → System Function Blocks → OB80 (BF-AW). The default body simply sets the OB80_RESERVED field and returns; that is all that is required.
  5. Save and download: PLC → Download.
  6. Perform a CPU restart: PLC → Operating Mode → Complete Restart or power-cycle PLCSIM.
  7. Verify: the diagnostic buffer should now show OB80 start events instead of 16#3502 OB-request errors.

If OB80 fires repeatedly, the simulator is still running OB33 over its budget – move to Path B.

Solution Path B – Re-Architect Cyclic Logic

Spread the heavy workload across multiple cyclic OBs and the free cycle so no single OB exceeds its phase time.

Workload Distribution Example

Task Original OB Recommended OB Reason
Acquisition / pre-processing (10 ms) OB33 OB38 (10 ms phase) Fast acquisition needs short phase
Control loop (50 ms) OB33 OB36 (50 ms phase) Matches typical PID cycle
Statistics / logging (500 ms) OB33 OB33 (500 ms phase) Long-period work fits in long phase
Housekeeping / diagnostics OB33 OB1 (free cycle) Non-time-critical work

Inside the OBs – Best-Practice Skeleton

// OB35 – 100 ms control loop
CALL  "CTRL_PID" , DB100       // PID with background self-tune
      I_IN   := IW512
      SETPNT := MD200
      I_OUT  := QW512

// Edge-trigger guard against overrun
      L     #OB35_TIME_LOAD     // accumulated OB35 runtime
      L     80                  // 80% of 100 ms budget
      >I
      JC    OVER                // jump if overrun risk

      // ...normal logic...
OVER: SET                          // set internal flag
      SAVE                        // for OB1 to log later

Use SFC79 SET_OB_RT to query the time remaining in the current OB, and SFC78 OB_RT to obtain the configured time base. Sample call inside OB33:

CALL  SFC 79                 // SET_OB_RT
      OB_NR     := 33
      RET_VAL   := MW240         // ms remaining or error code

      L     MW240
      L     200                 // 200 ms headroom
      <I
      JC    BUSY                // skip slow work this cycle
      // ...slow path...

Solution Path C – Adjust Cyclic Phase in HW Config

Sometimes the OB33 phase time is simply too tight for the project. Increase it in HW Config:

  1. Open HW Config.
  2. Select the CPU (e.g., CPU 317-2 PN/DP).
  3. Open Properties → Cyclic Interrupts tab.
  4. Change the OB33 phase to 1000 ms or 2000 ms (or whatever the logic actually needs).
  5. Recompile the hardware (Station → Save and Compile).
  6. Download the new SDB to PLCSIM.
Note on PLCSIM limits: PLCSIM honours the configured phase times but does not model instruction-execution timing the way an instruction-set simulator would. A 200 ms phase in PLCSIM may still be overrun by 80 ms of "wall-clock-equivalent" code because the host PC scheduler preempts the simulator. Increasing the phase is therefore a workaround, not a cure; the real fix is to make the OB budget positive on the physical target.

Solution Path D – Substitute or Bypass PLCSIM

When the project cannot be simplified (encrypted blocks, motion libraries, custom SFBs), evaluate alternatives:

Tool Vendor Cycle Accuracy Encrypted Blocks Cost
S7-PLCSIM V5.4 Siemens Low No (S7-Block Privacy blocked) Bundled with STEP 7
S7-PLCSIM V16/V17 (TIA) Siemens Low No Bundled with TIA Portal
PLCSIM Advanced V2/V3 Siemens Medium (virtual Eth, OPC UA) No Free download
SIMIT 10 / DEMO Siemens Medium (co-simulation) Limited License required
Physical CPU + ET200S lab Siemens High (real hardware) Yes Hardware cost
COOX 3S / Codesys + simulator 3S-Smart Medium N/A License

For S7-1500 targets, PLCSIM Advanced improves several limitations (virtual PROFINET, OPC UA server, web server) but still has the same OB execution-time discrepancy for very large cyclic OBs. For S7-300/S7-400, the only 100%-accurate option is a real CPU.

Verification Steps

After applying the fix, perform these checks in order:

  1. Diagnostic buffer clean. Power-cycle PLCSIM and watch the first 60 seconds of diagnostic events. The 16#3502/16#4541 cluster should be replaced by normal OB1 free-cycle start/stop entries (event ID 16#4381, 16#4382) or no events at all.
  2. OB33 cycle time check. In OB33, evaluate:
    L #OB33_EXC_FREQ
    L #OB33_TIME_LOAD
    /R
    T MD300 // ratio = load / phase
    L 0.8
    >R
    JC WARN

    If the ratio stays below 0.8 for a 30-minute test, the OB is healthy.
  3. OB80 presence test. In TIA Portal or SIMATIC Manager, open the online block list and confirm OB80 is online with the same timestamp as the rest of the project.
  4. Watchdog test. Force a deliberate OB33 overrun by inserting a 2-second delay loop. OB80 should fire, log a timing error, and the CPU should remain in RUN.
  5. Cross-check on physical CPU. Download to a real CPU 315-2 or CPU 317-2 and confirm the same diagnostic buffer pattern.
  6. Watchdog parameter audit. Open CPU Properties → Cycle/Clock Memory. Verify OB1 cycle monitoring time is 150 ms (default) or higher; 100 ms is too tight for many real projects.

Extended Troubleshooting Matrix

Symptom Diagnostic ID Likely Cause Fix
CPU enters STOP immediately 16#3502 + 16#4541 + 16#530D Missing OB80, OB33 overrun Add OB80 + redistribute logic
CPU enters STOP after 1 h 16#3502, OB80 fires Gradual data growth, array index out of bounds Bounds-check, IEC check enabled
CPU enters STOP on download 16#3582 / 16#3587 User program not consistent with HW Config Recompile, download SDBs together
CPU flashes SF/BF 16#AE03, 16#AE04 I/O fault, not OB issue Check ET200 stations
CPU OK in PLCSIM, STOP on real PLC None in PLCSIM, 16#3571 on real Encrypted block (S7-Block Privacy) Strip encryption for PLCSIM, use original on target
CPU STOP with 16#2522 16#2522 OB121 (programming error) not loaded Add OB121 default block
CPU STOP with 16#2523 16#2523 OB122 (I/O access error) not loaded Add OB122 default block
CPU STOP with 16#2942 16#2942 OB121 in OB1 raises unhandled exception Add OB121, check DB length, area-crossing errors
CPU STOP with 16#4303 16#4303 Mode selector, no startup OB Confirm OB100/101/102
CPU STOP with 16#43A3 16#43A3 Communication error, OB87 missing Add OB87 default

Why Real CPUs Hide the Problem

The S7-300/S7-400 CPUs use a deterministic priority-class scheduler driven by the hardware clock. PLCSIM V5.4 emulates the scheduler with the host-PC tick, but the host OS (Windows) preempts the simulator thread at irregular intervals. This makes PLCSIM more sensitive to long OBs than the physical PLC, and explains the symptom: "program runs on CPU, fails in PLCSIM." The real CPU's instruction execution is also faster – the 317-2's bit-execution time is 0.025 µs vs. PLCSIM's modelled 1-3 µs. If the OB33 logic is <300 ms on a real 317-2 it may push 600-800 ms in PLCSIM, exceeding the 500 ms phase.

Prevention Checklist for Future Projects

  1. Always load OB80, OB81, OB82, OB83, OB84, OB85, OB86, OB87, OB121, OB122 – the ten standard error OBs. They turn fatal errors into logged events and let the CPU stay in RUN.
  2. Configure IEC check in the offline program: STEP 7 → Options → Customise → LAD/FBD/STL → STL → Enable IEC check. This catches area-crossing errors at compile time.
  3. Set the OB1 cycle monitoring time to a value > 2× the measured worst-case OB1 runtime. Default 150 ms is often too low for projects with array processing.
  4. Use SFC79 SET_OB_RT inside cyclic OBs to query remaining time and skip slow work on the same cycle.
  5. When migrating from S7-PLCSIM V5.4 to TIA Portal PLCSIM V16/V17, retest every cyclic OB; the underlying execution model changed with the TIA simulator.
  6. Document the OB33 time budget in the project README. If the budget is < 200 ms, mark the project as "PLCSIM-incompatible."
  7. Prefer OB35 (100 ms) over OB33 (500 ms) for PID loops – the more frequent interrupt averages out jitter better and stays well below the typical PLCSIM sensitivity.

Related Siemens Documentation

For further reference, the following Siemens Industry Online Support entries are relevant. They are linked as the manufacturer documentation and should be used for verification against the latest firmware:

Field-Proven Caveats

  • Some users have reported that OB80 loaded but the simulator still drops to STOP because OB33 contained a DB_ANY variant that PLCSIM V5.4 mishandles. The fix is to use an explicit DB number rather than a DB opened by SFC7 DB_TEST in OB33.
  • When the OB33 body calls SFB41 CONT_C (PID) with the "background self-tune" option, PLCSIM may take 2-3× longer than a real CPU. Disable self-tune for the simulation branch.
  • Do not use SFC36 / SFC37 MSK_FLT / DMSK_FLT in PLCSIM to mask synchronous errors globally – the simulator's error model diverges from the hardware, and a masked error can still cause OB80 to fire repeatedly.
  • Encrypted S7-Block Privacy blocks are not executable in PLCSIM V5.4 SP5 and earlier. Trying to download them produces a follow-on 16#3582 diagnostic event. Use the unencrypted source project for simulation and the encrypted binary for the real CPU.

Summary of the Fix

For a project that runs on a real S7-300/400 CPU but emits 16#3502 / 16#4541 / 16#530D in PLCSIM, the canonical fix is a two-part change:

  1. Insert OB80 (Timing Error) with the default library body. This turns a fatal OB33 overflow into a logged event and keeps the CPU in RUN.
  2. Profile OB33 cycle time with SFC78/SFC79 or with the local temporary #OB33_TIME_LOAD. If the OB approaches or exceeds its 500 ms phase, redistribute work to other cyclic OBs (OB30-OB38) and to the free cycle (OB1).

Both changes must be saved into the SDB and downloaded together. After a complete restart of PLCSIM the diagnostic buffer should show only normal start events, and OB80 (if it still fires) will confirm that the scheduler is operating within budget.

What does S7-PLCSIM error 16#3502 mean?

Event 16#3502 is an "OB request error." The CPU operating system tried to start an OB that is either not present in the user program or was unable to execute. In the OB33/OB80 chain it means the cyclic-interrupt OB33 overflowed its phase time and OB80 (timing error) was not available, so the CPU entered STOP with priority-class error 16#4541.

Why does my program run on a real S7-300 CPU but fail in PLCSIM?

PLCSIM is a behavioural simulator: it does not execute the S7 instruction set in real time, and the host-PC scheduler preempts the simulator thread at irregular intervals. An OB33 that takes 300 ms on a real CPU 317-2 can take 600-800 ms in PLCSIM V5.4, exceeding the 500 ms default phase and triggering OB80. The error codes are real-time phenomena that the simulator exposes more aggressively than the hardware.

How do I add OB80 to a STEP 7 project?

In SIMATIC Manager, right-click Blocks, choose Insert New Object → Organization Block, select OB80, then copy the default body from Libraries → Standard Library → System Function Blocks → OB80 (BF-AW). Save and download to PLCSIM, then perform a complete restart. The CPU will now log timing errors instead of entering STOP.

How do I measure OB33 cycle time inside the program?

Use the local temporary variables of OB33: #OB33_EXC_FREQ (configured phase in ms), #OB33_TIME_LOAD (cumulative OB33 load), #OB33_STARTTIME (timestamp of OB33 start). For real-time budgeting, call SFC79 SET_OB_RT to read the remaining time in the current OB, and SFC78 OB_RT to obtain the configured time base. If #OB33_TIME_LOAD / #OB33_EXC_FREQ exceeds 0.8, the OB is close to its budget.

Can encrypted S7-Block Privacy blocks run in PLCSIM?

No. S7-PLCSIM V5.4 and the TIA Portal versions up to V17 cannot execute encrypted blocks. Trying to download such a project into PLCSIM produces a follow-on 16#3582 diagnostic event. Use the unencrypted source for simulation and the encrypted binary only for the real target CPU.

Back to blog