sonar.ping_median(iterations [, max_cm_distance]) - Do multiple pings (default=5), discard out of range pings and return median in microseconds. [max_cm_distance] allows you to optionally set a new max distance.
sounds like this already filters out extreme values (i.e. median filters).
not sure how a 5-pt median filter can be applied to sample set of 5 samples. it would result in one value, the median value of the 5 pts or 5 samples with the same value.
the resulting one value if then averaged with the value from the preceding measurement cycle.
here's a log10 histogram of the sample-to-sample variation.
there were ~10^3 (1000) samples that had < 0.01 variation and the same # of samples between 0.01 -0.02.
~3 (10^0.5) samples between 0.10 - 0.15
and trending upward > 0.15 variation
so maybe any measurement > 0.15 should be ignore or repeat the measurement until < 0.15
an N-pt median filter results in the median value of the last N samples. a 3-pt filter would ignore a single sample that is extreme. a 5-pt filter would ignore 2 consecutive extreme samples.
and filtering is generally applied to samples collected periodically.
i hope you see that a median filter of these 5 samples is one value, their median value, let's call is a super-sample. of course the median value can also be taken of the last 5 super samples
(i'm guessing that a piece of garbage can affect all samples collected in a 15 second period)
but it seems you collect samples in bursts (see histogram) a number of samples are collected in a short period of time from which a single value is determine that is then filtered again.
but even the sampling bursts don't appear periodic.
it's not clear why you don't just collect a sample or even a super sample consistently once every minute, for example
That's the code? Is something fudging with TIMEOUTDELAY to make it non-constant in the 10-800sec range?
You have noisy data in both measurements and timing, If you carefully train your filter to get all the garbage out on this set, it might behave unexpectedly when the weather isn't calm.
Here's a plot of your raw data (green) from post #20 compared with a plot (orange) that just limits the change to ±0.02 and averages the previous 8 samples.
Needs a true circular buffer that controls the head/tail indexes and reads correctly (or fix some other issue), then we can avoid this (and others). Might be some other issue, but too busy right now - might get a chance to take another look at this later...
I think the median lpf is a good one. You might consider implementing both with unsigned integers instead of floats. Comparison (in your sorting algorithm) and division will be way faster (especially if you divide by some power of 2 (i.e. 8).
The leaky integration van also be implemented that way:
avg = (meas + 7* avg + 4) / 8;
The compliler will implement this as 3 bitshifts. The 4 is there to get the rounding right.
It also saves ram (not really problem with 5 pt. median, but considerable saving in n = 32 moving average).