Slope Analysis in CX-Programmer for Flow Calibration

James Nishida12 min read
CJ/CP SeriesOmronTechnical Reference
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

Calibration machines that verify flow-rate behaviour on small fluid components require a deterministic way to decide whether the observed response of the part matches the expected response. On a typical Omron CJ2M / CP1H / CP2E platform programmed with CX-Programmer, a 0–10 V signal from a flow meter is scaled into engineering units, sampled at a fixed period, and stored in a 30-point circular buffer. The buffer is then evaluated in a single scan to flag the part as ideal, blocked, leaking or stripped using a combination of linear regression and second-derivative (slope-change) statistics.

This reference describes the math, the threshold selection, the structured text function block that performs the classification, and the commissioning steps that take the algorithm from a fresh CX-Programmer project to a verified production recipe.

1. Application Overview

A flow-calibration station takes a part, drives a small DC gear motor that turns an adjustment screw, and waits for the flow to ramp from 0 to a setpoint over a 6 second window. The expected behaviour of a good part is a near-linear ramp whose slope corresponds to the screw’s pitch. The four classes the cell must distinguish are:

Class Visual signature Process meaning
Ideal ~45° straight line from 0 to setpoint Accept the part, release to next station
Blocked Sharp upward spike then plateau Orifice plugged, route to reject bin
Leaking Near-horizontal line, slope ≈ 0 Seal failure, rework at the seat
Stripped Parabolic / S-curve, slope changes sign Screw threads damaged, scrap

The operator wants a single pass/fail decision plus a class code, and the customer wants the recipe held as CX-Programmer data so the part number drives the thresholds on a changeover.

2. Signal Conditioning and Scaling

Raw flow-meter output enters an Omron CP1W-AD041 or CJ1W-AD041-V1 analog input. Resolution is 1/6000 (0–10 V → 0000–1770 hex). Scaling is performed with the SCL2 instruction using the parameters listed below.

Parameter Address (D-word) Value Comment
Raw AI word CIO 200 0–1770 hex From AD041 channel 0
Scaled flow (L/min) D100 REAL (0.0–50.0) Output of SCL2
Setpoint (L/min) D102 REAL, recipe Operator target
Sampling period (s) D104 0.2 5 Hz sample rate
Sample count D106 30 6 seconds total window

For a CP1H, the AD041 input range word CIO 200 must be set to 0000 for 0–10 V. For a CJ2M built-in analog, the same scaling is performed in ST and stored directly into D100.

3. Data Acquisition: 30-Point Circular Buffer

A 0.2 s self-resetting timer drives a pointer that writes D100 into an array of 30 REAL registers, D200[0] through D200[29]. The timer is implemented with TIM 0000 200 on a CP1H (0.1 s base) and a divide-by-two counter when 0.2 s is required. On the CJ2M-CPU33 the TIMX instruction accepts a 1 ms base, so TIMX 0000 #200 gives an exact 200 ms period.

The acquisition is gated by a TEST_RUN flag (W0.00) that starts the timer and a TEST_DONE flag (W0.01) that latches when the index reaches 30. Both flags are reset when the operator presses “Start” on the HMI.

Always set D200…D229 to 0.0 on the rising edge of TEST_RUN using a BSET-style block move. Residual values from a previous bad part will corrupt the slope statistics.

4. Linear Regression Fundamentals

The classical least-squares fit returns a slope b and intercept a for the model y = a + b·x. With N=30 and xi = i·0.2 s:

slope b = (N·ΣXY − (ΣX)(ΣY)) / (N·ΣX² − (ΣX)²)
intercept a = (ΣY − b·ΣX) / N

For an evenly spaced time axis with xi = 0.2·i, the closed-form sums can be hard-coded constants to save PLC scan time:

Constant Symbolic form Numeric value (N=30, dt=0.2)
ΣX dt·N(N−1)/2 87.0
ΣX² dt²·N(N−1)(2N−1)/6 1738.0·dt² (0.2)
ΣX / N mean time 2.9

Replacing ΣX and ΣX² with constants reduces the regression to a single pass that only needs to accumulate ΣY and ΣXY. This is the version that should be deployed on CP1L / CP1E targets where scan time is critical.

5. Goodness of Fit: Sum of Squared Errors

Linear regression alone is not enough — the regression line is fit to any 30 points, including the parabolic stripped-unit curve. A separate metric is required to reject non-linear responses. The Sum of Squared Errors (SSE) is the standard choice:

SSE = Σi=0…29 (yi − (a + b·xi))²

A small SSE means the regression line tracks the data closely (ideal class). A large SSE means the data is not linear (stripped or blocked-then-flat). A flat line (leaking) has a small SSE because a horizontal line fits well, so a second test is needed for that class.

6. Second-Derivative (Slope-Change) Method

The second derivative of a sequence A[i] is a discrete three-tap filter:

d²A/di² ≈ A[i+2] − 2·A[i+1] + A[i]

For a straight line this quantity is zero at every index. For a parabola opening up it is a positive constant; for a parabola opening down it is a negative constant; for a flat line it is also zero. The Sum of Slope Change Squared (SSCS) test is:

SSCS = Σi=0…27 (A[i+2] − 2·A[i+1] + A[i])²

The SSCS test is cheaper than SSE because it does not need a regression — it is a direct three-tap filter applied to the 30 points and accumulated into a single double-precision register. On a CP1H this runs in roughly 1.6 ms; on a CJ2M-CPU33 in 0.4 ms.

7. Classification Logic and Thresholds

The four classes are separated by three metrics: net rise (A[29] − A[0]), SSCS, and the maximum single-step delta:

Class net rise SSCS max_step Action
Ideal ≥ SETPOINT·0.9 ≤ SSCS_OK ≤ SETPOINT·0.20 Pass
Leaking < SETPOINT·0.10 ≤ SSCS_OK ≤ SETPOINT·0.20 Rework
Blocked ≥ SETPOINT·0.5 ≤ SSCS_OK > SETPOINT·0.30 Reject
Stripped any > SSCS_OK any Scrap

SSCS_OK is calibrated by recording 50 good parts, computing the SSCS distribution, and setting the threshold at mean + 6σ. A typical value at 5 Hz sampling on a 50 L/min full scale is SSCS_OK = 0.45 (L/min)². The 0.20/0.30 spike ratios are dimensionless and stay valid across part numbers when flow is normalised to setpoint.

The blocked-unit detection must be tested with a step response that physically cannot occur in normal operation. A 30 % jump in a single 200 ms sample on a flow circuit with significant fluid inertia is unrealistic; consider using a slower sampling period (0.4–0.5 s) or adding a 3-point moving-average filter on the input if false-positive block flags occur.

8. CX-Programmer Implementation

CX-Programmer is the IEC 61131-3 programming environment for the CJ, CP, and NSJ families, supporting ladder, structured text, and function blocks. The classification logic is best held in an ST function block so the statistics, thresholds, and pass/fail decision can be moved between projects intact — CX-Programmer’s program-comparison feature will then highlight which thresholds changed when comparing two recipe revisions.

The FB takes the 30-point array as an ARRAY[0..29] OF REAL input and exposes the result as a structure output:

FUNCTION_BLOCK FlowClassify
VAR_INPUT
    Y : ARRAY[0..29] OF REAL;   (* scaled flow samples, L/min *)
    Setpoint : REAL;            (* recipe target, L/min *)
    SSCS_OK  : REAL;            (* linearity threshold *)
    END_VAR
VAR_OUTPUT
    NetRise  : REAL;
    SSCS     : REAL;
    MaxStep  : REAL;
    Class    : INT;             (* 0=Ideal 1=Leak 2=Block 3=Strip *)
END_VAR
VAR
    i : INT;
    sscs_acc : REAL;
    step     : REAL;
END_VAR

NetRise := Y[29] - Y[0];
SSCS    := 0.0;
MaxStep := 0.0;

FOR i := 0 TO 27 DO
    sscs_acc := sscs_acc + (Y[i+2] - 2.0*Y[i+1] + Y[i])*(Y[i+2] - 2.0*Y[i+1] + Y[i]);
END_FOR;
SSCS := sscs_acc;

FOR i := 1 TO 29 DO
    step := ABS(Y[i] - Y[i-1]);
    IF step > MaxStep THEN MaxStep := step; END_IF;
END_FOR;

IF SSCS > SSCS_OK THEN
    Class := 3;                                 (* Stripped *)
ELSIF MaxStep > 0.30 * Setpoint THEN
    Class := 2;                                 (* Blocked *)
ELSIF NetRise < 0.10 * Setpoint THEN
    Class := 1;                                 (* Leaking *)
ELSE
    Class := 0;                                 (* Ideal *)
END_IF;
END_FUNCTION_BLOCK

The FB is called once on the rising edge of TEST_DONE. The result Class is written to D300 and displayed on the HMI through a numeric indicator tied to a message table.

8.1 Ladder glue

The ladder that surrounds the FB has four rungs:

  1. Reset TEST_RUN on operator “Start” and clear D200…D229.
  2. Run TIMX 0000 #200 with its contact driving an INC on the sample index.
  3. On Index=30, raise TEST_DONE and call the FB instance FlowClassify_0.
  4. On FlowClassify_0.Class change, route the part with MOV to one of four reject gates (P_1, P_2, P_3, P_4).

Using the FB once per cycle keeps the cycle-time impact under 5 ms on a CP1H and under 1 ms on a CJ2M-CPU33.

9. Threshold Tuning Procedure

SSCS_OK and the spike ratios must be tuned against a known-good population. The procedure below is the field-validated sequence used to bring a new part into production:

  1. Build 50 good parts. Run the recipe and record SSCS, MaxStep, and NetRise to a CSV on the HMI SD card.
  2. Compute mean and σ for SSCS. Set SSCS_OK = mean + 6σ.
  3. Compute the 99th percentile of MaxStep / Setpoint across the 50 parts. Set the blocked threshold at the 99th percentile rounded up to the next 0.05. Typical: 0.20.
  4. Set the leaking threshold at 0.10·Setpoint as a fixed fraction; verify it is below the lowest acceptable ramp on the good population.
  5. Inject 10 deliberately bad parts per failure mode (blocked, leaking, stripped) and confirm 100 % classification.
A threshold that yields < 100 % detection on the bad sample set, or < 99 % acceptance on the good sample set, is wrong. Do not deploy.

10. Verification and Diagnostics

Verification consists of three checks per shift:

  1. Static check: short the analog input to 5.000 V; the FB must report Leaking with NetRise = 0.0.
  2. Step check: apply a 0 V → 8 V step; the FB must report Stripped because the second derivative of a step is a delta at the transition.
  3. Reference run: run a calibrated orifice plate; confirm Ideal class and that NetRise / Setpoint is between 0.95 and 1.05.

A live HMI page should expose SSCS, MaxStep, NetRise, and Class as numerical indicators. On a NB7W-TW01B or NS5 panel this is four numeric displays and a status indicator; the status indicator maps Class 0…3 to the colour-coded messages shown in the table in section 7.

11. Cycle-Time and Memory Budget

CPU FB execution time Data memory used EM banks touched
CP1E-E30DR-A 4.8 ms 248 bytes none
CP1H-X40DR-A 1.6 ms 248 bytes none
CJ2M-CPU33 0.4 ms 248 bytes none
CJ2H-CPU68 0.18 ms 248 bytes none

The 30-point REAL array plus the FB’s working variables occupy 248 bytes, well within the DM area of any CJ or CP CPU. The recipe thresholds add another 32 bytes per part number. For 200 recipes on a CP1E-N40DR-A, store the thresholds in the DM Area (D00000…D19999); on a CJ2M, the recipe set is more conveniently placed in the EM Area bank 0 with a bank-switching task.

12. Common Failure Modes and Remedies

Symptom Likely cause Remedy
Every part flagged Stripped SSCS_OK too tight or analog noise > 1 % Add a 3-point moving-average filter on D100; recompute SSCS_OK on filtered data
Blocked false positives on a steady ramp Sampling period too short, capturing electrical noise as a step Increase TIMX preset to 0.4–0.5 s, halve N if window must remain 6 s
Leaking flagged on good parts with low setpoint 0.10·Setpoint is below the resolution of the meter Use a fixed floor in L/min (e.g., 0.5 L/min) below the meter’s smallest reading
Class changes between two good parts with identical recipes SSCS_OK computed on a sample set with outliers Use median + 4·MAD instead of mean + 6σ when the population is < 30
Cycle time exceeded on CP1E FB inlined in ladder instead of a real FB Wrap the algorithm in a FUNCTION_BLOCK; CX-Programmer will produce tighter native code

13. Extension: Adding Goodness of Fit (SSE) When Stripped/Blocked Ambiguity Persists

If the spike ratio and SSCS still confuse blocked and stripped parts on a new product, add the SSE test from section 5. The FB grows by ~80 bytes and 0.3 ms on a CP1H. Use it as a tie-breaker: a Blocked call from the spike rule is upgraded to Stripped when SSE > 3·SSCS_OK. The Anscombe quartet is the textbook reminder that the regression line alone cannot disambiguate curves that differ in shape but share first- and second-moment statistics — the SSE / SSCS combination is what makes the four-class decision robust.

14. Comparison to Pure Ladder Implementation

A ladder-only implementation of linear regression on a CP1H is feasible but requires at least 60 rungs of ADD, MUL, and DDIV instructions and consumes 18–22 ms per classification. The ST function block reduces that to a single FOR loop and is the recommended path on every CJ/CP CPU. CX-Programmer’s enhanced program comparison also tracks the FB interface and the threshold constants so a recipe change is visible in a diff view — see the product page at industrial.omron.eu/en/products/cx-programmer for the feature set.

15. Putting It Together: Commissioning Checklist

  1. Wire the analog input, set the range word for 0–10 V, and confirm D100 tracks a handheld calibrator.
  2. Build the project in CX-Programmer, add the FB, and download to the CPU.
  3. Force TEST_RUN from the CX-Programmer watch window and confirm D200…D229 are populated within 6.0 s.
  4. Run the 50-good / 30-bad calibration described in section 9 and lock the threshold values into the recipe.
  5. Run the three verification checks in section 10 every shift and log the result.

How many samples do I need for the second-derivative (SSCS) test?

A minimum of 5 points is required to evaluate one second-derivative term; the recommended buffer is 30 points at 5 Hz so the SSCS accumulator sums 28 terms, which is enough to reject a single-point spike and still detect a parabolic curve with confidence.

Why not use the correlation coefficient R² instead of SSCS?

R² is a single number that summarises a linear fit and will be high for a clean straight line, but it is also high for a tilted parabola that the SSE or SSCS would reject. R² alone cannot separate ideal from stripped parts. Use SSCS as the linearity gate and the spike ratio as the blocked gate.

Can the algorithm run on a CP1E-N14DR-D with only 2 kB of user program memory?

Yes. The ST function block compiles to about 1100 steps on a CP1E; the rest of the ladder, including the timer and the HMI handshaking, fits in another 600 steps, leaving headroom for diagnostics. The 30-point REAL array fits in the DM area without touching EM.

How do I keep the recipe thresholds version-controlled when the part number changes?

Hold the three thresholds (SSCS_OK, the 0.30 spike ratio, the 0.10 floor) in three consecutive DM words and key them off the part number. CX-Programmer’s program comparison will flag any threshold change between two project revisions so the change is documented in the recipe diff.

What is the minimum detectable flow spike on this scheme?

With 0.2 s sampling and a 0.10 L/min noise floor, a 15 % setpoint jump is reliably flagged as Blocked. Below that, the SSCS gate will read the spike as a smooth step and may call the part Ideal; if smaller spikes must be detected, lower the sampling period to 0.1 s and double the buffer size to 60 points.

Back to blog