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