[P.S. this can be done without the Latch/Unlatch (Set/Reset) on ff_m; I was lazy]
### Detect start of ~10s of full flow on one scan
### - I.e. rising edge of full_flow
### - Latch (Set) ff_m to 1 so rising edge is not detected on next scan
### - initialize count of measurements in sum (INT)
### - initialize sum of measurements (REAL)
### - initialize maximum of measurements (REAL)
Code:
full_flow ff_m ff_m
-----] [-------]/[---+----(L)----------+----
| |
| bad_nozzle |
+----(U)----------+
| |
+----[MOV ]----+
| [0 ] |
| [count ] |
| |
+----[MOV ]----+
| [0.0 ] |
| [sumavg ] |
| |
+----[MOV ]----+
[meas ]
[maxmeas]
### As long as full flow is 1,
### - Accumulate running sums of measurements and count of measurements
### - Look for new maximum measurement
Code:
full_flow
-----] [-------+-----[ADD ]---------------+---
| [meas ] |
| [sumavg ] |
| |
+-----[ADD ]---------------+
| [1 ] |
| [count ] |
| |
+-----[GRT ]---[MOV ]---+
[meas ] [meas ]
[maxmeas] [maxmeas]
### Detect end of ~10s of full flow on one scan
### - I.e. falling edge of full_flow
### - Unatch (Reset) ff_m to 0 so falling edge is not detected on next scan
### - Calculate average from running sum
### - Need to handle case where count is 0, to avoid divide by 0 [update: actually no; count should always be > 0 when that DIV executes]
### - Subtract to get difference between max flow and average flow
### - If difference is greater than maximum expected, then latch (set) value of 1 into bad_nozzle to indicate a problem
Code:
full_flow ff_m ff_m
-----]/[-------] [---+----(U)---------------------+----
| |
+----[DIV ]---------------+
| [sumavg ] |
| [count ] |
| [sumavg ] |
| |
+----[SUB ]---------------+
| [maxmeas] |
| [sumavg ] |
| [maxmeas] |
| |
| bad_nozzle |
+----[GRT ]-------(L)-----+
[maxmeas]
[maxdelt]
Again, the difficult part, not shown here, will be choosing when the boolean full_flow is 1, as the nozzle system may require a few ms to stabilize at full flow when it turns on, and may also be unstable as it shuts off.