Creating an Average Value

sparkytex

Lifetime Supporting Member
Join Date
Jun 2013
Location
Port Hardy B.C.
Posts
354
hello,

I would like to create an average value of a specific address, which in my case is production rate of our bleach plant. I would like to average the value F8:80 over 30 seconds. Is there an easier way to do this rather than using up 30 address's with the "AVE" instruction. Or rather than using the FFL and every second for 30 seconds loading the F8:80 into the 30 different addresses then adding them all up and diving by 30. Just looking for an easier way.

thanks, Tex
 
Yes, you could use 1 address. Starting at Time = 0 seconds reset old AVG memory location, then after 1 second, add Production Rate Input to AVG. Each subsequent 1 second, repeat ADD Rate Input to AVG. At Time = 30, Divide AVG by 30, then Move Result to AVG1, then repeat cycle.
 
I guess I should have been more clear, I need to make a moving average over 30 seconds of the production rate. this complicated things more! any help is appreciated!
 
I guess I should have been more clear, I need to make a moving average over 30 seconds of the production rate. this complicated things more! any help is appreciated!

What PLC are you using? Check to see if it supports the COP instruction (most do).

A "rolling average" is simple, but you will need to store the last nn "samples"...
 
Using rslogix 5, I do have the cop instruction.

OK, you will want to create a new floating point data-table, 30 elements long. let's say you use F20:0 to 29.

Each time you "sample" your production rate in F8:80 (once per second ?), use a COP instruction to shift the data through the F20 storage file.

If you try to do this by copying F20:0 to F20:1 for a length of 19, it will fail, because the COP first copies F20:0 to F20:1, then F20:1 to F20:2, and so on. You will end up with the whole file as a copy of the data in F20:0.

The trick here is to copy it "backwards", F20:1 to F20:0 for a length of 19. After the COP, place your new value in F20:19.

Now use AVE to average the file F20:0 to F20:19, and you have your "rolling average".
 
I guess I should have been more clear, I need to make a moving average over 30 seconds of the production rate. this complicated things more! any help is appreciated!

I don't see how that complicates things. An average is always the sum of a set of values divided by the number of values.

What you really need to check for is if your controller supports the AVE instruction. Of so then your job is just managing moving your samples in and out of a file for the AVE instruction to take the average of.

If you don't have the averaging instruction then you will also have to do the adding and dividing as well.
 
See this thread

http://www.plctalk.net/qanda/showthread.php?p=260919#post260919

for two examples, one using a FIFO queue and one using a circular queue where a rolling total is kept to avoid the need to sum the entire queue each time. The circular method implements the queue without moving any data around.

The example was created in Logix500. If you can't open that then get back.
 
Last edited:
I will not be able to use your method Tconnolly, I do not have the L9 (long Int) data file created on that PLC, which means I'd have to put the PLC into program mode to create it. I've also never seen this data file before!?
 
here's what I did,

I took F8:80 which is the raw un-averaged production rate and moved it into
F15:69.

I used a COP instruction with source as F15:11 and destination as F15:10 and length of 60 elements which is triggered once every second by a timer.

I used an AVE instruction with file as F15:10 and with the length as 60 elements and destination as F15:71, control R6:1.

so the COP instruction is always moving the current number into F8:69 every second then moving it "down the line" so to speak. Then the AVE instruction just takes the average of all 60 Floating Points and stores it into F15:71. Thus getting a 60 seconds moving average of the production rate.

It seems to be working, but is this method correct? I did it this way as it seemed to be the easiest way for me to accomplish this, keep in mind I am a programmer in training.

Thanks for everyone's help to I'm very grateful!!
 
I think you should trigger the process by having received a new data point, not by time. If by time, after 60 seconds, the entire array would be populated with your last reading - not really desirable, I would think. Maybe I'm wrong.
 
This subject comes up often enough with PLC/5s that I converted the method I linked above to a PLC/5. It is attached here for future reference.

For small queues the COP and AVE method is simple, easy to understand and program and I recommend it. For averages of a large number of samples the methods shown eliminates the need to sum the entire long series every time and the circular method eliminates moving large blocks of memory around.
 

Similar Topics

I want to monitor the cycle times of some of our stations (the process, not the CPU cycle time). We had a case recently where throughput was down...
Replies
6
Views
4,064
The idea here is to provide for a brief rapid influx of message codes while preventing sequentially repeating the same message. i.e. if two...
Replies
23
Views
675
Hello everyone, In a factory where we installed Citect 7.20 the computer began to show the first signs of end of life. They never considered...
Replies
0
Views
73
Hi everyone, I'm a last year student at the university in Ghent, and for my thesis i need to write a TwinCAT program that writes data to a .daq...
Replies
0
Views
141
When I go to create a new module in Studio 5000 I can't enter any information for the IP Address or change any other fields. Is there any fix to...
Replies
1
Views
253
Back
Top Bottom