Calculating a running average?

fluxcapacitor

Member
Join Date
Oct 2021
Location
Michigan
Posts
1
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 = AvgValue + (NewValue-AvgValue)/NumSamples

but it would only work in this case if I reset it every 5,000 samples, which is not what I want to do.

The only way I can think of doing it is to use a FIFO, although BOOL isn't a valid parameter for a FIFO. Even if it was, using an array of 5,000 elements seems highly inefficient, especially since I'd have to do it for about 20 stations on the PLC.

Any ideas?
 
bit shift left, BSL in A-B (or right, BSR) is a fifo for bits, and only requires an array of 157 32-bit integers or 313 16-bit integers for 5kbits.

  • Keep a running total of the number of 1 bits in an array
  • Initialize the running total and the array elements to zeros,
  • Every time there is a new part with its pass/fail bit, there should be a rising edge somewhere
  • Use that rising edge to trigger the BSL to shift the pass/fail bit into the array, and get the 5000th oldest bit back out
  • add 1 to the running total when shifting a 1 bit into the array,
  • subtract 1 from the running total when shifting a 1 bit out of the array.
  • Divide the running total by 5k, or 50, to get the fractional, or percentage, yield, respectively.
If you have to do this many times, use an AOI.
 
Yes.

This is a problem solved by a circular buffer. No shifts, sorts, or any other work needed.

A few simple adds, subtractions, and a divide are all that’s necessary.

You start with a zero-population array of X capacity.

With each new data, N, you increase the element count Y and separately keep a running sum, Z.

Divide Z by Y to produce a running average, A.

Once X equals Z, you insert a new element by returning to index 0, subtracting the value N[0] there from Z, assigning N[0] the new N, compute new A. Repeat for N[1], and so on.
 
I agree with JeremyM that a circular queue should be used. However, 20 circular queues if 5000 parts is a lot of memory.
A compromise would be to make the circular queue 500 long and sum the number of passes for 10 parts before putting sum of 10 passes into the array. Since the sum will only be as high as 10 you should be able to use 16 bit WORDS. You will still need a sum of all the passes in the circular queue.
 
Circular queue is more efficient and I would usually go that way, but I am pretty sure that BSR approach will need fewer instructions, and will read cleaner/better. Not that circ. queue is that complex, to be fair, this will be done in an AOI with a UDT, or equivalent if not A-B.



If you want to update pass/fail on every part at every station, then 20 stations by 5000 parts per station is 100kbits or ~3k LONGs, so 12kB no matter how you do it.


As @Peter Nachtwey says, if you are willing to update less frequently, then there are ways to reduce memory usage.

But memory and CPU are cheap, so KISS.
 

Similar Topics

I have a vibratory conveyor that is being fed from another conveyor. The feeding conveyor does not always deposit a consistant flow of "product"...
Replies
14
Views
5,267
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,366
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,833
I would like to refer to this document of which I used some data ...
Replies
1
Views
1,481
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,101
Back
Top Bottom