Shop OBEX P1 Docs P2 Docs Learn Events
Stamp logic to find maximum and minimum of several values — Parallax Forums

Stamp logic to find maximum and minimum of several values

micamica Posts: 23
edited 2006-02-15 15:53 in BASIC Stamp
I setup a test device for a TSL230 light sensor (not that relevant to the question). For a given light input I would like to take 10 reads then have the stamp output the average, maximum and minimum.

Average is easy, or at least straightforward in that I can add up the 10 reads then divide by 10. But is there any shortcut to the logic of finding the max/min for the 10 reads?

I can see taking one number then comparing it to another with a series of < or > commands to ‘filter’ for the max. But this seems kind of… tedious is one word, and really eats into the memory.

Any suggestions?

Comments

  • Jeff DegeJeff Dege Posts: 85
    edited 2006-02-15 05:54
    To calculate min, max, and average, you need four variables. You don't need to store all ten measurements.

    Min so far, max so far, total so far, and count.

    And the new measurement, of course.

    Start by setting min to MAX_INT, max to MIN_INT, total and count to zero.

    For each measurement:

    If greater than max, save in max.
    If less than min, save in min.
    Add to total.
    And increment count by one.

    Personally, though, I'd consider an exponentially-decayed moving average.

    You've seen moving averages on the stock market pages of the newspaper - a figure showing 20-day moving average would chart for each day the average of the previous 20 days' stock prices,

    An exponentially-decayed moving average is similar, but instead of averaging a fixed number of measurements, it averages all measurements, but gives them different weights according to an exponentially decreasing function. Most recent measurements count the most, older ones less.

    The forum software seems to lack the basic mathematics symbols, so we'll skip all of that, but what makes this computationally simple is that the ratio between one period's average and that period's contribution to the next period's average is fixed.

    You only need one variable to hold the average, plus the variable that holds the measurement.

    For each new measurement, you add to the previous average a fraction of the difference between it and the previous average. Working pen-and-paper, accountants used to use 1/10th as the fraction because it's easy.

    The moving average will lag behind changes in the measurement - if the measurement suddenly and permanently increases, the average will gradually increase, and will eventually reach the measurement. It will wash out spikes - a single spurious measurement will move the average only slightly.

    The larger the fraction, the less the lag and the more influence spikes will have. If the fraction is 1, you're doing no averaging at all.

    The two aspects you control are how often you take the measurement, and how large the fraction is. Both will need to be tuned to your particular environment.

    average var word
    measurement var word
    
    average = 0
    
    do
       gosub getMeasurement
       gosub calculateAverage
       debug "Moving average is ", dec average, cr
       pause 1000
    loop
    
    getMeasurement:
       ' do something and put the results into measurement
       return
    
    calculateAverage:
       average = average + (measurement - average)/10
       return
    
    
  • micamica Posts: 23
    edited 2006-02-15 06:22
    Thanks for the quick reply and advice. I’ll keep it in mind.

    Regarding the exponentially-decayed, I didn’t give you enough information on what I’m doing. Your suggestion is appropriate for an average take over time… or I guess frequency as well. I’m looking for accuracy or predictability for one set of conditions.

    What I’m working on is an AOA (Angle of Attack) sensor. An air vain moves a ‘light valve’, if you will. So depending on the position of the fin in the air the light sensor will see more or less light. My need for the max/min is that for a given setting or a given angle of attack, I want to see how much variation I get. So if the max/min overlap a previous set of reads for the angle before or after, I know I still have some work to do. Once I get a constant change in reading and the ‘noise’ doesn’t overlap the reads before and after, I’m done…. and I can go work on something fun[noparse]:)[/noparse]

    Thanks again. Good info.
  • El PaisaEl Paisa Posts: 375
    edited 2006-02-15 13:22
    'easy method to determine max, min values
    maxvalue var word
    minvalue var word
    value var word

    maxvalue=65530 ' > or max expected value
    miinvalue=-65530 ' < or min expected value

    do
    'calculate value...
    if value>maxvalue then maxvalue=value
    if value<minvalue then minvalue=value

    .
    .
    .

    loop
  • Jeff DegeJeff Dege Posts: 85
    edited 2006-02-15 14:19
    I don't think your starting values are right.

    First, you want your minvalue to be initialized to something larger than any possible measurement, and your maxvalue to something smaller. You have it the other way round.

    And second, the values you're using are wrong. Words in Stamp Basic are 16-bit unsigned integers.

    Should be:

    maxvalue=0
    minvalue=65535
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2006-02-15 15:53
    The Stamp has built-in MAX and MIN operators:

    maxvalue=0
    minvalue=65535
    DO
    GOSUB getMeasurement
    maxvalue = measurement MIN maxvalue
    minvalue = measurement MAX minvalue
    DEBUG DEC MINVALUE, TAB, DEC MAXVALUE, CR
    LOOP
    



    It may seem strange to use the MIN operator to keep the maximum and MAX to keep the minimum, but that is the way it works. The operators are more like a floor and a ceiling: If the value is above the current floor, then move the floor up, and if the value is less than the current ceiling, move the ceiling down. You can read about MAX and MIN in the Stamp manual. The operators are commutative, that is, x MAX y = y MAX x.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
Sign In or Register to comment.