![]() |
|
|
This function will keep a running average a fixed point input on an FPGA target. The code utilizes feedback nodes to keep track of 1)How many samples have been taken and 2)The running sum of all values taken. There is also a reset boolean which will reinitialize both the counter and the running sum to zero.
In order to allow a large range of values and a large sum, the fixed point values for this example are set up with 64bit word length and 32bit integer length. You may need to adjust these values based on your specific applications to account for how long the averaging function must run. If you are only averaging a small amount of numbers (<1000), smaller fixed point allocation will conserve FPGA space.
Data should be passed to this code as a Fixed-Point Scalar. In order to get the average of an array, pass the array through a For Loops and autoindex it, this will automatically run each element of the array through the code. These values are stored in Feedback Nodes which contain 1)Current total sum of all values passed since last reset and 2)Iteration counter. Keep in mind how large the data types have to be to store your application data. When the 'Reset' is TRUE, a zero constant is passed to the total sum, and the iteration count passed is one in order to prevent dividing by zero. This one, however, is not passed to the feedback node since this would offset all future averaging functions, and a zero is still passed to this so that on the next count we do the averaging function: (0 + current value) / (0 + 1) = (current value) /(1). The next iteration would give (Last Value + Current Value) / (1 + 1) = Average of 2 numbers, etc.
Instructions:
1)Set input to any value, lets say 5
2)Run vi once, Running Average will indicate 5
3)Change input value to 10
4)Run vi again, average is now 7.5
5)Once you are done testing, set reset to 'True'
6)Running vi will now reset all values to 0, and
averaging will begin with next sample taken
while reset is False.
If you wish to have a quick running total, you can
test the VI with the code in a while loop with a wait
of 500ms, that way you can update the input
real-time and see the running average update quickly
This Vi can easily be made into a subvi for direct use in code, highlight the entire code, go to Edit->Create Subvi.
Be sure to reset the count whenever you are done calculating the average!
11/17/2008: Changed the code as per User Suggestion: Removed While loop and Shift Registers, replaced with feedback nodes. Removed second case structure for testing if dividing by zero, and used a 1 to start division rather than a zero.
Great Suggestions, Christian. I implemented the feedback nodes for functionality in timed loops, and a modified counter to eliminate a case structure. Next step will be to keep a running average of the last X elements.
I would eliminate the While loop and use Feedback nodes instead. This would allow the code to be run inside of a Single Cycle Timed Loop.
In addition on Reset I would set the counter to 1 (instaed of 0) and use the current input value as the sum, thereby eliminating the need for a special case to handle division by 0.