I got one of those Ultrasonic Sensors HC-SR04 (actually I bought two since they were so cheap).
When I hooked it up to the Arduino, I ran the typical setup with an LCD shield and the sensor. I adapted one of the typical programs out there and after debugging which pin is which (trigger and echo are the two choices), I got it basically working.
The problem was the thing just doesn't always pick up a return echo. Sometimes, When it does that, it sees the distance as 1300 and some number of change inches.
I decided to do some simple digital filtering on the results. Here's the code:
#include "Ultrasonic.h"
#include <LiquidCrystal.h>
#include <LCDKeypad.h>
LCDKeypad lcd; // typical LCD shield setup
Ultrasonic ultrasonic(12,2); // different pins than usual due to LCD
// keep an array of values sampled
short ranges[5];
//////////////////////////////////////////////////////////////////////
// start up the sketch
//////////////////////////////////////////////////////////////////////
void setup() {
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("Distance");
initRanges();
}
//////////////////////////////////////////////////////////////////////
// store the range into the array shuffling back the array values by 1
//////////////////////////////////////////////////////////////////////
void putNewRange(long newRangeVal)
{
ranges[0] = ranges[1];
ranges[1] = ranges[2];
ranges[2] = ranges[3];
ranges[3] = ranges[4];
ranges[4] = newRangeVal;
return;
}
//////////////////////////////////////////////////////////////////////
// initially prime the buffer with the first five values read
//////////////////////////////////////////////////////////////////////
void initRanges(void)
{
putNewRange(ultrasonic.Ranging(INC));
putNewRange(ultrasonic.Ranging(INC));
putNewRange(ultrasonic.Ranging(INC));
putNewRange(ultrasonic.Ranging(INC));
putNewRange(ultrasonic.Ranging(INC));
}
//////////////////////////////////////////////////////////////////////
// do a simple digital filter basically ignoring rogue values
//////////////////////////////////////////////////////////////////////
short getRangeVal(void)
{
if (ranges[4] == ranges[3])
return(ranges[4]);
else if (ranges[4] == ranges[3] + 1)
return(ranges[3]);
else if (ranges[4] == ranges[3] -1 )
return(ranges[3]);
else if (ranges[4] == ranges[2])
return(ranges[4]);
else if (ranges[3] == ranges[2])
return(ranges[3]);
else if (ranges[2] == ranges[1])
return(ranges[2]);
else return(ranges[4]);
}
//////////////////////////////////////////////////////////////////////
// run the repeated sketch
//////////////////////////////////////////////////////////////////////
void loop()
{
initRanges(); // primes the ultrasonic values array
lcd.setCursor(0,1);
putNewRange(ultrasonic.Ranging(INC)); // put a new value into the array
lcd.print(getRangeVal()); // get the digitally filtered value
lcd.print(" in ");
// delay(200);
}
The filter is pretty basic and could use some improvements. The basic idea is to toss out rogue values.
Update - Improved filter
Here's an improved filter. The idea is to toss out numbers which are widely different than numbers in the series.
short getRangeVal(void)
{
if ((ranges[4] <= ranges[3] + 5) && (ranges[4] >= ranges[3] - 5))
return(ranges[4]);
else if ((ranges[4] <= ranges[2] + 5) && (ranges[4] >= ranges[2] - 5))
return(ranges[4]);
else if ((ranges[3] <= ranges[2] + 5) && (ranges[3] >= ranges[2] - 5))
return(ranges[3]);
else if (ranges[2] == ranges[1])
return(ranges[2]);
else return(ranges[4]);
}
Comments (0)
You don't have permission to comment on this page.