7 posts in this topic

Hello!

 

Is there any FB for average value calculation?

 

I did add Value to int every secend and devide it value by passed secends. Only problem is that by the time goes on int will be full?

 

 

 

Share this post


Link to post
Share on other sites

maybe... did you check the instruction list?

and you should always post your code and expectations. (resolution, time span, accuracy...)

 

if i read this right you have a problem due summation since average is computed by:

AVG(n) = (X1+X2+...Xn)/n

it appears that you are attempting to store top side of the fraction into one variable and of course this will overflow pretty soon.

solution to not do that... note that the very next average will be

AVG(n+1) = (X1+X2+...Xn+1)/(n+1)

but this can also be written as this (isolate last term)

AVG(n+1) = (X1+X2+...Xn)/(n+1) + Xn+1/(n+1)

or

AVG(n+1) = (AVG(n)*n + Xn+1)/(n+1)

but that will overflow the same way as before due multiplication AVG(n)*n.

however this can be rewritten as

AVG(n+1) = AVG(n)*n/(n+1) + Xn+1/(n+1)

where AVG(n) is previous average, Xn+1 is the latest sample, and "n+1" is the latest sample count.

as long as you compute n/(n+1) before multiplying AVG(n), there should be no problem since n/(n+1) will grow but never exceed 1.

ultimately this will settle at some average value since limit of  Xn/n goes to zero as n goes to infinity so adding more samples will just add zeroes and average will stop changing. 

this begs question... are you really really sure you need total average over indeterminate and always increasing time interval and not average of several most recent samples? one would normally look at average only over fixed number of samples. that number can be small or large but it should be fixed.

if you really want to cover "endless" interval, you need to define what is "endless".

 

1 person likes this

Share this post


Link to post
Share on other sites

I think you are looking for the function MovingAverage. Often called a floating average. Essentially a FIFO of values that is divide by the number of values.

Share this post


Link to post
Share on other sites
On 8/6/2022 at 3:59 AM, VulpesLago said:

I did add Value to int every secend and devide it value by passed secends. Only problem is that by the time goes on int will be full?

Every time the summarizing register reaches certain threshold (the larger, the better), just divide it and the seconds by 2.
The average remains the same, the measurement resumes correctly.
The register will never overfill.

Edited by Sergei Troizky
1 person likes this

Share this post


Link to post
Share on other sites

That is a great idea... And so simple. To

Share this post


Link to post
Share on other sites

A related observation pay attention to your type of data.  An integer which is 16 bits tops out at 2^16 or 65,536.  An integer of 32 bits tops out at 2^32 or 4,294,967,296.  But a 32 bit Floating point which can represent number to  3.4028235 × 1038.  but due to it's 23 bit fractional part loses resolution after 2^23 or 8,388,608.  

What do I mean by loses resolution.  Add 0.49 to a float bigger than 8,388,608 in a PLC and nothing changes.  Add anything between 0.51 and 1.50 and it goes up just 1 count.

Stumbled onto this when our PLC Data Totalizers didn't agree with the field meter.

Share this post


Link to post
Share on other sites

The OP clearly mentioned INT.
And since this is signed 16-bit integer, it tops at (2^15-1)=+32767.
Unsigned 16-bit would top at (2^16-1)=65535.

Edited by Sergei Troizky

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now