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

teckel:
All of my HC-SR04 sensors work with both 2 pins and 1 pin, so it has nothing to do with the pins. Who did you purchase your sensors from as I'd love to duplicate the problem.

I got them from this vendor on Amazon http://www.amazon.com/gp/product/B0085MXZH0/ref=oh_details_o01_s00_i00

They're currently out of stock, so replacements you get may or may not be the same batch.

teckel:
Also see the attached file to this message. This modified version of the library simulates the pulseIn function that's being used the example sketch you linked to (waits up to a second for a ping echo). I would not suggest anyone else using this library, it's just meant for testing for those with a HC-SR04 that are giving 0cm results. It's an inferior library just meant for testing.

Let me know how this works.

I'll try that out tomorrow and report back. Thanks for your help!

Human:
I got them from this vendor on Amazon http://www.amazon.com/gp/product/B0085MXZH0/ref=oh_details_o01_s00_i00

They're currently out of stock, so replacements you get may or may not be the same batch.

I got one from this vendor on Amazon:

Two others I got direct from China on eBay. I forgot where the 4th one came from. All work, but 3 are only stable to around 50cm. This is the case with any library I use or if I use a sketch without a library. So they're defective for sure, and 3 out of 4 being defective makes me question the quality of the HC-SR04 sensors.

I'd say the SRF05 is the best sensor. Works perfectly and works with only one pin. It's also easy to identify as it's the only ultrasonic sensor I know of that has 5 pins (one is not used).

Tim

It's also easy to identify as it's the only ultrasonic sensor I know of that has 5 pins

So does the SRF04.
SRF02 also has five pins, but it is I2C.

I tried NewPingTest1, and I get one ping per second, returning 0cm each time. Is there a specific sketch you wanted me to use? I used the minimal sketch that does 20 pings per second in the loop() function.

This is with the sensor that works fine with that standalone code I linked to, even when I assign delays and timeouts that are consistent with the baseline NewPing.

If you're interested, I can mail it to you. I have two of them, and I just ordered an HY-SRF05.

Human:
I tried NewPingTest1, and I get one ping per second, returning 0cm each time. Is there a specific sketch you wanted me to use? I used the minimal sketch that does 20 pings per second in the loop() function.

This is with the sensor that works fine with that standalone code I linked to, even when I assign delays and timeouts that are consistent with the baseline NewPing.

If you're interested, I can mail it to you. I have two of them, and I just ordered an HY-SRF05.

That basic sketch is just fine. The modified library basically waits up to 1 full second for the ping echo (which is what pulseIn does). It's very interesting that it doesn't work for you yet we are running seemingly identical hardware. The only variable is the sensor, so yes, it would be great if you could send it to me. I'll message you my address. I'm sure we can get to the bottom of this if I have a sensor with this issue in front of me to test.

Tim

teckel:

deverett:
Tim,
So far everything is working fine with the single pin version. I've only had time to wire up 2 of the sonars so far.

Dave

Basically, because the library is designed specifically to communicate with ultrasonic sensors instead of using stock commands like pulseIn, it waits for all the correct pin states between the trigger and echo stages. So, it can both trigger and echo using the same Arduino pin because the output and input stages are clearly defined.

The idea came when I wired a sensors incorrectly (trigger and echo pins reversed) with no ill effect while looking at adding support for the Ping))) sensor which only uses 1 pin for both trigger and echo. I knew it wouldn't break anything to try (from my incorrect wiring experience) and it also seemed logical that the sensor was only ever listening for a trigger during certain situations and only sending an echo output during other situations. Sure enough, I believe 3 lines of code were modified and it worked perfectly.

On projects where you have multiple sensors (which many have) reducing the number of pins needed by half is huge. Projects that at once needed a large Arduino Mega could be done with a thumbnail-sized Teensy 2.0.

Keep us updated!

Tim

Up to 6 sonars now, not a hitch. Also I think the reads are more stable as I get solid results even when the robot is moving. I currently have the update set at 80ms, but I'm about to take it back to 35ms as the number of sonars increases.

You do good work Tim.

Dave

I put my HC-SR04 sensor in the mail to Tim today. Hopefully it'll tighten the test cycle and benefit others who have HC-SR04 sensors. :slight_smile:

My backup HC-SR04 is definitely less reliable than the one I shipped out, but it still "works" (for some value of "work"). I have digital filters in place to try to determine if a reading is true or not, so this mitigates the inherent issues with the sensor.

My code base can also create a virtual sensor from N actual sensors, and I was planning to do this to work around the unreliability, since it seemed unlikely that two sensors would be unreliable at the same moment in time (unless there are common environmental or power factors that cause this). If the HY-SRF05 is more reliable, then I can probably start trusting the data more and tune the digital filters to be more lenient.

Is there any demand for virtual sensors as I described? If so, I can work on turning what I have into a subclass of NewPing. It sounded like other people are using multiple sensors in non-redundant ways, and if the reliability solution really is "just buy an HR-SRF05" then maybe that effort would be wasted.

Human:
I put my HC-SR04 sensor in the mail to Tim today. Hopefully it'll tighten the test cycle and benefit others who have HC-SR04 sensors. :slight_smile:

My backup HC-SR04 is definitely less reliable than the one I shipped out, but it still "works" (for some value of "work"). I have digital filters in place to try to determine if a reading is true or not, so this mitigates the inherent issues with the sensor.

My code base can also create a virtual sensor from N actual sensors, and I was planning to do this to work around the unreliability, since it seemed unlikely that two sensors would be unreliable at the same moment in time (unless there are common environmental or power factors that cause this). If the HY-SRF05 is more reliable, then I can probably start trusting the data more and tune the digital filters to be more lenient.

Is there any demand for virtual sensors as I described? If so, I can work on turning what I have into a subclass of NewPing. It sounded like other people are using multiple sensors in non-redundant ways, and if the reliability solution really is "just buy an HR-SRF05" then maybe that effort would be wasted.

Can't wait to get the sensor and figure out what's going on. I hope to test and send back ASAP.

With properly working sensors, a virtual sensor from multiple sensors should not be required. Sensors that actually work are very reliable and give consistent and accurate readings all the time. I also have sensors that "work" but are clearly not 100% functional (this is with any library). Mine having a problem seem to work to around 50cm, then get all wonky.

While I find that my SRF05 and SRF06 are more reliable, online I've also found at least two totally different kinds of SRF05 sensors. Both have the same model number on them, but each are electronically different with different pinouts. So, I don't want to totally endorse the SRF05 as superior, as it appears they're made my multiple manufactures with different specs. Which is probably why there's some HC-SR04 sensors that "work" and probably why the HC-SR04 sensors you have don't work with my library, as they're made by a bunch of different manufactures, with different specs or quality control.

Tim

teckel:
Can't wait to get the sensor and figure out what's going on. I hope to test and send back ASAP.

I'm still amazed you're volunteering to do this :slight_smile: That's dedication!

If you find that the SR04 that I sent you behaves significantly differently than the ones you have, I would be happy for you to keep it for regression testing purposes. (I could potentially help write a regression test, too, although I've never tried making one for an Arduino library, and it couldn't be fully automated due to its nature.) I have a spare SR04 anyway, and they're cheap enough that I could just order more if I wanted more.

teckel:
With properly working sensors, a virtual sensor from multiple sensors should not be required. Sensors that actually work are very reliable and give consistent and accurate readings all the time. I also have sensors that "work" but are clearly not 100% functional (this is with any library). Mine having a problem seem to work to around 50cm, then get all wonky.

The sensor I'm sending you works up to 100cm (I didn't try longer distances), but it occasionally throws in an outlier of some kind, whether it's an in-range but wrong value while something is in the sensor's range, an out-of-range value while something is in range, or an in-range value while nothing is in range. I agree that if a sensor is working properly, it shouldn't do this. My original idea was to use virtual sensors to combat inherent unreliability issues with these cheap sensors (much like RAID was created to create reliability out of unreliable cheap parts), but if there are reliable sensors in the same family for the same price, I think I should just use those :slight_smile:

teckel:
While I find that my SRF05 and SRF06 are more reliable, online I've also found at least two totally different kinds of SRF05 sensors. Both have the same model number on them, but each are electronically different with different pinouts. So, I don't want to totally endorse the SRF05 as superior, as it appears they're made my multiple manufactures with different specs. Which is probably why there's some HC-SR04 sensors that "work" and probably why the HC-SR04 sensors you have don't work with my library, as they're made by a bunch of different manufactures, with different specs or quality control.

Hmm. Any such variations with the SRF06 sensors?

Human:
Hmm. Any such variations with the SRF06 sensors?

It doesn't appear there's different types of SRF06 sensors. But, I wouldn't be surprised if there were multiple manufactures. Also, the SRF06 won't work using one pin unless you put a cap across the trigger and echo pins, and, even that doesn't work with the Teensy. The ability to use only one pin is a huge advantage as in many projects multiple sensors are used and pins can be in short supply. For that reason, I'd lean towards the SRF05, which for at least one manufacture is actually designed to be used with only one pin.

Tim

Human:

teckel:
Can't wait to get the sensor and figure out what's going on. I hope to test and send back ASAP.

I'm still amazed you're volunteering to do this :slight_smile: That's dedication!

If you find that the SR04 that I sent you behaves significantly differently than the ones you have, I would be happy for you to keep it for regression testing purposes. (I could potentially help write a regression test, too, although I've never tried making one for an Arduino library, and it couldn't be fully automated due to its nature.) I have a spare SR04 anyway, and they're cheap enough that I could just order more if I wanted more.

Got your sensor today and had to plug it in to see what happens. Connected to the Teensy 2.0, it works perfectly with both 2 and 1 pins. Don't have a connector on this computer to connect to the Arduino R3, but I'll try it tomorrow on my primary system. Turning out to be quite a good puzzle this is.

Tim

hii,..i m using hc-sr04 ultrasonic sensor,..i m using the lastest version of ping,...all my connections are fine,,... and the code i m running is..
// ---------------------------------------------------------------------------
// Getting a reliable ping every 50 milliseconds isn't possible with other ping or ultrasonic libraries.
// These kinds of speeds work perfectly with the NewPing library. Even at the maximum sensor distance of
// 500cm, distance measurements can be done 20 times a second! If you set the maximum distance to 200cm
// as we have in this example sketch, even faster pings can be achieved. I suggest waiting at least 37
// milliseconds between pings to avoid previous ping echo issues, that translates to a maximum ping rate
// of around 27 times per second. Much better than the sometimes 1 ping a second with other libraries.
//

#include <NewPing.h>

#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on ping sensor.
#define ECHO_PIN 13// Arduino pin tied to echo pin on ping sensor.
#define MAX_DISTANCE 200
// Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

unsigned int pingSpeed = 50; // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer = 75; // Holds the next ping time, start at 75ms to give time for the Arduino pins to stabilize.

void setup() {
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}

void loop() {
// Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distance pings.
if (millis() >= pingTimer) { // pingSpeed milliseconds since last ping, do another ping.
pingTimer += pingSpeed; // Set the next ping time.
Serial.print("Ping: ");
int cm = sonar.ping_cm(); // Send out the ping, get the results in centimeters.
Serial.print(cm); // Print the result (0 = outside the set distance range, no ping echo)
Serial.println("cm");
}
}
and the output coming is..
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
and continue....
i dont know why,..the sensor is just giving this output
plzz help

karan2012singh:
hii,..i m using hc-sr04 ultrasonic sensor,..i m using the lastest version of ping,...all my connections are fine,,... and the code i m running is..
// ---------------------------------------------------------------------------
// Getting a reliable ping every 50 milliseconds isn't possible with other ping or ultrasonic libraries.
// These kinds of speeds work perfectly with the NewPing library. Even at the maximum sensor distance of
// 500cm, distance measurements can be done 20 times a second! If you set the maximum distance to 200cm
// as we have in this example sketch, even faster pings can be achieved. I suggest waiting at least 37
// milliseconds between pings to avoid previous ping echo issues, that translates to a maximum ping rate
// of around 27 times per second. Much better than the sometimes 1 ping a second with other libraries.
//

#include <NewPing.h>

#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on ping sensor.
#define ECHO_PIN 13// Arduino pin tied to echo pin on ping sensor.
#define MAX_DISTANCE 200
// Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

unsigned int pingSpeed = 50; // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer = 75; // Holds the next ping time, start at 75ms to give time for the Arduino pins to stabilize.

void setup() {
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}

void loop() {
// Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distance pings.
if (millis() >= pingTimer) { // pingSpeed milliseconds since last ping, do another ping.
pingTimer += pingSpeed; // Set the next ping time.
Serial.print("Ping: ");
int cm = sonar.ping_cm(); // Send out the ping, get the results in centimeters.
Serial.print(cm); // Print the result (0 = outside the set distance range, no ping echo)
Serial.println("cm");
}
}
and the output coming is..
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
and continue....
i dont know why,..the sensor is just giving this output
plzz help

Try connecting it to pins 5 and 6 instead of 12 and 13. Also, is there a clear shot in front of your sensors? No wires or stuff in the way? Sensor at the edge of your breadboard? A user sent me a sensor that experienced the same problem on his Arduino, but on mine it works just fine. So, I'm starting to think it's how it's being wired or what the environment is.

Tim

Human:
I'm still amazed you're volunteering to do this :slight_smile: That's dedication!

Can't get your sensor to fail. Works perfect no matter what I try (works better than my 3 semi-working sensors). See my private message to start from the begining as we must be missing something basic here.

Tim

I don't mind posting this in public, since it may benefit others, but I was accidentally using a Duemilenove (2009) board instead of an Uno R3 :blush:

With the 2009 board, the sensor will send a ping, and status output goes to the serial port, but the distance reported is always 0cm. Swapping out the board for an Uno R3 makes it all work with NewPing, and the 2009 board works fine with the code I linked to. I assume that it's something about how NewPing compiles for the 2009's architecture.

I don't know why the 2009 board would have this issue, but at least this explains why my HC-SR04 appeared to be acting strangely.

To sum up:

2009 + NewPing + HC-SR04 = 0cm always
2009 + NewPing + HY-SRF05 = 0cm always
2009 + primitive code + HC-SR04 = works
2009 + primitive code + HY-SRF05 = works
UnoR3 + NewPing + HC-SR04 = works
UnoR3 + NewPing + HY-SRF05 = works
UnoR3 + primitive code + HC-SR04 = works
UnoR3 + primitive code + HY-SRF05 = works

Human:
I don't mind posting this in public, since it may benefit others, but I was accidentally using a Duemilenove (2009) board instead of an Uno R3 :blush:

With the 2009 board, the sensor will send a ping, and status output goes to the serial port, but the distance reported is always 0cm. Swapping out the board for an Uno R3 makes it all work with NewPing, and the 2009 board works fine with the code I linked to. I assume that it's something about how NewPing compiles for the 2009's architecture.

I don't know why the 2009 board would have this issue, but at least this explains why my HC-SR04 appeared to be acting strangely.

To sum up:

2009 + NewPing + HC-SR04 = 0cm always
2009 + NewPing + HY-SRF05 = 0cm always
2009 + primitive code + HC-SR04 = works
2009 + primitive code + HY-SRF05 = works
UnoR3 + NewPing + HC-SR04 = works
UnoR3 + NewPing + HY-SRF05 = works
UnoR3 + primitive code + HC-SR04 = works
UnoR3 + primitive code + HY-SRF05 = works

I guess this is good news, as before it was quite a mystery. My guess is that the Duemilanove 2009 board is somehow different with port registers. Since NewPing uses all port register access and the primitive code uses all built-in high-level pin access commands the two are quite different. Did the Duemilanove 2009 come in both ATmega168 and ATmega328? Which do you have?

Tim

teckel:
I guess this is good news, as before it was quite a mystery. My guess is that the Duemilanove 2009 board is somehow different with port registers. Since NewPing uses all port register access and the primitive code uses all built-in high-level pin access commands the two are quite different. Did the Duemilanove 2009 come in both ATmega168 and ATmega328? Which do you have?

Reading the chip silkscreening itself indicates that it's an ATmega328, which is consistent with the behavior in the IDE.

Human:

teckel:
I guess this is good news, as before it was quite a mystery. My guess is that the Duemilanove 2009 board is somehow different with port registers. Since NewPing uses all port register access and the primitive code uses all built-in high-level pin access commands the two are quite different. Did the Duemilanove 2009 come in both ATmega168 and ATmega328? Which do you have?

Reading the chip silkscreening itself indicates that it's an ATmega328, which is consistent with the behavior in the IDE.

So, the exact same processor as the Uno, darn... I'm thinking that I'll create a couple different test libraries if you're willing to try each. Probably one that replaces the ping echo detection with pulseIn to isolate the problem, then a few variations that do it a little differently.

Let me know if you're willing to do this, should be really quick and simple.

Tim

teckel:
So, the exact same processor as the Uno, darn... I'm thinking that I'll create a couple different test libraries if you're willing to try each. Probably one that replaces the ping echo detection with pulseIn to isolate the problem, then a few variations that do it a little differently.

Let me know if you're willing to do this, should be really quick and simple.

Even if it's not quick and simple, I'd be happy to help.

Hello Teckel.

First of all thanks a mil for your library I think is a lot of job and you are really kind sharing it with us.

I'm new to arduino and I have recently acquired a HC-SR04 sensor and I have donwloaded and installed your library for a test that I'm doing.

This is the little sketch that I'm running and I don't know if it's because I did something wrong but from time to time the sensor returns a 0 value.

#include <NewPing.h>

#define TRIGGER_PIN  7  
#define ECHO_PIN     6  
#define MAX_DISTANCE 200 

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); 
int Range=200;
boolean Alarm=false; 
int Counter = 1;
void setup() {
  Serial.begin(9600); 
}

void loop() {
  
  Range = sonar.ping_cm();
 
delay(20);
  
  if (Range < 10) { 

    Alarm = true;   
    Counter = 1;    
  }
  else if (Counter == 11) { 
    Alarm = false;          
    Counter = 1;
  }
  
  if (Alarm)
    AlarmOn();
  
}

void AlarmOn(){
Serial.print("Intruso en:");  
Serial.println(Range); 
Serial.print("Valor del contador:");  
Serial.println(Counter);  
  Counter++;
  
}

looking at the serial output I see that from time to time the sensor gets a 0 value and I don't know if it's a problem with my sketch or with the sensor itself...

Valor del contador:8
Intruso en:40
Valor del contador:9
Intruso en:40
Valor del contador:10
Intruso en loop:0
Intruso en:0
Valor del contador:1
Intruso en:39
Valor del contador:2
Intruso en:39
Valor del contador:3

I hope you can help thanks :wink: