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

Hello Tim,

Thanks for your clarifications. I followed your instructions and modified your excellent code so readings are in millimeters.

To avoid using Float numbers I simply use millimeters in the US_ROUNDTRIP_MM value.

Since some readings are Zero when they shouldn’t be (in my case they can never be zero), I exclude those readings.

I also average 5 consecutive readings so the calculated distance is more stable.

I am attaching your modified code in case someone else is interested.

Thanks again for your excellent code and your help!

// ---------------------------------------------------------------------------
// Example NewPing library sketch that calculates distance in MILLIMETERS
// ---------------------------------------------------------------------------

#include <NewPing.h>

#define TRIGGER_PIN  2  // ESP32 pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     5  // ESP32 pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 2000 // Maximum distance we want to ping for (in millimeters). Maximum sensor distance is rated at 4000-5000mm.
#define US_ROUNDTRIP_MM 5650 // Roundtrip sound speed mm/microseconds (In my case 5650 gave me most accurate distance)

int d;
int d1;
int i = 0;
int daverage = 0;  // average of 5 sonar.ping() readings


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

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

void loop() {
  delay(50);           // Wait 50ms between pings. 29ms should be the shortest delay between pings.
  Serial.println("Ping: ");
i = 1;
  while (i <= 5) {
    
  d = sonar.ping();

  if (d == 0)  d = sonar.ping();
  
  daverage = daverage + d;
  i++;
  }

  d=daverage/5;
  daverage = 0;

  Serial.print (" Average ping time in microseconds = ");
  Serial.println (d);
  
  d1 = ((1000*d / US_ROUNDTRIP_MM));   //  Calculate Distance in mm

  Serial.print("Distance = ");
  Serial.print(d1);  // Print distance in m
  Serial.println("mm  ");
  Serial.println(" ");
  delay(1000); //  Wait 1 second until next reading (can be zero or any other number) 
}

Hi, thanks for the great job.
I’m trying to use the median filter.
How can I make 10 (1 reading every 2 seconds one from the other) and perform the median of these in order to have a more stable reading? I have seen that in the library there is the possibility of varying the distance between the pings (of default is 29 milliseconds) but I can’t find an example to take this to 10 seconds.
Thanks for your help. Greetings Fabio

fafidio: Hi, thanks for the great job. I'm trying to use the median filter. How can I make 10 (1 reading every 2 seconds one from the other) and perform the median of these in order to have a more stable reading? I have seen that in the library there is the possibility of varying the distance between the pings (of default is 29 milliseconds) but I can't find an example to take this to 10 seconds. Thanks for your help. Greetings Fabio

It's not designed to work like that. The ping_median() method is designed to take several samples over a short period of time and return the median time. You would need to write your own code to do what you're looking to do as it's non-typical.

Tim

thanks for reply.

could you suggest an example to do it?

thanks Fabio

fafidio: thanks for reply.

could you suggest an example to do it?

thanks Fabio

The example sketch does a ping every about 30ms, just change that to 1000ms for once a second. Then, do whatever averaging you want to do on those pings. There's a million ways of averaging numbers, and it has nothing to do with NewPing.

You could (for example) take the previous ping result, multiply it by 9, add the new ping result, and divide the sum by 10. That would average out the pings over the last 10 seconds.

But, there's many ways to average results. It all depends on what kind of average you're looking for. Mean, median, mode, etc. Running average, average over a certain amount of time, etc.

There's no way to write it for you, as it depends on what you want. But, you can expand your search outside a sonar distance sensor as you're now just working with number results, and any C language information will work helping guild you to write the averaging code you're looking for.

Tim

Sir, I am starting to use HC-SR04 ultrasonic sensor with Arduino DUE. May I ask which library I should use with NewPing Library. And could you tell important details it may help me to be succeed. I am a begginer.

Murat_Artan: Sir, I am starting to use HC-SR04 ultrasonic sensor with Arduino DUE. May I ask which library I should use with NewPing Library. And could you tell important details it may help me to be succeed. I am a begginer.

I assume you mean what methods to use with the NewPing Library? ping() ping_cm() ping_in() ping_median() will all work with the Due. The timer methods won't work as they require the ATmega chip.

Tim

I was going to work with ping() ping_cm() ping_in() ping_median(). Thank you

Hello and happy new year!

Quick question regarding platform support; does this library provide support for the newer range of boards? i.e. the Nano Every - which is to replace the nano. It's an ATMega4809 chip.

Based on the output, it looks like this board misses some timers.

edit - Looking at the official site (which I couldn't find before posting, apologies) it seems this hardware is indeed unsupported.

https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home

swilkens:
Hello and happy new year!

Quick question regarding platform support; does this library provide support for the newer range of boards? i.e. the Nano Every - which is to replace the nano. It’s an ATMega4809 chip.

Based on the output, it looks like this board misses some timers.

edit - Looking at the official site (which I couldn’t find before posting, apologies) it seems this hardware is indeed unsupported.

teckel12 / Arduino New Ping / wiki / Home — Bitbucket

swilkens:
Hello and happy new year!

Quick question regarding platform support; does this library provide support for the newer range of boards? i.e. the Nano Every - which is to replace the nano. It’s an ATMega4809 chip.

Based on the output, it looks like this board misses some timers.

edit - Looking at the official site (which I couldn’t find before posting, apologies) it seems this hardware is indeed unsupported.

teckel12 / Arduino New Ping / wiki / Home — Bitbucket

There’s been a lot of new hardware released over the years. As new hardware is released, the library may be tweaked to fully accommodate new boards. The latest boards are no different.

Like always, the library will work with ALL boards with the non-timer methods. The timer methods may require code to accommodate. Anyone is free to submit a pull request that will add support for a new chipset, just like always.

In other words, NewPing will work with the latest boards, and the timer methods will also work as the community submits a pull request to accommodate. This is how it always has been and still is true today.

Hi, I try to use SR04T with arduino Uno and newping to measure distance under water ... Do you think it's possible and when ? I dont' find examples .... I have some results over 80cm but it' s not so good... Olivier 31830

Olivier31830: Hi, I try to use SR04T with arduino Uno and newping to measure distance under water ... Do you think it's possible and when ? I dont' find examples .... I have some results over 80cm but it' s not so good... Olivier 31830

The sensor your using is designed to measure solid surface objects through the air. They won't work underwater. You would need to use a sensor designed for underwater usage.

Tim

Hello! Thanks for this lovely library!
I’m using the following code to tell an actuator to move positions when something is in the way. I’ve got it to “stop,” to adjust the actuator when something is in the way, but I cannot figure out where/how to add code to say “nothing is in the way, hold actuator in this position”
Said another wait, if nothing is sensed to actuator should be in “Go” position, when something is sense it’s changed to “Stop” position.
Thanks!

/*
Vehicle will have four sensors across the front.
Sensors are named by location: Left (L), Middle Left (ML), Middle Right (MR), Right (R)
Sensors Used: JSN-SR04T / RB-Dfr-720 :: Weatherproof Ultrasonic Sensor w/ Separate Probe

Uses NewPing Library: teckel12 / Arduino New Ping / wiki / Home — Bitbucket
*/

#include <NewPing.h>

#define SONAR_NUM 4 // Number of sensors.
#define MAX_DISTANCE 130 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33
unsigned long pingTimer[SONAR_NUM];
uint8_t currentSensor = 0;

NewPing sonar[SONAR_NUM] = { // Sensor object array.
NewPing(3, 2, MAX_DISTANCE), // Each sensor’s trigger pin, echo pin, and max distance to ping.
NewPing(5, 4, MAX_DISTANCE),
NewPing(6, 7, MAX_DISTANCE),
NewPing(9, 8, MAX_DISTANCE)
};

void setup(void)
{
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
pingTimer[0] = millis() + 75;
for (uint8_t i = 1; i < SONAR_NUM; i++)
pingTimer = pingTimer[i - 1] + PING_INTERVAL;

  • pinMode(0, OUTPUT);*
  • pinMode(11, OUTPUT);*
  • pinMode(12, OUTPUT);*
    }
    void loop() {
    for (uint8_t i = 0; i < SONAR_NUM; i++) {
    _ if (millis() >= pingTimer*) {_
    pingTimer += PING_INTERVAL * SONAR_NUM;
    sonar[currentSensor].timer_stop();
    _ currentSensor = i;_
    sonar[currentSensor].ping_timer(echoCheck);
    _ }
    }*
    // Other code that DOESN’T analyze ping results can go here._

}
void echoCheck() {
if (sonar[currentSensor].check_timer())
* pingResult(currentSensor, sonar[currentSensor].ping_result / US_ROUNDTRIP_CM);*

}
void pingResult(uint8_t sensor, int cm) {
// The following code would be replaced with your code that does something with the ping result.
Serial.print(sensor);
Serial.print(" ");
Serial.print(cm);
Serial.println(“cm”);
digitalWrite(12, HIGH);
delay(20);
digitalWrite(11, LOW);
Serial.println(“STOP”);
delay(100);

}

tsmacinspires:
Hello! Thanks for this lovely library!
I’m using the following code to tell an actuator to move positions when something is in the way. I’ve got it to “stop,” to adjust the actuator when something is in the way, but I cannot figure out where/how to add code to say “nothing is in the way, hold actuator in this position”
Said another wait, if nothing is sensed to actuator should be in “Go” position, when something is sense it’s changed to “Stop” position.
Thanks!

/*
Vehicle will have four sensors across the front.
Sensors are named by location: Left (L), Middle Left (ML), Middle Right (MR), Right (R)
Sensors Used: JSN-SR04T / RB-Dfr-720 :: Weatherproof Ultrasonic Sensor w/ Separate Probe
http://www.robotshop.com/en/weatherproof-ultrasonic-sensor-separate-probe.html
Uses NewPing Library: teckel12 / Arduino New Ping / wiki / Home — Bitbucket
*/

#include <NewPing.h>

#define SONAR_NUM 4 // Number of sensors.
#define MAX_DISTANCE 130 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33
unsigned long pingTimer[SONAR_NUM];
uint8_t currentSensor = 0;

NewPing sonar[SONAR_NUM] = { // Sensor object array.
NewPing(3, 2, MAX_DISTANCE), // Each sensor’s trigger pin, echo pin, and max distance to ping.
NewPing(5, 4, MAX_DISTANCE),
NewPing(6, 7, MAX_DISTANCE),
NewPing(9, 8, MAX_DISTANCE)
};

void setup(void)
{
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
pingTimer[0] = millis() + 75;
for (uint8_t i = 1; i < SONAR_NUM; i++)
pingTimer = pingTimer[i - 1] + PING_INTERVAL;

  • pinMode(0, OUTPUT);*
  • pinMode(11, OUTPUT);*
  • pinMode(12, OUTPUT);*
    }
    void loop() {
    for (uint8_t i = 0; i < SONAR_NUM; i++) {
    _ if (millis() >= pingTimer*) {_
    pingTimer += PING_INTERVAL * SONAR_NUM;
    sonar[currentSensor].timer_stop();
    _ currentSensor = i;_
    sonar[currentSensor].ping_timer(echoCheck);
    _ }
    }*
    // Other code that DOESN’T analyze ping results can go here._

}
void echoCheck() {
if (sonar[currentSensor].check_timer())
* pingResult(currentSensor, sonar[currentSensor].ping_result / US_ROUNDTRIP_CM);*

}
void pingResult(uint8_t sensor, int cm) {
// The following code would be replaced with your code that does something with the ping result.
Serial.print(sensor);
Serial.print(" ");
Serial.print(cm);
Serial.println(“cm”);
digitalWrite(12, HIGH);
delay(20);
digitalWrite(11, LOW);
Serial.println(“STOP”);
delay(100);

}
[/quote]
That code will never work how you’re using it. Can I ask where you got that base code from? I need to somehow get people to stop using it and without knowing where you are getting the code I can’t stop people from using it.
Basically, you’re using two different programming paradigms in the same program, which simply isn’t going to work. I can give you the correct base code you should be using, but I really need to know how exactly you decided to use this code in the first place to stop the insanity!
Tim

I found the code on this forum, about halfway through the 80 pages. I was searching for code that uses four sensors and the median function. I couldn't get median to work with multiple sensors on my own using the tips you have provided (sorry I'm not a great coder). I sincerely appreciate your support to this community and will donate.

Basically I have four sensors attached to the front of a vehicle, and an actuator adjusting throttle (it has two positions controlled by pins 11 and 12). If nothing is in front of the vehicle the Arduino sends: digitalWrite(11, HIGH); // Pin for actuator position "Go" delay(20); digitalWrite(11, LOW); // Turn Off Pin for actuator position "Go" (maintains position) Serial.println("GO");

If something is detected: digitalWrite(12, HIGH); // Pin for actuator position "Stop" delay(20); digitalWrite(12, LOW); // Turn Off Pin for actuator position "Go" (maintains position) Serial.println("STOP");

tsmacinspires:
I found the code on this forum, about halfway through the 80 pages. I was searching for code that uses four sensors and the median function. I couldn’t get median to work with multiple sensors on my own using the tips you have provided (sorry I’m not a great coder). I sincerely appreciate your support to this community and will donate.

Better to start with the official page and the included examples.

Specifically, there’s a 3 sensor sketch linked on my home page.

For 4 sensors, you just change SONAR_NUM and the sensor array appropriately.

tsmacinspires:
Basically I have four sensors attached to the front of a vehicle, and an actuator adjusting throttle (it has two positions controlled by pins 11 and 12). If nothing is in front of the vehicle the Arduino sends:
digitalWrite(11, HIGH); // Pin for actuator position “Go”
delay(20);
digitalWrite(11, LOW); // Turn Off Pin for actuator position “Go” (maintains position)
Serial.println(“GO”);

If something is detected:
digitalWrite(12, HIGH); // Pin for actuator position “Stop”
delay(20);
digitalWrite(12, LOW); // Turn Off Pin for actuator position “Go” (maintains position)
Serial.println(“STOP”);

To do what you want, you would just replace the loop() in the above 3 sensor sketch with something like this:

void loop() {
  bool object_detected = false;
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through each sensor and display results.
    if (sonar[i].ping(130) > 0) {
      object_detected = true;
      break;
    }
  }
  if (object_detected == true) {
    digitalWrite(12, HIGH); // Pin for actuator position "Stop"
    delay(20);
    digitalWrite(12, LOW);  // Turn Off Pin for actuator position "Go" (maintains position)
  } else {
    digitalWrite(11, HIGH); // Pin for actuator position "Go"
    delay(20);
    digitalWrite(11, LOW);  // Turn Off Pin for actuator position "Go" (maintains position)
  }
  delay(30);
}

But, that’s under the condition that’s really what you want to do anytime any sensor detects anything in front of the sensors or not, which I question. Basically, the NewPing logic is correct, but what you do with the information is difficult if not impossible to assist you with without the hardware and a better understanding of how the logic really should work. But, that should give you a good start.

In total, here’s probably what your code would look like:

#include <NewPing.h>

#define SONAR_NUM 4      // Number of sensors.
#define MAX_DISTANCE 130// Maximum distance (in cm) to ping.

NewPing sonar[SONAR_NUM] = {   // Sensor object array.
  NewPing(3, 2, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(5, 4, MAX_DISTANCE),
  NewPing(6, 7, MAX_DISTANCE),
  NewPing(9, 8, MAX_DISTANCE)
};

void setup(void) {
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
}

void loop() {
  bool object_detected = false;
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through each sensor and display results.
    if (sonar[i].ping() > 0) {
      object_detected = true;
      break;
    }
  }
  if (object_detected == true) {
    digitalWrite(12, HIGH); // Pin for actuator position "Stop"
    delay(20);
    digitalWrite(12, LOW);  // Turn Off Pin for actuator position "Go" (maintains position)
  } else {
    digitalWrite(11, HIGH); // Pin for actuator position "Go"
    delay(20);
    digitalWrite(11, LOW);  // Turn Off Pin for actuator position "Go" (maintains position)
  }
  delay(30);
}

But again, just a guess without carnal knowledge. I hope you can see how this is keeping it simple, so it’s easy to understand and extend to do what you want, unlike the sample code you were trying to use which requires a much better understanding of timers and event-driven programming.

Tim

I cannot seem to get my code to work, I don’t know what I am doing wrong.
Please Help
Getting the error:

Arduino: 1.8.10 (Windows 10), Board: “Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)”

C:\Users\disstudent\Desktop\fix\fix.ino:15:0: warning: “TRIGGER_PIN” redefined

#define TRIGGER_PIN 10 // Arduino pin tied to trigger pin on the ultrasonic sensor.

C:\Users\disstudent\Desktop\fix\fix.ino:9:0: note: this is the location of the previous definition

#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on the ultrasonic sensor.

C:\Users\disstudent\Desktop\fix\fix.ino:16:0: warning: “ECHO_PIN” redefined

#define ECHO_PIN 9 // Arduino pin tied to echo pin on the ultrasonic sensor.

C:\Users\disstudent\Desktop\fix\fix.ino:10:0: note: this is the location of the previous definition

#define ECHO_PIN 11 // Arduino pin tied to echo pin on the ultrasonic sensor.

Tone.cpp.o (symbol from plugin): In function `timer0_pin_port’:

(.text+0x0): multiple definition of `__vector_13’

libraries\NewPing\NewPing.cpp.o (symbol from plugin):(.text+0x0): first defined here

c:/program files (x86)/arduino/hardware/tools/avr/bin/…/lib/gcc/avr/7.3.0/…/…/…/…/avr/bin/ld.exe: Disabling relaxation: it will not work with multiple definitions

collect2.exe: error: ld returned 1 exit status

Multiple libraries were found for “NewPing.h”
Used: C:\Users\disstudent\Documents\Arduino\libraries\NewPing
exit status 1
Error compiling for board Arduino/Genuino Mega or Mega 2560.

This report would have more information with
“Show verbose output during compilation”
option enabled in File → Preferences.
[/b]

#include <NewPing.h>

#define pingSpeed 100 // Ping frequency (in milliseconds), fastest we should ping is about 35ms per sensor
unsigned long pingTimer1, pingTimer2;

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

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

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

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

void setup() {

Serial.begin(115200);//Open Serial Monitor
pingTimer1 = millis() + pingSpeed; // Sensor 1 fires after 100ms (pingSpeed)
pingTimer2 = pingTimer1 + (pingSpeed / 2); // Sensor 2 fires 50ms later
}

void loop() {

if (millis() >= pingTimer1) {
pingTimer1 += pingSpeed; // Make sensor 1 fire again 100ms later (pingSpeed)
int in1 = sonar1.ping_in();
}
if (millis() >= pingTimer2) {
pingTimer2 = pingTimer1 + (pingSpeed / 2); // Make sensor 2 fire again 50ms after sensor 1 fires
int in2 = sonar2.ping_in();
// Both sensors pinged, process results here

delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.

unsigned int uS = sonar1.ping(); // Send ping, get ping time in microseconds (uS).
Serial.print("Ping: ");
Serial.print(sonar1.convert_cm(uS)); // Convert ping time to distance and print result (0 = outside set distance range, no ping echo)
Serial.println(“cm”);

unsigned int US = sonar2.ping(); // Send ping, get ping time in microseconds (uS).
Serial.print("Ping: ");
Serial.print(sonar2.convert_cm(uS)); // Convert ping time to distance and print result (0 = outside set distance range, no ping echo)
Serial.println(“cm”);

if (uS < 18) //If Sonar1 distance is less than 18cm
tone (3,50,200); //a buzzer on port 3 will go off
if (US<18) //If Sonar2 distance is less than 18cm
tone (4,50,2000); // a buzzer on port 4 will go off
}
// Do other stuff here, notice how there’s no delays in this sketch, so you have processing cycles to do other things :slight_smile:
}

fix.ino (2.58 KB)

Ok, cool - so your code is mostly working, but I'm getting a good amount of false "goes." If placing an item in front of any of the sensors it will send a signal to "STOP," however if I keep holding it there it sends a "GO" signal even though I'm in front of the sensors, it happens rather quickly. So instead of it staying at stop, if I'm standing in front of the sensors it basically goes from STOP to GO back and forth. Any ideas? Thanks so much! Sensors used: JSN-SR04T Microcontroller: Arduino Uno Uno has three pins connected to transistors which control grounding thee different wires from the following device (three different wires, when grounded, go to three different positions): https://www.northerntool.com/shop/tools/product_200520503_200520503 That device is connected to: https://www.northerntool.com/shop/tools/product_200520510_200520510

richmona:
I cannot seem to get my code to work, I don’t know what I am doing wrong.

You’re using code that you don’t understand as a basis. And where the hell is everyone getting that code from and trying to use it without knowing how to code? Please tell me were you got it so I can stop these constant questions about using the wrong code for your coding abilities.

Please see the official NewPing site, use code examples from that page, and read the warnings about some of the examples that are HEAVILY discouraged for you to use if you’re not an expert.

I can’t and will not help debug your code if you’re not using my examples and heeding all the warnings.

STOP THE INSANITY!!!

tsmacinspires: Ok, cool - so your code is mostly working, but I'm getting a good amount of false "goes." If placing an item in front of any of the sensors it will send a signal to "STOP," however if I keep holding it there it sends a "GO" signal even though I'm in front of the sensors, it happens rather quickly. So instead of it staying at stop, if I'm standing in front of the sensors it basically goes from STOP to GO back and forth. Any ideas? Thanks so much! Sensors used: JSN-SR04T Microcontroller: Arduino Uno Uno has three pins connected to transistors which control grounding thee different wires from the following device (three different wires, when grounded, go to three different positions): https://www.northerntool.com/shop/tools/product_200520503_200520503 That device is connected to: https://www.northerntool.com/shop/tools/product_200520510_200520510

It sounds more like the code IS working, but your understanding of the results you are seeing is the issue.

What kind of object are you putting in front of the sensor? How big is it? What kind of surface does it have? What if you replace the object with a large flat board placed at 90 degrees from the sensor? What about doing multiple pings using the ping-median() method instead or writing your own function to ping multiple times?

Basically, this isn't a problem with the NewPing library or even with sample code. The problem is understanding the physics of sonar and knowing how to write code to solve your unique problem.