stevieb has asked for the wisdom of the Perl Monks concerning the following question:
Hello there fellow Monks!
I'm here once again to ask for a review of some mathematical code that I'm working on. I want to see if this is a reasonable approach to the problem I'm facing.
I'm building a grow environment controller which is working great, but I periodically get a spurious reading from the hygrometers.
To help combat this, I've implemented an exponential weighted moving average routine on the sensor's readings, but now I want to proceed further, and before running the EWMA, I want to literally remove any erroneous readings that are +/- 15% of the average of the last 10 readings.
Although this code will be translated into C++ code, I prototype in Perl first, and below is my quickly written testing code. It seems to work quite well, but I'm hoping our mathematicians can have a look at whether there are better or more efficient/reliable ways to do what I'm hoping to do.
use warnings; use strict; use feature 'say'; my $limit_percent = 0.15; my @nums = ((75) x 5, 99, (75) x 4); # 10 numbers filtered(\@nums); for (qw(75 74 75 90 74 75 7)) { # shift off oldest number, push the next new one shift @nums; push @nums, $_; say "Added: $_"; filtered(\@nums); } sub filtered { my ($nums) = @_; my $sum; $sum += $_ for @$nums; my $avg = $sum / scalar @$nums; my $range_limit = $avg * $limit_percent; my @filtered_nums; for (@nums) { if ($_ > $avg + $range_limit || $_ < $avg - $range_limit) { say "Removing: $_"; next; } push @filtered_nums, $_; } my $filtered_avg; $filtered_avg += $_ for @filtered_nums; return if ! scalar @filtered_nums; $filtered_avg = $filtered_avg / scalar @filtered_nums; printf( "Filtered %.2f, Avg %.2f, Limit: %.2f\n\n", $filtered_avg, $avg, $range_limit ); }
Output:
Removing: 99 Filtered 75.00, Avg 77.40, Limit: 11.61 Added: 75 Removing: 99 Filtered 75.00, Avg 77.40, Limit: 11.61 Added: 74 Removing: 99 Filtered 74.89, Avg 77.30, Limit: 11.59 Added: 75 Removing: 99 Filtered 74.89, Avg 77.30, Limit: 11.59 Added: 90 Removing: 99 Filtered 76.56, Avg 78.80, Limit: 11.82 Added: 74 Removing: 99 Filtered 76.44, Avg 78.70, Limit: 11.80 Added: 75 Removing: 90 Filtered 74.78, Avg 76.30, Limit: 11.44 Added: 7 Removing: 90 Removing: 7 Filtered 74.75, Avg 69.50, Limit: 10.42
For those interested, I've got five indoor grow areas/environments. One for clone cuttings, one for plants in vegetative state, one for flowering/blooming state and I just started my hand at growing mushrooms, so I've got a cabinet for that as well. Each area is managed by either a Raspberry Pi, Arduino Pro Mini, or ESP8266 NodeMCU-12e.
You can see the dashboard of where I'm at right here.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Combining Exponential Moving Avg with Avg Filtering
by bliako (Abbot) on Mar 15, 2020 at 17:09 UTC | |
Re: Combining Exponential Moving Avg with Avg Filtering
by karlgoethebier (Abbot) on Mar 15, 2020 at 18:14 UTC | |
by stevieb (Canon) on Mar 15, 2020 at 18:23 UTC | |
Re: Combining Exponential Moving Avg with Avg Filtering
by Ea (Chaplain) on Mar 17, 2020 at 15:40 UTC |