Analog Smoothing Algorithm

Here’s another simple algorithm for smothing analog values. This one was posted by Brian Taylor on the PicBasic list.

Adjust alpha for more or less smoothing. A large alpha takes much longer to reach final value. 1 = no smoothing. 4 or 5 would typically give good results, but your mileage may vary.

```newVal var word        ' the value from the ADC
smoothed var word    ' a nicely smoothed result

if newval > smoothed then
smoothed = smoothed + (newval - smoothed)/alpha
else
smoothed = smoothed - (smoothed - newval)/alpha
endif
```

Here’s a more fully-developed example of it in Wiring syntax (tested on an Arduino board):

```/*
Analog smoothing algorithm
by Tom Igoe

uses a potentiometer on analog in 2 to generate the value for alpha,
the number of samples to average.

n.b. the variable "smoothed" needs to be a global, since it's modified
each time a new smoothing is done.  So if you want to use this for multiple
inputs, you'll need a "smoothed" variable for each input.

Created 17 October 2005
Updated 24 March 2006

*/

int analogVal = 0;      // the value from the ADC
int smoothed = 0;    // a nicely smoothed result. This needs to be a global variable
int alpha = 4;       // the number of past samples to average by

// function prototypes:
void smoothValue(int rawValue);

void setup() {
Serial.begin(9600);
}

void loop() {
// read the trimmer pot, use it to generate alpha:
alpha = (analogRead(1) /114) + 1;
// smooth it:
smoothValue(analogVal);

// to see the difference, try outputting analogVal
// instead of smoothed here, and graph the difference.
// divide by 4 to print the result as a byte:
Serial.print(smoothed/4, BYTE);

delay(10);
}

int i;
for (i=0; i< howManyTimes; i++) {
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
delay(200);
}
}

// Smooth out an analog reading:
void smoothValue(int rawValue) {
if (rawValue > smoothed) {
smoothed = smoothed + (rawValue - smoothed)/alpha;
}
else {
smoothed = smoothed - (smoothed - rawValue)/alpha;
}
}

```

Written in PicBasic Pro, tested on a PIC 18F252:

```
'  Analog smoothing algorithm
' by Tom Igoe

' uses a potentiometer on analog in 2 to generate the value for alpha,
' the number of samples to average.

' n.b. the variable "smoothed" needs to be a global, since it's modified
' each time a new smoothing is done.  So if you want to use this for multiple
' inputs, you'll need a "smoothed" variable for each input.

' Created 17 October 2005
' Updated 27 March 2006

DEFINE  ADC_BITS        10     ' Set number of bits in result
DEFINE  ADC_CLOCK       3     	' Set clock source (3=rc)
DEFINE  ADC_SAMPLEUS    50    	' Set sampling time in uS

TRISA = %11111111       ' Set PORTA to all input
ADCON1 = %10000010      ' Set PORTA analog and right justify result

analogVal var word    '  the value from the ADC
smoothed var word     '  a nicely smoothed result. This needs to be a global variable
byteVar var byte      ' a byte variable to send out serially
alpha var byte        '  the number of past samples to average by
trimPotValue var word ' the trimmer pot input

' serial variables and constants:
tx var portc.6
rx var portc.7
inv9600 con 16468

'   Variables for subroutines:
i var byte
LEDPin var portb.7

main:
' read the trim pot to determine alpha between 1 and 10:
alpha = (trimPotValue / 114) + 1
'  smooth it:
gosub smoothValue

'  to see the difference, try outputting analogVal
'  instead of smoothed here, and graph the difference.
'  divide by 4 to print the result as a byte:
byteVar = smoothed /4
serout2 tx, inv9600, [byteVar]

pause 10
goto main

for i=0 to 3
high LEDPin
pause 200
low LEDPin
pause 200
next
return

'  Smooth out an analog reading:
smoothValue:
if (analogVal > smoothed) then
smoothed = smoothed + (analogVal - smoothed)/alpha
else
smoothed = smoothed - (smoothed - analogVal)/alpha
endif
return
```
This entry was posted in arduino/wiring, PicBasic Pro. Bookmark the permalink.