NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.7

Human:
Assuming that pin 13 really is the reason why the Duemilanove wasn't working with NewPing,

Pin 13 was my first guess as to the cause of the problem as there's an LED attached to it. I've been suggesting to people to try different pin assignments and changed the default sketch to use pin 12 and 11 for a few weeks now.

With that said, I didn't ask you specifically not to use pin 13 for two reasons. First, pin 13 works fine on the Uno and we both assumed you were using the Uno at the begining. Secondly, the sketch you linked to at TrollMaker.com is for sale | HugeDomains also uses pins 12 and 13. So, to totally close this case, were you using the exact trollmaker sketch including using pins 12 and 13 or did you use that sketch but with different pins? The TestF library is basically exactly the same as the trollmaker sketch. If the Duemilanove really can't use pin 13 as a input, it shouldn't be able to with either the NewPing library or the trollmaker sketch (as it uses pin 13 for input).

Human:
I wanted to work on a contribution to the project. Everyone's experiences with the HC-SR* family of sensors is that they're mostly reliable, but they occasionally throw out a false positive or false negative. I've put digital filters in my code so that I don't trust readings until they remain consistent for a window of time or number of pings. It occurs to me that this would be of general utility, as an optional way of using NewPing objects.

Some ideas of how I'd do this:

    1. Sliding scale between responsive and trustworthy: Max responsiveness would provide no filter. Max trustworthiness would only trust a reading if there are no incompatible readings over a period of time, depending on whether we're trying to eliminate false positives or false negatives.
    1. "Best result in N ms": Similar to the above, except it only examines as many pings as it can in an N ms window. Should ensure that a filtered ping comes through in N ms, +/- some inherent latency
    1. Parameter-level tweaking: Open up all the configuration options to advanced users. They could specify a time-based filter or a filter that waits for N compatible pings in a row before believing the results.

I think I'd start with #1 and see how it's received.

Would you like me to have a go at coding this up? Would you prefer that I subclass NewPing or extend NewPing with additional methods that enable/configure the digital filter option? My intent is to not change the existing API so as not to break any legacy code, and I think either approach could facilitate that.

I don't ever remember seeing false positives or false negatives. For example, if I put an object a foot away from the sensor it will show a distance every time. It may fluctuate a bit as far as the distance, but will never give a 0 reading. Likewise, if I set the maximum distance at 200cm and have it ping out at a wall that's 15 feet away, it will always get a 0 reading. Some, have incorrectly interpreted this as incorrect. But, this is the correctly designed behavior. You wouldn't want the sensor to report back 200cm when there was something 400cm away as you've set the sensor to only listen for objects 200cm away or closer. A reading of 200cm would tell you that something is 200cm away, when there is not. Any object beyond the specified maximum distance is returned as 0, which means "all clear". It's slightly different with the timer interrupt method as we don't create an event unless there's something in-range.

I used the below sketch with your HC-SR04 sensor. It does VERY fast pings and displays a "." if it gets a ping within 200cm or an "0" if it gets no ping (zero). It displays it in 80 columns so a lot of data can quickly be looked after the test is complete. Each line ends with the ping microseconds for the final ping (kind of a test to make sure you're understanding what it's showing).

#include <NewPing.h>
#define trigPin 12
#define echoPin 11
NewPing sonar(trigPin, echoPin, 200);
byte i = 0;

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

void loop() {
  unsigned int us = sonar.ping();
  if (us==0) {
    Serial.print("0");
  } else {
    Serial.print(".");
  }
  i++;
  if (i==80) {
    Serial.print(" ");
    Serial.println(us);
    i=0;
  }
  delay(10);
}

I ran it for an hour pointing in the general area of my coffee cup and monitor sitting on my desk about 18 inches away and I got all periods, not a single "0". A ping every 10ms for an hour is around 360,000 pings. For the next test I turned the sensor around and pointed it towards a wall that was about 10 feet away. I started the test and let it run for another hour and got nothing but zeros with no periods.

So, you may want to try the above sketch and a similar test before we try to filter false positives or false negatives that I can't even duplicate. What I could see as useful is averaging. Either a simple multi-sample average or a more complex standard deviation type calculation. But, I question if this type of calculation is really outside the scope of an ultrasonic library as one could simply take the ping results and feed them to a standard deviation library to do the calculation.

Tim