moving average/rolling average
Hi,
I searched the OBEX and this forum for a simple five sample simple moving average routine. I found one object that was way off the deep end for complexity. I would think some clever trick with absolute address space may be in order but I've never tried that yet with the Prop. Thoughts?
I searched the OBEX and this forum for a simple five sample simple moving average routine. I found one object that was way off the deep end for complexity. I would think some clever trick with absolute address space may be in order but I've never tried that yet with the Prop. Thoughts?

Comments
pub newaverage(newvalue) | idx samples[samplepntr] := newvalue if (++samplepntr == 5) samplepntr := 0 result := 0 repeat idx from 0 to 4 result += samples[idx] result /= 5error := SomeValue
Darray[2] := error - PrevError
Daverage := (Darray[0] + Darray[1] + Darray[2])/3
PrevError := error
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 #1, HOME, #8, BKSP, TAB, LF, CLREOL, CLRLB, CR, #16, CLS ' PST formmatting control ORDER = 4 ' length of moving average OBJ Sio : "FullDuplexSerialPlus" VAR long values[ORDER], sum, newValue, avg byte index Pub Main | i Sio.start(31,30,0,115200) ' Rx,Tx, Mode, Baud repeat until Sio.rxcheck <> -1 ' wait for PST Sio.str(string("Enter a value: ")) ' initialize with first value newValue := Sio.GetDec sio.Dec(newValue) Sio.tx(CR) sum := ORDER * newValue avg := sum / ORDER repeat index from 0 to ORDER - 1 values[index] := newValue Display repeat newValue := GetValue index++ ' update value of index index //= ORDER sum -= values[index] ' remove oldest from sum values[index] := newValue ' insert new value in list sum += newValue ' add new value to sum avg := sum / ORDER ' calculate average Display PRI GetValue ' get the value Sio.str(string("Enter a value: ")) result := Sio.GetDec Sio.Dec(result) Sio.tx(CR) PRI Display | i repeat i from 0 to ORDER - 1 sio.dec(values[i]) sio.tx(TAB) sio.dec(sum) sio.tx(TAB) sio.dec(avg) sio.tx(CR) {{ ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ │is furnished to do so, subject to the following conditions: │ │ │ │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ │ │ │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ }}John Abshier
pub ma4(x_meas):x_ret ''4-sample moving average filter, implemented with recursion. ''Max filter update rate ~13000 samples/sec for 1 cog @ clkfreq=80 ptr &= %00000011 'mask off all but lower two bits sum := sum + x_meas - x_buf4[ptr] x_buf4[ptr] := x_meas x_ret := sum ~> 2 'divide sum by 4 ptr++ pub ma16(x_meas):x_ret ''16-sample moving average filter, implemented with recursion. ''Max filter update rate ~13000 samples/sec for 1 cog @ clkfreq=80 ptr &= %00001111 'mask off all but lower four bits sum := sum + x_meas - x_buf16[ptr] x_buf16[ptr] := x_meas x_ret := sum ~> 4 'divide sum by 16 ptr++ dat '-----------[ Predefined variables and constants ]----------------------------- x_buf4 long 0,0,0,0 '4-place filter input history buffer x_buf16 long 0,0,0,0,0,0,0,0 '16-place filter input history buffer long 0,0,0,0,0,0,0,0 sum long 0 ptr byte 0 'pointer (set up as ring buffer)I will need. THANKS!!!
I won't have it in the EEPROM until Friday. I'll be able to see the effect on the tachometer DRO on the commute to work on Saturday. Switching to cat 5 cable and tightening the connections to the breadboard already killed some of the display jitter. jw_freqin is working well at 5 samples per second.
Stan
As spoon-feeding is demanded, let the spoon-feeding begin.... <grin>
The attached demo uses PST to display the array values as well as the average. The display is refreshed after each new entry.
Way cool! I now have two data streams to smooth because this evening I got the programmable speedometer read out working in concert with the tachometer. 90% of the software is the same. The breadboard and coding stage of the project now stands at 50% complete.