Implementing a Moving Totalizer Rolling Window FIFO Integrator in PCS 7 APL

Implementing a Moving Totalizer Rolling Window FIFO Integrator in PCS 7 APL

In SIMATIC PCS 7, the standard Advanced Process Library TotalL block (FB 1906) operates as a continuous accumulator or interval-based totalizer, but lacks native First-In-First-Out (FIFO) buffer mechanics required for a moving or rolling-window totalizer (e.g., totalizing flow over the preceding 2 hours at a 1-second sampling rate). To implement a moving totalizer in the automation controller without excessive CPU cycle overhead, design a custom SCL function block utilizing a circular ring buffer (Ringpuffer) rather than array-shifting FIFO logic. By maintaining a running sum—adding the newest incoming sample and subtracting the oldest expiring sample from the ring buffer in each cycle—the algorithm computes the moving total with O(1) mathematical efficiency, eliminating heavy memory copy operations across organization blocks.

Table of Contents

Executive Summary

Continuous process industries (such as wastewater effluent monitoring, batch chemical feed rates, and environmental emissions compliance) often mandate calculating rolling cumulative quantities over sliding historical windows (e.g., 1-hour or 2-hour rolling limits). While standard PCS 7 totalizer blocks accumulate forward totals until an explicit reset pulse occurs, they do not retain a sliding window of historical sample points. Attempting to implement a naive FIFO queue using large array memory shifts (BLKMOV) in CFC quickly exhausts S7-400 CPU work memory and introduces execution latency into OB35. Implementing an optimized circular ring buffer in SCL provides predictable execution time and scalable moving totalization.

Architecture and Fundamental Mechanics

The algorithmic and architectural mechanics of a rolling-window moving totalizer operate through structured data manipulation:

  1. Standard TotalL Limitations:
    * TotalL calculates totals using trapezoidal or rectangular numerical integration over continuous execution time.
    * It provides daily or batch resetting via external triggers, but maintains zero historical state memory beyond the previous execution cycle.
  2. The Pitfall of Classical FIFO Array Shifting:
    * Storing 2 hours of data at 1-second intervals requires 7,200 samples (7,200 REAL values = 28.8 KB of data block memory per stream).
    * A traditional FIFO shifts array elements on every sample: Array[0] := Array[1], Array[1] := Array[2], up to 7,200.
    * Executing 7,200 memory moves every second inside a cyclic interrupt (OB35 100ms or OB32 1s) consumes unacceptable controller execution time, triggering cycle overruns and communication watchdog faults (WD_ERR).
  3. The Circular Ring Buffer Architecture (Optimal O(1) Solution):
    * A circular ring buffer uses a fixed-size static array of size $N$ (e.g., $N = 7200$) and a single moving pointer (WriteIndex).
    * The running total ($S$) is updated instantaneously using the difference equation:
    S_new = S_old + Sample_new - Array[WriteIndex]
    * The expiring oldest sample (Array[WriteIndex]) is subtracted, the newest sample (Sample_new) is added to the running sum, and the newest sample is written into Array[WriteIndex].
    * The pointer advances cyclically: WriteIndex := (WriteIndex + 1) MOD N.
    * This mathematical approach requires exactly one subtraction, one addition, and one memory write per execution scan, regardless of whether the window contains 100 or 10,000 samples.

Step-by-Step Implementation Procedure

Follow these procedures to create and deploy a circular ring buffer moving totalizer in PCS 7:

  1. Create SCL Moving Totalizer Function Block:
    * In SIMATIC Manager, open your S7 Program and navigate to the Sources folder.
    * Create a new SCL source file named FB_MovingTotalizer.
    * Declare the ring buffer array in the static memory section: Buffer : ARRAY[0..7199] OF REAL;.
    * Declare parameters: PV_In : REAL;, WindowSize : INT := 7200;, Reset : BOOL;, Total_Out : REAL;.
  2. Implement Ring Buffer Logic in SCL:
    * In the SCL implementation body, program boundary checking and ring updating:
    scl IF Reset OR (WindowSize <= 0) THEN Total_Out := 0.0; WriteIndex := 0; FOR i := 0 TO 7199 DO Buffer[i] := 0.0; END_FOR; ELSE // Subtract oldest expiring value and add newest incoming value Total_Out := Total_Out + PV_In - Buffer[WriteIndex]; // Overwrite oldest position with new sample Buffer[WriteIndex] := PV_In; // Advance pointer cyclically WriteIndex := (WriteIndex + 1) MOD WindowSize; END_IF;
  3. Compile SCL Source into S7 Program:
    * Compile the SCL source file; verify that FB is generated in the Blocks folder without compiler errors.
  4. Instantiate in CFC Cyclic Interrupt OB:
    * Open CFC editor.
    * Drag your custom FB_MovingTotalizer into a CFC chart.
    * Assign the block to an appropriate cyclic interrupt organization block (e.g., OB32 with a 1.0-second cycle time, or OB35 with appropriate sample timing).
    * Interconnect the analog measurement from Pcs7AnIn.PV_Out.Value to PV_In.
  5. Compile and Download:
    * Compile CFC charts with 'Scope: Changes only'.
    * Download the program to the AS controller in RUN mode.

Verification

In CFC test mode, monitor the block inputs and outputs. Apply a constant input of 10.0 units/sec. Set WindowSize = 10 for initial bench testing. Confirm that for the first 10 cycles, Total_Out increments by 10.0 each second until reaching 100.0. After 10 cycles, confirm that Total_Out remains locked at exactly 100.0 as oldest samples drop off. Change the input to 20.0; confirm that the total ramps smoothly to 200.0 over the next 10 seconds.

Limitations and Operational Precautions

Ensure that the S7-400 / CPU 410 work memory is adequately sized; large arrays declared in instance data blocks consume substantial RAM. For historical compliance reporting spanning multiple days or months, execute long-term rolling averages on the OS Server or Process Historian rather than within the PLC controller.

Engineer FAQ

Can APL TotalL perform moving totalization natively?

No. TotalL is an accumulating integrator with forward summation; it does not retain a sliding historical buffer of individual samples.

Why is a circular ring buffer preferred over array shifting?

A circular ring buffer has O(1) constant execution time, performing only one add and one subtract per cycle, whereas array shifting consumes massive CPU cycles shifting thousands of elements.

How much DB work memory is required for 7,200 REAL values?

7,200 REAL values at 4 bytes each consume approximately 28.8 KB of data block memory.

What happens during controller restart (OB100)?

On restart, the buffer can either be cleared to zero or preserved if configured in non-volatile retentive DB memory.

Technical References

Related Articles

Related Tags

  • TotalL
  • Moving Totalizer
  • Ring Buffer
  • SCL Programming
  • S7-400 Memory
20 respuestas