So I started with a library program that read data from my sharp IR distance sensor.  I modified the program to print the data to teraterm, with some advice from Erik O.  Then I modified it to turn a servo based on the sensor data.  Then I modified it with a servo calibration routine.  So far so good.  I noticed a lot of chatter in the readings and the servo movement, so I figured I should filter the sensor data.  I am shooting from the hip on this one.  First I added what I call a spike filter which detects and averages out sensor data spikes.  That filter data goes into an averaging filter which averages the last 5 values.  PWM is then calculated with that despiked averaged reading.  It all seems to work, though I do still get some chatter and spikes.  I could smooth it out by averaging more values, and changing the threshold of my spike filter, increasing overall latency. I am wondering if somebody could have a quick look at my code and see if I am doing a good job so far :)  I am curious if there is a more standard way to do this.  After I created my method I decided to search the library for a filter routine.  I did find an analog filter of some sort, but don't really understand it at this point.  So far I am proud of my little achievements here!  I will post my code below.  Thanks!
 
/* Sharp Sensor Test
 * Connections:
 * PIN15          (White) Signal
 * 5.0V USB Out   Sensor Power (+)
 * GND            Sensor Gnd   (-)
 * Place a 10uf cap close the the sensor between VCC nad GND
 */
#include "mbed.h"
/* Standard LED's on the mbed */
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
Serial pc(USBTX, USBRX); // tx, rx /
/* Our signal line is PIN15 */
AnalogIn   Sensor(p15);
PwmOut servo(p21);
int main() {
    
    servo.period(0.020);          // servo requires a 20ms period 
    
    /**********Begin Servo Range Calibration******************/
    float UPL = 0.0021; /*Initialize PWM Upper Limit*/
    float LPL = 0.0009; /*Initialize PWM Lower Limit*/
    char c = 'z'; /*Initialize char for calibtation inputs*/
 
    /*Calibration Loop for Upper PWM Limit*/
    servo.pulsewidth(UPL);
    pc.printf("\n***Calibration of Upper PWM Limit***");
    pc.printf("\nPress 'u' to increase, 'd' to decrease,  'q' to calibrate Lower PWM Limit\n");
    while( c != 'q') 
    {
        c = pc.getc();
        if(c == 'u') UPL += 0.0001;
        if(c == 'd') UPL -= 0.0001;
        servo.pulsewidth(UPL);
    }
    /*Calibration Loop for Lower PWM Limit*/
    servo.pulsewidth(LPL);
    pc.printf("***Calibration of Lower PWM Limit***");
    pc.printf("Press 'u' to increase, 'd' to decrease,  'q' to quit\n");
    c = 'z';
    while( c != 'q') 
    {
        c = pc.getc();
        if(c == 'u') LPL += 0.0001;
        if(c == 'd') LPL -= 0.0001;
        servo.pulsewidth(LPL);
    }
    pc.printf("\nUpper PWM Limit: %f   Lower PWM Limit: %f",UPL,LPL);
    
    /*converting Analog pin reading (0-1) to servo PWM range as calibrated*/
    /*sensor producing pin range from .06 to .85*/
    float x; /*extrapolated lower limit of PWM range*/
    float y; /*extrapolated upper limit of PWM range*/
    float UAL = 0.850; /*observed upper limit of pin reading from sensor*/
    float LAL = 0.060; /*observed lower limit of pin reading from sensor*/
    x = UPL-(((UAL)*(UPL-LPL))/(UAL-LAL)); /*extrapolation for x*/
    y = LPL+(((1-LAL)*(UPL-LPL))/(UAL-LAL)); /*extparolation for y*/
    /*checking if the extrapolation is correct*/
    pc.printf("\nFor UAL=.850, UPL: %f=%f",UPL,(0.850*(y-x)+x));
    pc.printf("\nFor LAL=.060, LPL: %f=%f",LPL,(0.060*(y-x)+x)); 
    c = 'z';
    while (c != 'y')
    {
        pc.printf("\nenter 'y' to continue\n");
        c = pc.getc();
    }
    /****************End Servo Range Calibration********************/
    
    /****************Begin filtering sensor readings****************/
    int count = 4; /*count for spike filter*/
    float ss = 0.60; /*spike error threshold percentage*/
    float sp[5]={}; /*initial array for sensor values for spike filter*/
    float cum = 0; /*initial cumulative value for moving average filter*/
    float old = 0; /*initial value for placeholder used in moving average filter*/
    int i = 0; /*initial value for counter in moving average filter*/
    int as = 5; /*size of array for moving average filter*/
    float sensvals[5]={};
    float sensvalavg;
    float avg0134;
    float sensval;
    
    while(count>0) /*loop to fill sp[0-3] with sensor values, done to initialize the Spike filter*/
        {
        sensval=Sensor.read();
        sp[count-1]=sensval;
        count-=1;
        }
    float PWMVal;  
          
    while (1) {
        /*****filter continues here inside main loop**********/
        sensval=Sensor.read();
        sp[4]=sp[3]; /*moving values down the array and filling sp[0] with the newest data point*/
        sp[3]=sp[2];
        sp[2]=sp[1];
        sp[1]=sp[0];
        sp[0]=sensval;
        avg0134 = (sp[0]+sp[1]+sp[3]+sp[4])/4; /*taking avg of the array values except position 2*/
        if (sp[2] > (1+ss)*avg0134 || sp[2] < (1-ss)*avg0134) /*comparing position 2 with the avg to see*/
            {                                     /*if it is > or < the ss percentage, if so, use avg0134*/
            sp[2]=avg0134; 
            pc.printf("\n***********SPIKE************SPIKE************");
            }
        old = sensvals[i];
 /* debug      pc.printf("\ncum1= %f   old1=%f",cum,old);  */
        cum = cum+sp[2]-old;  /*moving average filter*/
        sensvals[i]=sp[2];    /*moving average filter*/
        i+=1;                 /*moving average filter*/
        if (i>as-1) i=0;      /*moving average filter*/
            
 /* debug       pc.printf("\n%f %f %f %f %f",sp[0],sp[1],sp[2],sp[3],sp[4]);
                pc.printf("\n%f %f %f %f %f %f %f %f %f %f",sensvals[0],sensvals[1],sensvals[2],sensvals[3],sensvals[4]
                                                           ,sensvals[5],sensvals[6],sensvals[7],sensvals[8],sensvals[9]);
                pc.printf("\ncum= %f  old=%f  i=%f  sensvals[i]=%f  sp2= %f",cum,old,i,sensvals[i],sp[2]);  */ 
             
        sensvalavg = cum/as; /*moving average filter*/
    /****************End filtering sensor readings******************/
    
        PWMVal=(sensvalavg*(y-x)+x); /*conversion to PWM*/
        if (PWMVal >=UPL) PWMVal=UPL;  /*limits servo movement per calibration routine*/
        if (PWMVal <=LPL) PWMVal=LPL;  /*limits servo movement per calibration routine*/   
        servo.pulsewidth(PWMVal); /*sending out the final PWM value*/
 /* debug      pc.printf("\n SenseValAvg: %f    PWMVal: %f\n",sensvalavg,PWMVal);  */       
            
        /*
         * Efficient way as the object gets closer to the
         * sensor the LED's will turn on, as the object
         * moves away they count back down. Original by Dan Ros
        */
        led1 = (Sensor > 0.2) ? 1 : 0;
        led2 = (Sensor > 0.4) ? 1 : 0;
        led3 = (Sensor > 0.6) ? 1 : 0;
        led4 = (Sensor > 0.8) ? 1 : 0;
        /*
         * A cool effect when the full range of the sensor
         * has been reached, all LED's flash
        */
        if (Sensor  >= 0.9) {
            led1 = led2 = led3 = led4 = 1;
            wait(0.02);
            led1 = led2 = led3 = led4 = 0;
            wait(0.02);
        }
        wait(0.002);
    }
}
So I started with a library program that read data from my sharp IR distance sensor. I modified the program to print the data to teraterm, with some advice from Erik O. Then I modified it to turn a servo based on the sensor data. Then I modified it with a servo calibration routine. So far so good. I noticed a lot of chatter in the readings and the servo movement, so I figured I should filter the sensor data. I am shooting from the hip on this one. First I added what I call a spike filter which detects and averages out sensor data spikes. That filter data goes into an averaging filter which averages the last 5 values. PWM is then calculated with that despiked averaged reading. It all seems to work, though I do still get some chatter and spikes. I could smooth it out by averaging more values, and changing the threshold of my spike filter, increasing overall latency. I am wondering if somebody could have a quick look at my code and see if I am doing a good job so far :) I am curious if there is a more standard way to do this. After I created my method I decided to search the library for a filter routine. I did find an analog filter of some sort, but don't really understand it at this point. So far I am proud of my little achievements here! I will post my code below. Thanks!
/* Sharp Sensor Test * Connections: * PIN15 (White) Signal * 5.0V USB Out Sensor Power (+) * GND Sensor Gnd (-) * Place a 10uf cap close the the sensor between VCC nad GND */ #include "mbed.h" /* Standard LED's on the mbed */ DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); Serial pc(USBTX, USBRX); // tx, rx / /* Our signal line is PIN15 */ AnalogIn Sensor(p15); PwmOut servo(p21); int main() { servo.period(0.020); // servo requires a 20ms period /**********Begin Servo Range Calibration******************/ float UPL = 0.0021; /*Initialize PWM Upper Limit*/ float LPL = 0.0009; /*Initialize PWM Lower Limit*/ char c = 'z'; /*Initialize char for calibtation inputs*/ /*Calibration Loop for Upper PWM Limit*/ servo.pulsewidth(UPL); pc.printf("\n***Calibration of Upper PWM Limit***"); pc.printf("\nPress 'u' to increase, 'd' to decrease, 'q' to calibrate Lower PWM Limit\n"); while( c != 'q') { c = pc.getc(); if(c == 'u') UPL += 0.0001; if(c == 'd') UPL -= 0.0001; servo.pulsewidth(UPL); } /*Calibration Loop for Lower PWM Limit*/ servo.pulsewidth(LPL); pc.printf("***Calibration of Lower PWM Limit***"); pc.printf("Press 'u' to increase, 'd' to decrease, 'q' to quit\n"); c = 'z'; while( c != 'q') { c = pc.getc(); if(c == 'u') LPL += 0.0001; if(c == 'd') LPL -= 0.0001; servo.pulsewidth(LPL); } pc.printf("\nUpper PWM Limit: %f Lower PWM Limit: %f",UPL,LPL); /*converting Analog pin reading (0-1) to servo PWM range as calibrated*/ /*sensor producing pin range from .06 to .85*/ float x; /*extrapolated lower limit of PWM range*/ float y; /*extrapolated upper limit of PWM range*/ float UAL = 0.850; /*observed upper limit of pin reading from sensor*/ float LAL = 0.060; /*observed lower limit of pin reading from sensor*/ x = UPL-(((UAL)*(UPL-LPL))/(UAL-LAL)); /*extrapolation for x*/ y = LPL+(((1-LAL)*(UPL-LPL))/(UAL-LAL)); /*extparolation for y*/ /*checking if the extrapolation is correct*/ pc.printf("\nFor UAL=.850, UPL: %f=%f",UPL,(0.850*(y-x)+x)); pc.printf("\nFor LAL=.060, LPL: %f=%f",LPL,(0.060*(y-x)+x)); c = 'z'; while (c != 'y') { pc.printf("\nenter 'y' to continue\n"); c = pc.getc(); } /****************End Servo Range Calibration********************/ /****************Begin filtering sensor readings****************/ int count = 4; /*count for spike filter*/ float ss = 0.60; /*spike error threshold percentage*/ float sp[5]={}; /*initial array for sensor values for spike filter*/ float cum = 0; /*initial cumulative value for moving average filter*/ float old = 0; /*initial value for placeholder used in moving average filter*/ int i = 0; /*initial value for counter in moving average filter*/ int as = 5; /*size of array for moving average filter*/ float sensvals[5]={}; float sensvalavg; float avg0134; float sensval; while(count>0) /*loop to fill sp[0-3] with sensor values, done to initialize the Spike filter*/ { sensval=Sensor.read(); sp[count-1]=sensval; count-=1; } float PWMVal; while (1) { /*****filter continues here inside main loop**********/ sensval=Sensor.read(); sp[4]=sp[3]; /*moving values down the array and filling sp[0] with the newest data point*/ sp[3]=sp[2]; sp[2]=sp[1]; sp[1]=sp[0]; sp[0]=sensval; avg0134 = (sp[0]+sp[1]+sp[3]+sp[4])/4; /*taking avg of the array values except position 2*/ if (sp[2] > (1+ss)*avg0134 || sp[2] < (1-ss)*avg0134) /*comparing position 2 with the avg to see*/ { /*if it is > or < the ss percentage, if so, use avg0134*/ sp[2]=avg0134; pc.printf("\n***********SPIKE************SPIKE************"); } old = sensvals[i]; /* debug pc.printf("\ncum1= %f old1=%f",cum,old); */ cum = cum+sp[2]-old; /*moving average filter*/ sensvals[i]=sp[2]; /*moving average filter*/ i+=1; /*moving average filter*/ if (i>as-1) i=0; /*moving average filter*/ /* debug pc.printf("\n%f %f %f %f %f",sp[0],sp[1],sp[2],sp[3],sp[4]); pc.printf("\n%f %f %f %f %f %f %f %f %f %f",sensvals[0],sensvals[1],sensvals[2],sensvals[3],sensvals[4] ,sensvals[5],sensvals[6],sensvals[7],sensvals[8],sensvals[9]); pc.printf("\ncum= %f old=%f i=%f sensvals[i]=%f sp2= %f",cum,old,i,sensvals[i],sp[2]); */ sensvalavg = cum/as; /*moving average filter*/ /****************End filtering sensor readings******************/ PWMVal=(sensvalavg*(y-x)+x); /*conversion to PWM*/ if (PWMVal >=UPL) PWMVal=UPL; /*limits servo movement per calibration routine*/ if (PWMVal <=LPL) PWMVal=LPL; /*limits servo movement per calibration routine*/ servo.pulsewidth(PWMVal); /*sending out the final PWM value*/ /* debug pc.printf("\n SenseValAvg: %f PWMVal: %f\n",sensvalavg,PWMVal); */ /* * Efficient way as the object gets closer to the * sensor the LED's will turn on, as the object * moves away they count back down. Original by Dan Ros */ led1 = (Sensor > 0.2) ? 1 : 0; led2 = (Sensor > 0.4) ? 1 : 0; led3 = (Sensor > 0.6) ? 1 : 0; led4 = (Sensor > 0.8) ? 1 : 0; /* * A cool effect when the full range of the sensor * has been reached, all LED's flash */ if (Sensor >= 0.9) { led1 = led2 = led3 = led4 = 1; wait(0.02); led1 = led2 = led3 = led4 = 0; wait(0.02); } wait(0.002); } }