Calculating change-over-time for slow process variable

ryangriggs

Lifetime Supporting Member
Join Date
Jun 2016
Location
USA
Posts
193
TLDR; What's a simple way of generating a "change-over-time" value, indicating the amount of change in a process value over a specified time interval?

Hello, I recently built a control panel with PLC which runs a tank-filling routine (water tank). The routine turns on a pump when the tank level falls below a low-level setpoint, and then turns off the pump after a high-level setpoint is reached. The drain/fill cycle is slow, and may take several hours to complete.

The tank uses a standard 4-20mA pressure transducer and calculates the level based on the standard PSI-to-feet water column conversion.

Recently, however, the line feeding the pressure transducer sprang a tiny pinhole leak, reducing pressure to the transducer and causing it to report a half-full tank when it was actually full and overflowing.

I thought it would be wise add a safety mechanism that determines whether the level is actually changing. For example, I want to implement the following logic:
If the pump is running, and the tank level has not changed by at least X inches in X minutes, throw an alarm to alert the user of the possibility of a problem.

Does anyone have a boilerplate example of tracking the change in a process variable over a specified time window? For example, how much has the level changed in the last 1 hour?

I really hate to create an entire table of historical sampled values, as that seems to add a huge amount of complexity.


The simplistic answer would be to simply sample the level value at the specified interval and compare to the past sample. However, this would ignore large changes/spikes between the sample periods.

I'm thinking a moving average may be the answer, but doesn't it require a reset periodically? I was hoping to hear from someone who has already written a similar algorithm or who has a simpler method.


References:
Simple Running Average: http://www.plctalk.net/qanda/showthread.php?t=19066
Hourly Average: http://www.plctalk.net/qanda/showthread.php?t=17831
Calculating moving averages: https://stackoverflow.com/questions...rage-without-keeping-the-count-and-data-total
Exponential moving averages: https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
and https://stackoverflow.com/questions/10990618/calculate-rolling-moving-average-in-c/10990656#10990656








Thanks for any advice.
 
Last edited:
The rate of change of level is ( inflow - outflow )/area. If you know both the inflow and the outflow you can predict, estimate, the rate of change in level. If the actual change in level does not match the estimated change in level within some bounds then you know you have a problem.

You know what the inflow should be but you don't mention the outflow. If you don't know the outflow there isn't a away to estimate the rate of change in level.
 
@Peter - I don't have access to a rate of inflow or outflow. All I have is access to a tank level value. From this, I need to calculate the rate of change, so I can compare with the desired minimum rate of change specified by the operator.
 
Best you can do is use the information from the pump curve to determine how much volume the pump pumps. That value used together with a timer/counter to grossly estimate how much volume SHOULD have been pumped into the tank vs what has actually been pumped given by the pressure sensor.
I would imagine this could work marginally well for filling the tank, although will probably require some hysteresis.

You would basically be giving an alarm based on theoretical vs actual pump efficiency. Less than 80%? Less than 60%? Without the actual flow of what’s going in and out, it’s a **** shoot.
 
I think I must have expressed the question badly... sorry about that. I think everyone is missing the point of what I'm actually asking.



I don't care about how much the pump *should* transfer in a given time. That's outside the scope of this question. All I want to do is calculate an approximate "rate of change" value based on the tank level, and keep this value up-to-date, so that at all times, I can look at this value to determine how much the level is changing per (minute/second/hour/other unit of time).



Is there a simpler algorithm than storing an array of previous values to generate a calculated rate-of-change value?


For example, I want to output a value that indicates "the tank level is currently changing at approximately 2.5 ft per hour."



One way I could do this is to set a timer to expire once per hour. Each time the timer expires, I could subtract the current level value from the previous one, then overwrite the previous level with the current one. This would give me a "rate of change" over that hour, but would only look at two snapshots. I would prefer to have an "averaged" rate of change with a sample taken every minute, but I don't want to store the 60 sampled values in an array.


Hopefully this clarifies the question. Most basic form of my question: "how to calculate reasonably accurate rate-of-change over a specified period without storing lots of values in an array".


Thanks!
 
Last edited:
causing it to report a half-full tank when it was actually full and overflowing.

I thought it would be wise add a safety mechanism that determines whether the level is actually changing.

For the stated problem, a faulty continuous level sensor that causes an overflow, the conventional industry solution is a high limit point level switch using a different technology than the primary continuous level sensor.

Be my guest doing some rate of change calc, but there are commercial solutions available.
 
Last edited:
There is a Rate of Change alarm inside the ALMA instruction, both +ve and -ve, which is %/s in a given period (s)

For simplicity, you could monitor this for NOT alarm, when your pump is running.
 
MAVE block in Logix 5000?
only Function Block or Structured text, but does the job. Yes, you need to store N samples of data for a MAVE.

If not logix 5000, here is a moving average algorithm in structured text syntax.
https://github.com/simsum/oscat/blob/master/FILTER_MAV_W.EXP

Alternative to a MAVE is a single order low pass filter:

Code:
// execute at a fixed period.  smaller k = longer filter time.
Filtered level change := Filtered level change + k * instantaneous rate of level change;
 
So you're looking at a weighed average? If you calculate your rate of change once a minute and add that to a weighed average consistently and map both current level and the weighed average side by side you should get a trailing or lagging value effect where if something changed rapidly it will leave a trace behind it until it settles at a stable value.
 
If you want to pursue your rate of change solution then you'll need a fairly accurate level transmitter. For example, if your rate of change per hour is 2.5 feet / 60 samples per hour = 0.041 feet per minute. If your rate of change was 1 foot per hour then that would be 0.016 feet per minute. I would guess that your level sensor isn't that accurate, so a sample rate of 10 minutes would probably be better. 2.5 feet / 6 samples per hour = 0.41 feet per 10 minutes or 1.0 feet / 6 samples per hour = 0.16 feet per 10 minutes. The basic equation is (current level - previous level) * samples per hour.

But there is a simpler and probably more beneficial solution to the problem. Put current runtime meters on the tank's request for lead and lag and on the pumps themselves. Then you add an alarm to the current runtime meters called High Runtime. So if it generally takes 4 hours to fill the tank then the operators could set the High Runtime alarm for 5 or 6 hours. You can also give the operators a previous runtime reading.

Going with a High Runtime alarm is simple to implement, simple for the operators to understand and gives additional beneficial information.

TankMeters.JPG
 
For the stated problem, a faulty continuous level sensor that causes an overflow, the conventional industry solution is a high limit point level switch using a different technology than the primary continuous level sensor.

The above is the correct way to address your problem. Alarm and interlock off both sensors as necessary.
 

Similar Topics

This application has a motor with encoder feedback that drives a linear actuator that moves in/out, and is at roughly 45 degs from horiz. As the...
Replies
19
Views
1,296
I need to keep a running pass/fail yield of the previous 5,000 parts produced. I have used this formula before to calculate average: AvgValue =...
Replies
6
Views
2,113
Does anyone know how to calculate the savings from now needing to run an air compressor all day? Basically I have a design that replaced 6 * 1"...
Replies
26
Views
4,747
I would like to refer to this document of which I used some data ...
Replies
1
Views
1,450
Seems like this should be a simple thing but I’m struggling with it. The basis is that I am trying to detect if a linear assembly is stopped or...
Replies
6
Views
3,048
Back
Top Bottom