
Cache450 (Customer) asked a question.
flow totalizer from 4-20ma signal in productivity?
Is there a good way to create a flow totalizer in the ladder logic of productivity by using a 4-20ma signal?
I have a flow meter feeding me a 4-20ma signal but I want to have a readout of total flow from the last hour and from the last 24 hours. Is there an easy way to do this in the productivity suite?
Are you already using the "scale" instruction to get your units from raw counts into a unit of measure you want to work with like gpm? If not, that should be where you start.
For storing the data, I would do something like move (shift/rotate array) the current flow value into an array at a specific interval (second or minute). Then use "array statistics" to get the sum of all your stored values.
You can also do something like have 3 arrays. Use the first to move the current flow rate into it every second. At the minute mark, do an array statistics instruction on that first array and find the average flow rate for the past 60 entries. Store the result in a second array. At the hour mark, do an array statistics on the second array and find the sum of the previously stored hours data. Display this so you know how much your last hour flow was, and also move the data into your third array. Each new day (hour = 0, minute = 0, second = 0 contacts), do an array statistics on the third array to find your sum for the whole previous day.
By feeding the average flows from each second into the array calculations it will probably be more accurate to the true amount.
You can sample at a periodic interval and scale that accordingly to add to your total, it will likely have some drift but 24hrs wont be terrible.
To get volume one would need to integrate flow over time, periodically adding the "current" flow to the total is straightforward way to do that. However if the period is too long, then the "current" flow may not accurately tell you what you want to know it the flow has any rapid variations.
You don't say what input module you are using, but a P1-04ADA-1 has an all channels update of 10mS
this could be several PLC scans with a not so large program, but with a rather lager program the two might be close-ish? In the latter case I'd add the flow to an accumulator every scan, and increment a counter, (I might do it every scan, for simplicity, even with a short program even though I'd be using the same sample multiple times) Then, at a fixed period (say a second or perhaps minute?) , calculate the average for the last period and add that to my total (and reset accumulator and counter for next period) This should maximize granularity while minimizing timing issues (I think)
As was previously answered, you would need to create a tag that is scaled for the time interval that you would log the total. I would use the leading and trailing edge of the one second bit to trigger math, where I would add the instantaneous flow to the total flow and store it in the total flow. Your flow amount would have to be scaled into units per second. The one second bit is on for one second and off for one second. Using the leading and trailing edges of it to trigger the math provides a consistent one second interval.
As recommended, always try to use a timed interrupt or system bit for optimal timing accuracy, and one second intervals are often plenty fast enough.
Also, have a tag for "low flow cutoff". You don't want to be totalizing when everything is stopped but the analog signal varies enough to generate a value that amounts to a trickle. If the calculated flow rate is below that cutoff level, don't execute the totalizer.
Also, it can be problematic to accumulate large totals using floating point numbers. Depending on the range that your long term total needs to be able to reach, it can be useful to accumulate using a float up to 1000 or 10,000 units of measure, then add 1 to a Long integer and subtract the 1000.0 or 10,000.0 from your temporary float. This will let you have a long term total that can roll over at several billion units of measure rather than a float that may lose accuracy when it gets into the millions.
If you don't need long term or large value totals, then you may not need to worry about that extra step, but if you do, it can be useful to never zero out that total, just store it at the same time every day as "yesterday total" and for today's number, subtract it from the long term total.
Wow you guys are awesome. Thank you for the suggestions. There has been a learning curve here for me as I have never used an array, after a few revisions of programing I think I have come up with a solution.
I want to make my totalizer as accurate as possible while keeping the program somewhat simple.
Please feel free to critique my solution.
solution #1:
my first solution was to use the second bit as an edge contact which would fill a (shift/rotate) array once a second with the current GPM flow reading (scaled from raw readout)... then using a few array statistics I pulled the data I needed for minute and hourly readings
--but I couldn't stop there I wanted more accuracy--
solution #2:
(right or wrong this is what i did, please tell me if its no good.)
First off I made a huge array tag with 10,000 columns (for testing) and used it with a shift/rotate array (with one-shot turned off) so that my readings could free flow into the array. I did this so that i could see how many readings I would get in a minutes time. after several runs I consistently got around 1100 readings per minute.
so I took that info and knowing that the size of my program might increase in the future (thus slowing down my readings?) I decided to use only 900 samples per minute (15 samples per second) for future safety of getting true totals.
In my next line I used the 1 minute bit to activate an array statistics to pull the "average" for columns 1-900 thus giving me the true GPM (for the last minute of time) since the samples going into the array are already scaled to GPM.
does that give me a good reading? whats your thoughts?
beyond that, to take it further and give me hourly and daily readings this is what I did:
I did a second edge contact(1 minute bit) to activate the second shift/rotate array... it gets its input from the first "array stats" output. So, this second array is getting its columns filled with 1 minute averaged readings, accumulating all day. Therefore i can pull "array stats" from it, for the last hour or last 24hrs, whatever I want.