Averaging, Smoothing
I used Flex sensor and same Processing code for Sensors and Time.
Averaging and finding the median Pic Code
' Analog median and average
' by Tom Igoe
' This program reads an analog input and gives the average of 9 readings,
' and sorts the list of readings and delivers the median number.
' Created 17 October 2005
' Updated
' Define ADCIN parameters
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
numReadings con 9 ' number of samples to take
median var byte ' median of the sorted samples
readingNumber var byte ' counter for the sample array
' serial variables and constants:
tx var portc.6
rx var portc.7
inv9600 con 16468
' variables for subroutines:
i var byte
j var byte
position var byte
analogValues var word[numReadings]
total var word
average var word
out var byte
in var byte
swapper var word
main:
for readingNumber = 0 to (numReadings - 1)
' get the reading:
adcin 0,analogValues[readingNumber]
' increment the counter:
readingNumber = readingNumber + 1
next
' sort the array using a bubble sort:
gosub bubbleSort
' get the middle element:
median = analogValues[numReadings / 2]
' print the results:
' print the array, nicely ASCII-formatted:
serout2 tx, inv9600,["Array: ["]
for j = 0 to (numReadings - 1)
serout2 tx, inv9600, [DEC analogValues[j], ", "]
next
serout2 tx, inv9600,["]", 10, 13]
' average the array:
gosub averageArray
serout2 tx, inv9600, ["Average: ", DEC average, 10, 13]
serout2 tx, inv9600, ["Median: ", DEC median, 10, 13]
GOTO MAIN
' average the values in the array:
averageArray:
total = 0
average = 0
for i = 0 to (numReadings - 1)
total = total + analogValues[i]
next
average = total/numReadings
RETURN
bubbleSort:
for out = 0 to (numReadings - 2) ' outer loop
for in = out+1 to (numReadings - 1) ' inner loop
if analogValues[out] > analogValues[in] then 'out of order?
swapper = analogValues[out]
analogValues [out] = analogValues[in]
analogValues[in] = swapper
endif
next
next
return
Next one is Eliminating the pick points
Written in PicBasic Pro, tested on a PIC 18F252:
' Analog smoothing algorithm
' by Tom Igoe
' This program reads an analog input and smooths out the result by averaging
' the result with past values of the analog input.
' 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 ADCIN parameters
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
gosub blink
main:
' read the trim pot to determine alpha between 1 and 10:
adcin 1, trimPotValue
alpha = (trimPotValue / 114) + 1
' get an analog reading:
adcin 0, analogVal
' 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]
' delay before next reading
pause 10
goto main
' Blink the reset LED:
blink:
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
Processing Code(same as Sensors and time)
import processing.serial.*;
Serial myPort; // The serial port
// initial variables:
int i = 1; // counter
int inByte = -1; // data from serial port
void setup () {
size(400, 300); // window size
// List all the available serial ports
println(Serial.list());
// I know that the third port in the serial list on my mac
// is always my Keyspan adaptor, so I open Serial.list()[2].
// Open whatever port is the one you're using.
myPort = new Serial(this, Serial.list()[0], 9600);
// set inital background:
background(0);
}
void draw () {
if (myPort.available() > 0) {
inByte = myPort.read();
serialEvent();
}
}
void serialEvent () {
// draw the line:
stroke(0,255,0);
line(i, height, i, height - inByte);
// at the edge of the screen, go back to the beginning:
if (i >= width) {
i = 0;
background(0);
}
else {
i++;
}
}