Avoiding Infinite WHILE Loops and Implementing Periodic Cycle Timers in PCS 7 SCL Blocks

Avoiding Infinite WHILE Loops and Implementing Periodic Cycle Timers in PCS 7 SCL Blocks

In SIMATIC PCS 7, writing a custom SCL block containing an unbounded 'WHILE IN = TRUE DO ... END_WHILE;' loop will cause the automation controller or SIMIT simulation to freeze, trigger an Organization Block 80 (OB80) cycle time watchdog timeout, and crash the CPU into STOP mode. A programmable logic controller operates on a cyclic execution model; a WHILE loop whose exit condition cannot be satisfied within microseconds monopolizes the CPU scan, blocking all other blocks and task queues. To generate a recurring pulse (e.g., to re-trigger an alarm on a MonDiL block), use standard non-blocking library blocks—such as TimerP (FB5) or Pulse from the PCS 7 Basis Library—or implement a non-blocking accumulator in SCL that increments by SampleTime each execution cycle without looping.

Table of Contents

Executive Summary

Developing custom algorithmic blocks in Structured Control Language (SCL) for SIMATIC PCS 7 allows automation engineers to implement specialized calculations, state machines, and message re-triggering logic. A recurring requirement involves generating a recurring periodic pulse: asserting an output TRUE for one CPU scan cycle every $N$ seconds while an enabling condition remains active (e.g., to periodically re-announce an unacknowledged alarm on an APL MonDiL block).

Engineers transitioning from standard procedural programming (such as C++, Java, or Python) frequently attempt to implement periodic timers using standard looping constructs—specifically writing WHILE IN = TRUE DO ... END_WHILE;. When this block is downloaded to an S7-400 CPU or tested in SIMIT Simulation Platform, the runtime environment immediately freezes, task execution halts, and the CPU trips its cycle watchdog timer (OB80). This technical guide analyzes the fundamental cyclic execution paradigm of industrial PLCs, explains why blocking loops cause fatal system lockups, and provides two verified non-blocking solutions using standard PCS 7 blocks and clean SCL accumulator code.

Architecture and Fundamental Mechanics

The execution model of SIMATIC S7 controllers and SIMIT simulation engines differs fundamentally from general-purpose desktop operating systems:
1. The Cyclic Execution Paradigm:
* An industrial PLC does not dedicate a thread to wait for a timer; it executes sequentially through an Organization Block (e.g., OB35 at 100 ms or OB1).
* Every block assigned to that OB must execute its instructions from top to bottom and exit within a few microseconds, returning control to the operating system dispatcher.
* The operating system enforces a strict Scan Cycle Watchdog Timer (typically configured between 150 ms and 6000 ms).
2. The Anatomy of a WHILE Loop Crash:
* Consider the problematic code:
scl WHILE IN = TRUE DO ms := TIME_TO_DINT(T); IF ((ms MOD cycle) = 0) AND IN = TRUE THEN OUT := TRUE; END_IF; END_WHILE;
* When IN transitions to TRUE, the CPU enters the WHILE loop. Because IN is an external input parameter that does not change during the microsecond execution of that specific block, the condition IN = TRUE remains permanently true within that scan.
* The CPU becomes trapped in an infinite execution loop, recalculating the modulo operation millions of times. The scan cycle timer elapses, OB80 is called (or the CPU stops if OB80 is unhandled), and SIMIT simulation freezes because the virtual clock cannot advance.
3. Non-Blocking Periodic Pulse Mechanics:
* A non-blocking periodic timer evaluates time progression across successive scan cycles.
* Each cycle, it increments an internal real-time accumulator by the OB cycle time (SampleTime, e.g., 0.1 s).
* When Accumulator >= TargetInterval, the block asserts OUT := TRUE, resets the accumulator to 0.0, and exits immediately.
* On the subsequent scan, OUT returns to FALSE, producing a clean, single-cycle pulse without delaying the CPU.

Step-by-Step Implementation Procedure

Step 1: Replace Custom Code with Standard TimerP Block (Recommended)

  1. Open the target CFC chart in the Engineering Station.
  2. In the PCS 7 Basis Library or Standard Library, locate the standard timer block: TimerP (FB5).
  3. Instantiate TimerP in the chart adjacent to your MonDiL block.
  4. Configure the parameters:
    * MODE = 1 (Pulse mode) or MODE = 2 (Extended pulse).
    * Ti: Set to your desired recurrence interval (e.g., T#10s).
    * Connect the enable condition to the start input.
    * Interconnect TimerP.Out through an inverter or edge evaluator back to its reset pin to create an automated recurring astable multivibrator pulse.

Step 2: Implement Non-Blocking Periodic Pulse in SCL

If custom SCL code is strictly required, implement a clean, non-blocking accumulator pattern:

FUNCTION_BLOCK FB3007
TITLE = 'PeriodicPulseTimer'
{ S7_m_c := 'true' }
AUTHOR : 'Engineering'
VERSION : '1.0'

VAR_INPUT
    Enable     : BOOL;       // Enable periodic pulse generation
    Interval   : REAL := 5.0;// Pulse interval in seconds
    SampleTime : REAL := 0.1;// OB execution sample time in seconds (e.g., 0.1 for OB35)
END_VAR

VAR_OUTPUT
    PulseOut   : BOOL;       // Generates 1-cycle TRUE pulse every Interval
END_VAR

VAR
    AccTime    : REAL := 0.0;// Internal elapsed time accumulator
END_VAR

BEGIN
    // Reset output pulse by default each scan cycle
    PulseOut := FALSE;

    IF Enable THEN
        // Increment accumulator by cyclic OB sample time
        AccTime := AccTime + SampleTime;

        // Evaluate if interval has elapsed
        IF AccTime >= Interval THEN
            PulseOut := TRUE;  // Output single-cycle pulse
            AccTime := 0.0;    // Reset accumulator
        END_IF;
    ELSE
        AccTime := 0.0;        // Reset timer when disabled
    END_IF;

END_FUNCTION_BLOCK

Step 3: Integrate with MonDiL External Message Input

  1. In the CFC chart, insert FB3007.
  2. Interconnect your process condition (e.g., unacknowledged trip condition) to Enable.
  3. Set Interval = 10.0 (10 seconds).
  4. Set SampleTime matching the chart's cyclic interrupt OB (e.g., 0.1 for OB35).
  5. Interconnect PulseOut to the ExtMsg1 or ExtMsg2 input on the MonDiL block.

Step 4: Verify OB Execution Order

  1. Open the CFC Run Sequence (Edit > Run Sequence).
  2. Verify that FB3007 executes immediately BEFORE MonDiL in the same cyclic interrupt OB, ensuring that the pulse is evaluated by MonDiL in the same execution cycle.

Step 5: Compile and Test in SIMIT / PLCSIM

  1. Compile the CFC chart folder (Chart > Compile > Changes only).
  2. Download to S7-PLCSIM or SIMIT Simulation Platform.
  3. Start the simulation and verify smooth execution.

Verification

  1. In SIMIT or CFC test mode, force Enable = TRUE.
  2. Monitor the CPU diagnostic buffer: verify that zero OB80 cycle watchdog errors are recorded and CPU scan time remains under 10 ms.
  3. Add PulseOut to the CFC watch list: verify that PulseOut pulses TRUE for exactly one execution cycle every 10 seconds.
  4. In WinCC Runtime, open the alarm journal: confirm that MonDiL triggers a recurring message at 10-second intervals without locking the HMI or freezing faceplate scripts.

Limitations and Operational Precautions

  1. Never use unbounded WHILE or REPEAT loops in PLC programming; all loops must have guaranteed termination counts that execute within a few microseconds.
  2. The precision of SampleTime accumulation depends on consistent OB scheduling; place the block in a fixed cyclic interrupt OB (OB32–OB38), not the free cycle (OB1).
  3. If Interval is set smaller than SampleTime, the block will pulse every cycle; ensure Interval > SampleTime.
  4. Custom SCL function blocks require unique block numbers (FBs) that do not conflict with the PCS 7 Basis Library or APL block ranges (FB1000–FB2999).

Engineer FAQ

Why did the WHILE loop freeze SIMIT and the S7 CPU?

The condition WHILE IN = TRUE could never become false during that single scan cycle. The CPU was trapped in an infinite loop, exceeding its watchdog timeout and crashing the controller.

How do timers work in PLCs without pausing execution?

PLC timers do not pause code. They evaluate time progression non-blockingly across successive scan cycles by measuring system clock ticks or accumulating the OB's execution sample time (SampleTime).

Can I use standard TimerP instead of writing custom SCL?

Yes. Standard TimerP (FB5) or Pulse from the PCS 7 Basis Library is the manufacturer-recommended solution, requiring zero custom coding.

What is OB80 in SIMATIC S7?

OB80 is the Cycle Time Fault Organization Block, called by the CPU operating system when a scan cycle exceeds the configured maximum cycle watchdog time.

What block numbers are safe for custom user FBs in PCS 7?

User-created blocks should be assigned numbers outside standard library ranges, typically in the range FB3000 to FB4095.

Technical References

Related Articles

Related Tags

  • SCL
  • WHILE Loop
  • Cycle Watchdog
  • OB80
  • TimerP
20 respuestas