Average value calculation

arthur.hauer

Member
Join Date
Nov 2016
Location
Paraná
Posts
34
Hi!
Currently I'm trying to implement an average calculator in a S5-95U.
In order to do the job, I'm using the folowing equation:

M(k) = M(k-1)*((k-1)/k) + V(k)/k

Where k is the sample index, M(k) is the average value for sample k and V(k) is the value of interest for sample k.
I got to this equation after contemplating the overflow problem that would be caused by simple average equation:

(V(k)+V(k-1)+...V(k-n))/k

Because this code will run for a long time, the sample count will eventually overflow.

I think calling this function periodically should do the trick. The question is: How to do this? Is there a better way to calculate the average value?

Att.,
Arthur

Post Scriptum: Sorry for bad english
 
Is that thing still used :O .. Weren't the support cut down in 2010.

Anyway you need to implement a running average with use of n last measurements and maybe some filtration ie. dropping out noise peaks etc.
Unfortunately the Step5 command and memory structure is almost faded away from my memory. You need n numbers deep stack sum it up and divide with the n. Of course you need to drop the oldest and push the rest back in stack in the right order, repeat after x amount of new datainputs (in case of x>1 you need drop more than one old inputs out from stack).
 
Last edited:
You could use a counter, and when you get to a preset move the average into a register and zero k. Then you can add the preset to k and the old average into the calculation.
 
I know nothing about the S5 except to stay as far away as possible but...
Can the S5 do 16x16=32 bit multiplies?
Can two 32 bit numbers be added together?
Can it do unsigned math? If so I have a solution, if not then no.
See Q16 format for unsigned math. Q15 format for signed math.
This methods avoids the divides and is much faster.
 
Last edited:
Exponential moving average

av = alpha x new_value + old_av * (1 - alpha)
0<alpha<1
The smaller the value the more filtering occurs.

It's a nice thought Geoff but the CPU in question does not support floating point arithmetic.

The 95U CPU is 16 bit integer only processor. There is a special function block that allows you to multiply two 16 bit words but the answer is given as two words (high and low); this can also be used to divide when you multiply by a "magic number"(divisor *256) and then take 1 256th of the result. There is also an integer divide block that gives result and remainder separately. Keeping everything within the realms of a fixed number system is quite a challenge.

If anyone is bored over Christmas, they can have a go at coding a square root algorithm for this CPU.

Nick
 
Last edited:
The S5-95U can do Floating Point math; I've got several applications that have been doing that for about 20 years now. If I remember correctly you would use the Floating Point blocks for a S5-115U.
 
The S5-95U can do Floating Point math; I've got several applications that have been doing that for about 20 years now. If I remember correctly you would use the Floating Point blocks for a S5-115U.

Sorry If I lead anyone astray. I guess I never had access to the add on package.

Nick
 
Arthur,
We are displaying machine speed by using an extended pulse timer with a value of 12 seconds. Then a count up counter counts mach revs.The flag set by the timer jumps to M1. Then the flag set by the timer is used to load the value to DB (11) and transferred to a DW(8). The jump to M2 is a NOP. Then the counter is cleared and the result is machine speed displays and updated every 12 seconds. This is all done in FB(3).
 
Thanks for all the replies!
To this day, I still didn't figure out a satisfactory way of doing this.
I'm very inclined to use Tom's hint. I guess it will take some time to work out this one.
 
Can the S5 do 16x16=32 bit multiplies?
Can two 32 bit numbers be added together?
Can it do unsigned math? If so I have a solution, if not then no.
See Q16 format for unsigned math. Q15 format for signed math.
This methods avoids the divides and is much faster.
Can you share an example?
 
Can you share an example?
When dealing with old 16 bit micro controllers I rarely divided by a constant. I would use a Q16 ( unsigned ) or Q15 signed format.
Assuming the math is signed I would used the Q15 format.
Assume I want to divide a signed number by 10.
I would multiply the signed number by 32768/10 or 3277. The 3277 is the hard coded constant. This results in a 32 bit number. Since each signed number has a signed bit the upper 2 bits have the sign and the lower 30 bits have the the next 15 bits. To get a usable result the 32 bit number need to be shifted left 1 bit. Now the result is in the upper 16 bits of the 32 bit number. The lower 16 bits are a fraction which may not be accurate, but close, because 32768 can't be divided by 10 evenly.

Multiplies are MUCH faster than divides. Divides often require a lot of shifts and subtracts so they take many cycles whereas multiplies often take just one cycle.

If the the numbers are unsigned then I would multiply 65536/10 by the other unsigned number. Now the unsigned 16 bit result is in the upper 16 bits of the 32 bit result. No shifting is required because there are no sign bits or extra sign bits.

If I multiply 65536/10 ( 6554 ) by 123 i get 12 and a fraction.

This method is fast. The only error occurs when 65536 is not divided evenly because 6554 is not exactly 65536/10.

If I needed more precision I would shift the 65536 by 4 then divide by 10. The resulting constant is 26214.4 but I would use 26215. Then I would multiply this constant by the other unsigned number but the 32 bit result right 4 times.

It is also possible to multiply unsigned by signed numbers but this get tricky.
 
If anyone is bored over Christmas, they can have a go at coding a square root algorithm for this CPU.

I remember a program for a S5 100u where the positions for a turbo compressors variable inlet and outlet guide vanes where calculated from a 3d data map stored in a datablock by interpolation.

It was using the heron method to calculate the square root. But with floating point numbers done in software, retriggering the cycle so that the S5 doesn't got in stop mode during calculation - which took about 5 seconds...
 

Similar Topics

Hi Guys! I have resently got my hands on a small project, getting data from a check weigher that speaks Modbus RTU. I want to use the ML1100...
Replies
6
Views
6,924
Hi all-- I need to create code in a Micrologix 1400 project that requires minimum, maximum and running average calculated values (Flows and...
Replies
17
Views
3,738
Hello, I'm using a counter as a timer to get a time value to get the current cycle time and last cycle time. I need to put this "last cycle...
Replies
3
Views
2,792
I'm thinking about how to help a customer tonight and I've got an idea, but I don't know if it's possible. I've used the Data Logger on a Red...
Replies
2
Views
3,051
Hi, I want to find the moving average of the FTviewSE trend. Since it's not a built-in feature, can anyone help me with this, maybe using VBA...
Replies
3
Views
2,704
Back
Top Bottom