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

Weissglut: Yes of course. I am useing the 1.9.0-Version. And yes I keep the sketch as simple as possible (like the NewPing Example). So nothing else could disturb the measurement. What do you mean by "try setting ONE_PIN_ENABLED to false" ?

BR Martin

Edit: Okay. I know what you are meaning with "try setting ONE_PIN_ENABLED to false". I set this parameter at the NewPing.h to false, but it did not solve the problem. Every time I reset the ESP8266 I am getting 2 "good" results. After the first 2 results, most of the time I get "0" at the output-monitor. And only a very few times, a trigger was sending...

First, try changing the delay between pings to 1000 ms. It could be that that sensor can't ping as frequently.

Secondly, you could try changing the MAX_SENSOR_DELAY value in NewPing.h from 5800 to maybe 40000. That value is how long to wait for a previous ping to finish. 5800 works for every sensor I have, but it's possible that some sensors need a longer timeout.

Tim

Hi Tim,

now I am back from work to test your tips. I've changed the delay between the pings many times before. This had no effect. I've changed the "MAX_SENSOR_DELAY" also, but no effect :-( That's why I took a look at the trigger signal with the scope. With the NewPing-Lib and the simple sketch I see most of the time a constant high level at the trigger-pin! If I use the method "trigger pulse and evaluation by "pulseIn (echo, HIGH)" without NewPing, I get the trigger and echo impulses that I expect. Any ideas what could be wrong?

Regards Martin

Weissglut: Hi Tim,

now I am back from work to test your tips. I've changed the delay between the pings many times before. This had no effect. I've changed the "MAX_SENSOR_DELAY" also, but no effect :-( That's why I took a look at the trigger signal with the scope. With the NewPing-Lib and the simple sketch I see most of the time a constant high level at the trigger-pin! If I use the method "trigger pulse and evaluation by "pulseIn (echo, HIGH)" without NewPing, I get the trigger and echo impulses that I expect. Any ideas what could be wrong?

Regards Martin

Are you using an ATmega microcontroller or something else?

The only time that NewPing sets the trigger pin to high is for 10 microseconds to initiate the sensor. If the ONE_PIN_ENABLED value is set to true, it then sets the trigger pin to input mode, which is why I suggested setting this to false if you're using two pins anyway.

The last thing I'd try is adding the following two lines right before the "class NewPing {" line in NewPing.h:

#undef DO_BITWISE
#define DO_BITWISE false

This will force it to use Arduino commands instead of bitwise logic on the pins. This would especially be required if not using an AVR ATmega microcontroller.

If this doesn't work, there's probably no way for me to help without having your exact hardware to duplicate it.

Tim

Does NewPing work with an Espressif ESP32 (using Arduino IDE)?

Thanks for any hints

David

DTC57: Does NewPing work with an Espressif ESP32 (using Arduino IDE)?

Thanks for any hints

David

Should. Would take 0.1 seconds to at least see if it compiled.

Tim

Thanks - I got it working. I wasn’t using suitable IO pins the first time around.

Many thanks, I’m still a beginner...

teckel: Are you using an ATmega microcontroller or something else?

The only time that NewPing sets the trigger pin to high is for 10 microseconds to initiate the sensor. If the ONE_PIN_ENABLED value is set to true, it then sets the trigger pin to input mode, which is why I suggested setting this to false if you're using two pins anyway.

The last thing I'd try is adding the following two lines right before the "class NewPing {" line in NewPing.h:

#undef DO_BITWISE
#define DO_BITWISE false

This will force it to use Arduino commands instead of bitwise logic on the pins. This would especially be required if not using an AVR ATmega microcontroller.

If this doesn't work, there's probably no way for me to help without having your exact hardware to duplicate it.

Tim

Hi Tim.

Yesterday I received new hardware (JSN-SR04T-2.0) and now it works. I just had to set the parameter "ONE_PIN_ENABLED to false" ... Nevertheless, many thanks for your help.

However, I have another question: I currently calculate the distance in the following way: duration = sonar.ping (); distance = ((duration / 2) * 0.03435); Result e.g. 233,34cm

If I measure the distance in the following way: float distance = (sonar.ping_cm ()); then I get another result, e.g. 238cm at the same measuring distance. Yes, in the first variant, the temperature and the humidity affect the result, but the result of the second variant is closer to the true measuring distance (237 cm). Why?

Can you explain me how the distance is calculated with "(sonar.ping_cm ())"?

Best regards Martin

Weissglut: However, I have another question: I currently calculate the distance in the following way: duration = sonar.ping (); distance = ((duration / 2) * 0.03435); Result e.g. 233,34cm

If I measure the distance in the following way: float distance = (sonar.ping_cm ()); then I get another result, e.g. 238cm at the same measuring distance. Yes, in the first variant, the temperature and the humidity affect the result, but the result of the second variant is closer to the true measuring distance (237 cm). Why?

Can you explain me how the distance is calculated with "(sonar.ping_cm ())"?

Best regards Martin

If you can believe it, there's actually a debate on what the speed of sound is. Resources will give different values and factor things in like altitude when that doesn't change the speed of sound.

Also, doing floating point math on your calculation increases the size of your code by about 1kb and slows down your script. It's also not typically very important that the distance is exact, it's more about measuring the change in distance. Finally, these ultrasonic sensors are not very accurate to begin with.

Due to the above, I've greatly simplified things with the cm calculation. It just divides by 57. This is actually quite close to the correct number for common indoor temps, it's an integer so it keeps the compiled code size small, and it's much faster than using floating point math.

In the NewPing.h file, the #define US_ROUNDTRIP_CM 57 sets the conversion to cm. You could change this to a floating point number, or anything you wanted, but I'd suggest just leaving it as 57 and using the ping_cm() method as I've found it to be very accurate in normal conditions, with the added benefit of being faster and smaller.

Tim

Hi

I have an SR-05 connected to an ESP32 DevKit C and am using the Arduino IDE to drive things.

It all worked fine for a while: I could reliably measure distances in cm with no problems using the following code snippet:

   unsigned int uS = sonar.ping_median(10);
   sensors.distance = sonar.convert_cm(uS);

Now all of a sudden I only seem to get random results. Mostly zero and then large numbers. I don't think I did anything I should not have. Could it be that I have frizzed the sensor in some way? What could I look for? The placement of the hardware did not change either (as far as I can tell).

Any hints welcome before I go and buy another sensor!

Thanks, David

DTC57: Hi

I have an SR-05 connected to an ESP32 DevKit C and am using the Arduino IDE to drive things.

It all worked fine for a while: I could reliably measure distances in cm with no problems using the following code snippet:

   unsigned int uS = sonar.ping_median(10);
   sensors.distance = sonar.convert_cm(uS);

Now all of a sudden I only seem to get random results. Mostly zero and then large numbers. I don't think I did anything I should not have. Could it be that I have frizzed the sensor in some way? What could I look for? The placement of the hardware did not change either (as far as I can tell).

Any hints welcome before I go and buy another sensor!

Thanks, David

If you didn't change anything and it stopped working, it points to a hardware problem.

To verify, use the test sketch and just the sensor and if that doesn't work (and it did previously), it must be a dead sensor.

Tim

@teckel, maybe in NewPing.h you can change this

#define US_ROUNDTRIP_CM 57

in this

#ifndef US_ROUNDTRIP_CM
#define US_ROUNDTRIP_CM 57
#endif

I am not sure that is written correctly. It mean that if the user doesn't use a define for US_ROUNDTRIP_CM, your library will use the default value of 57. In this way you don't change the library code, since in every update you will lost any changes.

zoomx: @teckel, maybe in NewPing.h you can change this

#define US_ROUNDTRIP_CM 57

in this

#ifndef US_ROUNDTRIP_CM
#define US_ROUNDTRIP_CM 57
#endif

I am not sure that is written correctly. It mean that if the user doesn't use a define for US_ROUNDTRIP_CM, your library will use the default value of 57. In this way you don't change the library code, since in every update you will lost any changes.

NewPing isn't updated very often anyway and you really shouldn't change that value as there's very good reasons why it's set to 57 (speed, accuracy, compiled code size, etc.).

Tim

This is very cool. I feel like I am learning with this fosum

To the NewPing Library moderators:

Hello, and thank you (in advance) for your patience.

Hardware used: Genuine Arduino Uno R3 (made in USA); external power supply - ‘wall wart’ style 120V in, 5V at 2A out; Arduino IDE ver 1.8.5; breadboard - Jameco JE24.

I have looked through this forum, as well as the main Arduino ones, and have not seen my question asked. I apologize if I have been obtuse.

Briefly, I have used an HC_SR04 with the NewPing library. Using the sonar.ping_cm() result(s), I can get and print a reasonably consistent distance from my table to the wall (164 cm, or ca. 64 in).

Please see attachment “test_us-with-servo_05.ino”

My data output has a few instances like this:

Distance to target: 165 cm 64 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 21 in
Distance to target: 165 cm 21 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 21 in

My first question is: why does the distance in centimeters appear to be stable, but the distance in inches (the output of sonar.ping_in()) occasionally get to 1/3rd of what it ought to be - 21 instead of 64 inches? Note that the table support for the HC_SR04 and Arduino is large and unmoving, as is the wall at which the SR04 is pointed. The processing load on the Arduino should be minimal.

Larger data file attachment is “test_us-with-servo_05.txt”

So, despite the odd behavior of the distance in inches, the results for distance in cm seems stable enough for my purposes.

My goal though, was to use the distance function in conjunction with a continuous revolution servo motor, an FS90R from FEETECH. The idea is to have the servo rotating clockwise unless an object comes within the ‘thresHold’ distance, at which point the servo stops moving.

Adding statements to include the <Servo.h> library, and setting up the servo on Arduino digital pin 7 with range statements did not change the previous results.

However, as soon as my code began to communicate with BOTH the HC_SR04 and the FS90R, the accuracy of the HC_SR04 results was destroyed.

Code with HC_SR04 and FS90R in it: attachment “test_us-with-servo_07.ino”

Here is a sample of the output now:

Distance to target: 43 cm 17 in
Distance to target: 50 cm 10 in
Distance to target: 11 cm 11 in
Distance to target: 50 cm 19 in
Distance to target: 60 cm 15 in
Distance to target: 44 cm 17 in
Distance to target: 40 cm 16 in
Distance to target: 31 cm 19 in
Distance to target: 10 cm 12 in
Distance to target: 29 cm 17 in
Distance to target: 42 cm 20 in
Distance to target: 44 cm 13 in
Distance to target: 59 cm 16 in
Distance to target: 44 cm 19 in
Distance to target: 41 cm 13 in
Distance to target: 51 cm 17 in
Distance to target: 44 cm 19 in

I noticed that as bad as the distance in cm results are (the wall is still 164 cm or 64 inches away), the problem with the distance in inches is far worse - every distance is stated incorrectly for the inch values, whereas before, this only happened a few times. How does this relate to the occasional distance in inches problem we saw originally - i.e., without any servo code?

Larger data file attachment is: “test_us-with-servo_07.txt” If you look at the larger data file, you will notice I put a book in front of the SR04 a couple of times to verify the FS90R stopped rotating.

In fact, the servo DOES stop moving when the ‘thresHold’ value is reached [there is a slight stutter every 20 seconds or so as well], but the distance results seem completely unreliable. What have I done incorrectly? I thought I used the NewPing library correctly, but I am not pleased with my results. I have spent a fair amount of time attempting to correct this problem, but it seems as soon as I interact with both devices, my programming skills aren’t up to the challenge.

I would appreciate any suggestions. Sorry for the long-winded explanations. Thank you.

test_us-with-servo_07.ino (2.29 KB)

test_us-with-servo_05.ino (1.52 KB)

test_us-with-servo_05.txt (8.56 KB)

test_us-with-servo_07.txt (36.3 KB)

thehelpdeskguy:
To the NewPing Library moderators:

Hello, and thank you (in advance) for your patience.

Hardware used: Genuine Arduino Uno R3 (made in USA); external power supply - ‘wall wart’ style 120V in, 5V at 2A out; Arduino IDE ver 1.8.5; breadboard - Jameco JE24.

I have looked through this forum, as well as the main Arduino ones, and have not seen my question asked. I apologize if I have been obtuse.

Briefly, I have used an HC_SR04 with the NewPing library. Using the sonar.ping_cm() result(s), I can get and print a reasonably consistent distance from my table to the wall (164 cm, or ca. 64 in).

Please see attachment “test_us-with-servo_05.ino”

My data output has a few instances like this:

Distance to target: 165 cm 64 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 21 in
Distance to target: 165 cm 21 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 21 in

My first question is: why does the distance in centimeters appear to be stable, but the distance in inches (the output of sonar.ping_in()) occasionally get to 1/3rd of what it ought to be - 21 instead of 64 inches? Note that the table support for the HC_SR04 and Arduino is large and unmoving, as is the wall at which the SR04 is pointed. The processing load on the Arduino should be minimal.

Larger data file attachment is “test_us-with-servo_05.txt”

So, despite the odd behavior of the distance in inches, the results for distance in cm seems stable enough for my purposes.

My goal though, was to use the distance function in conjunction with a continuous revolution servo motor, an FS90R from FEETECH. The idea is to have the servo rotating clockwise unless an object comes within the ‘thresHold’ distance, at which point the servo stops moving.

Adding statements to include the <Servo.h> library, and setting up the servo on Arduino digital pin 7 with range statements did not change the previous results.

However, as soon as my code began to communicate with BOTH the HC_SR04 and the FS90R, the accuracy of the HC_SR04 results was destroyed.

Code with HC_SR04 and FS90R in it: attachment “test_us-with-servo_07.ino”

Here is a sample of the output now:

Distance to target: 43 cm 17 in
Distance to target: 50 cm 10 in
Distance to target: 11 cm 11 in
Distance to target: 50 cm 19 in
Distance to target: 60 cm 15 in
Distance to target: 44 cm 17 in
Distance to target: 40 cm 16 in
Distance to target: 31 cm 19 in
Distance to target: 10 cm 12 in
Distance to target: 29 cm 17 in
Distance to target: 42 cm 20 in
Distance to target: 44 cm 13 in
Distance to target: 59 cm 16 in
Distance to target: 44 cm 19 in
Distance to target: 41 cm 13 in
Distance to target: 51 cm 17 in
Distance to target: 44 cm 19 in

I noticed that as bad as the distance in cm results are (the wall is still 164 cm or 64 inches away), the problem with the distance in inches is far worse - every distance is stated incorrectly for the inch values, whereas before, this only happened a few times. How does this relate to the occasional distance in inches problem we saw originally - i.e., without any servo code?

Larger data file attachment is: “test_us-with-servo_07.txt” If you look at the larger data file, you will notice I put a book in front of the SR04 a couple of times to verify the FS90R stopped rotating.

In fact, the servo DOES stop moving when the ‘thresHold’ value is reached [there is a slight stutter every 20 seconds or so as well], but the distance results seem completely unreliable. What have I done incorrectly? I thought I used the NewPing library correctly, but I am not pleased with my results. I have spent a fair amount of time attempting to correct this problem, but it seems as soon as I interact with both devices, my programming skills aren’t up to the challenge.

I would appreciate any suggestions. Sorry for the long-winded explanations. Thank you.

You’re just getting random values as you’ve never setup NewPing. You open the library and then try to use it without setting it up. Something like this is missing:

NewPing sonar(trigPin, echoPin, maxDist);

Please see the NewPing example code. Basically, you’re never setting up which pins to even ping with nor setting up NewPing at all. Surprised it even compiled as you’ve never setup sonar.

Tim

Mr. Teckel:

Thank you for the response. If I did not set up the NewPing correctly, would you please tell me what is incorrect with the code from my attached file "test_us-with-servo_07.ino, which I used to generate those results:

#include <NewPing.h>
#include <Servo.h>

Servo myservo;

const int trigPin = 9; // Arduino pin tied to trigger pin on the ultrasonic sensor.
const int echoPin = 10; // Arduino pin tied to echo pin on the ultrasonic sensor.
const int maxDist = 400; // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated as 400-500cm.
long unsigned thresHold; // if object closer than this (in cms), do something

void setup() {

Serial.begin(9600); // Open serial monitor at 9600 baud to see ping results (NOTE: 115200 DOES NOT WORK).
myservo.attach(7, 544, 2400); //attach the servo, set the pin for the servo control, and range if desired
thresHold = 20; // when an object is closer than 20 cm (ca. 8 inches), we will do something - stop the motor
}

void loop() {
NewPing sonar(trigPin, echoPin, maxDist); // NewPing setup of pins and maximum distance.
delay(100); // Wait 100ms between pings (about 10 pings/sec). 29ms should be the shortest delay between pings.
long unsigned distIn_in;
long unsigned distIn_cm;
distIn_in = sonar.ping_in();
distIn_cm = sonar.ping_cm();
Serial.print(“Distance to target: \t “);
Serial.print(sonar.ping_cm()); // Send ping, get distance in cm (centimeters) and print result (0 = outside set distance range)
Serial.print(” cm \t”);
Serial.print(sonar.ping_in()); // Send ping, get distance in in (inches) and print result (0 = outside set distance range)
Serial.println(" in");
myservo.write(180);
if ( (distIn_cm <= thresHold) && (distIn_cm != 0) )
{
myservo.write(90);
}
}

I believe the first line after “void loop() {” has the suggested setup.

I am sorry if I have misunderstood something. Thank you for your time.

thehelpdeskguy:
Mr. Teckel:

Thank you for the response. If I did not set up the NewPing correctly, would you please tell me what is incorrect with the code from my attached file "test_us-with-servo_07.ino, which I used to generate those results:

#include <NewPing.h>
#include <Servo.h>

Servo myservo;

const int trigPin = 9; // Arduino pin tied to trigger pin on the ultrasonic sensor.
const int echoPin = 10; // Arduino pin tied to echo pin on the ultrasonic sensor.
const int maxDist = 400; // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated as 400-500cm.
long unsigned thresHold; // if object closer than this (in cms), do something

void setup() {

Serial.begin(9600); // Open serial monitor at 9600 baud to see ping results (NOTE: 115200 DOES NOT WORK).
myservo.attach(7, 544, 2400); //attach the servo, set the pin for the servo control, and range if desired
thresHold = 20; // when an object is closer than 20 cm (ca. 8 inches), we will do something - stop the motor
}

void loop() {
NewPing sonar(trigPin, echoPin, maxDist); // NewPing setup of pins and maximum distance.
delay(100); // Wait 100ms between pings (about 10 pings/sec). 29ms should be the shortest delay between pings.
long unsigned distIn_in;
long unsigned distIn_cm;
distIn_in = sonar.ping_in();
distIn_cm = sonar.ping_cm();
Serial.print(“Distance to target: \t “);
Serial.print(sonar.ping_cm()); // Send ping, get distance in cm (centimeters) and print result (0 = outside set distance range)
Serial.print(” cm \t”);
Serial.print(sonar.ping_in()); // Send ping, get distance in in (inches) and print result (0 = outside set distance range)
Serial.println(" in");
myservo.write(180);
if ( (distIn_cm <= thresHold) && (distIn_cm != 0) )
{
myservo.write(90);
}
}

I believe the first line after “void loop() {” has the suggested setup.

I am sorry if I have misunderstood something. Thank you for your time.

See the example sketch for NewPing. Here’s an example: teckel12 / Arduino New Ping / wiki / Home — Bitbucket

Notice where the NewPing sonar() is located. It’s not in the loop() as you’re doing. I’m surprised it works at all as you’re not following how you setup a library. Nowhere do I setup NewPing inside the loop(). That would run on each loop. You only need to setup the library once. Again, just look at the example sketches (one is linked above) and it should be obvious.

Tim

Tim, congrats for the great library! Helped me a lot.

I'm using two HC-SR04 to return me the angle of inclination of a given wall, it's working great, but the angles i need to read are very small and the round numbers that ping_cm gives me doesnt help.

My question is: how do i get measures to the mm level? maybe a silly question but i'm not familiar with programing...

Many THanks.

Luthiano: Tim, congrats for the great library! Helped me a lot.

I'm using two HC-SR04 to return me the angle of inclination of a given wall, it's working great, but the angles i need to read are very small and the round numbers that ping_cm gives me doesnt help.

My question is: how do i get measures to the mm level? maybe a silly question but i'm not familiar with programing...

Many THanks.

First, you really can't as the sensor isn't really that accurate (see the spec sheet of the sensor). But, if you'd really like to calculate distance to the mm, just use the ping() method and then divide that number by the speed of sound at your sampling temp to convert time to mm.

But like I said, it's kinda pointless as the sensor isn't mm accurate, which is why there's a ping_cm() and not a ping_mm() as it really wouldn't be more valuable.

Please read the spec sheet for your sensor, and the bitbucket page for NewPing, everything is explained there.

Tim

Hello,

The NewPing is amazing and it worked great with Arduino mega I used single pin of Mega for Trigger and Echo signals of Ultrasonic sensor HC-sr04 and it worked fine.

However when I try to use one pin for signals in ESP32 I get 0cm value in result everytime. If I use two pins for sensor on esp32 everything works fine but I am unable to use single pin of esp32.

Please help me in understanding what is wrong here? Are there any changes to be made in library for using one pin functionality on esp32.

I have also attached the code I am using.

Ultrasonic_ping.ino (436 Bytes)