Analog to digital averaging with hysteresis

You know how the least sigificant digit will "wobble" back and forth between 2 numbers? It's half-way between 2 numbers and it can't quite figure out which one it should be. Well, this adds hysteresis to the averaging routine to eliminate that.

'****************************************************************
'*  Name    : Average_Hyst.pbp                                  *
'*  Author  : Darrel Taylor                                     *
'*  Date    : 7/19/2005                                         *
'*  Version : 3.0                                               *
'*  Notes   : Modified to use Hysteresis                        *
'*          : Use as an INCLUDE file                            *
'****************************************************************
' This routine will keep a "Running Average" of 10-bit Analog Values 
' Instead of adding a bunch of values together and then dividing by the number 
' of samples, it averages each sample into the final result immediately.
' This eliminates the need for 32 bit math.
' To allow it to "Catch up" to large changes, set the FAspread to an 
' acceptable range.
' Simply place the new number in VALUE and GoSub Average 
' The Average (with Hysterisis) will be returned into the same variable VALUE

'---- [ User Options ] ---------------------------------------------------------
HystLevel   CON  7      ' 7 = .7 of the Least Significant Digit
                        '    Valid HystLevel is from 6 to 13
AvgCount    CON  16     ' = Number of samples to average. For best response 
                        '    times, keep AvgCount as small as you can
FAspread    CON  50     ' = Fast Average threshold +/-
                        '  FAspread should be larger than the worst possible
                        '  noise in the A/D conversion.
'-------------------------------------------------------------------------------

AVGchanged  VAR  BIT    ' 1 indicates that the Average Value has changed
                        ' you have to clear this bit after using it
ADavg       VAR  WORD   ' Stores the current Average
ADhyst      VAR  WORD   ' Stores the current Value for Hysterisis
Value       VAR  WORD   ' Input / Output variable to be averaged
spread      CON  FAspread * 10  ' adjust spread *10 for Hyst.

GOTO OverAverage
' -=-=-=-=-=-=  Average Analog values -=-=-=-=-=-=-=-=-=-=
Average:
    Value = Value * 10                      ' Scale value up for hysterisis
    IF Value = ADavg Then NoChange          ' if they're the same, nothing to do 
    IF ABS (Value - ADavg) > spread OR Value < AvgCount Then FastAvg
    IF ABS (Value - ADavg) < AvgCount Then RealClose
    ADavg = ADavg - (ADavg/AvgCount)         ' Subtract 1 samples worth
    ADavg = ADavg + (Value/AvgCount)         ' Add in the new sample portion 
    GoTo AVGok
  FastAvg:                                   ' Catch up to the changing value
    ADavg = Value                            ' Set Average to the current value
    GoTo AVGok
  RealClose:                                 ' Reduce the sample size when
    ADavg = ADavg - (ADavg/(AvgCount/4))     ' the average and the sample are
    ADavg = ADavg + (Value/(AvgCount/4))     ' "Real Close"
  AVGok:
    IF ABS (ADavg - ADhyst) > HystLevel then ' If it changed > HystLevel +/-
        ADhyst = ((ADavg + 5) / 10) * 10     ' Round ADavg to get new Value
        AVGchanged = 1                       ' Indicate that Average changed
    ENDIF   
  NoChange:
    Value = ADhyst / 10                      ' Scale the result down
Return

OverAverage:
'---------------------------------------------------------------
Page last modified on March 06, 2018, at 12:57 PM