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.


In reply to Combining Exponential Moving Avg with Avg Filtering by stevieb

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.