Arduino library 路 Sensors

NewPing: fast, filtered ultrasonic readings

NewPing by Tim Eckel was written because the usual pulseIn() approach to the HC-SR04 waits up to a second for an echo that is not coming. NewPing takes a maximum distance in its constructor and stops listening once sound could have gone that far and back, so a missed echo costs a few milliseconds instead of stalling the sketch.

Built in on Mokxi: #include <NewPing.h> and it builds, with nothing to install. Free, and no account needed.

What NewPing does

A ping that gets no echo inside that distance returns 0, not a large number. That is the most important thing to handle in a NewPing sketch: treat 0 as "nothing in range" rather than as an object touching the sensor.

ping_median() fires several pings, throws away the ones that failed and returns the middle value, which cleans up the odd wild reading from a soft or angled target. Upstream also offers ping_timer(), which runs the ping from a timer interrupt; in Mokxi it does the whole ping at once and then calls your function, so the result is the same but the sketch does not keep running meanwhile.

Library Manager nameNewPing
AuthorTim Eckel
Include#include <NewPing.h>
Boardsevery board Mokxi compiles for
In the simulatorRuns, with a gap the note below names.
Parts it drivesUltrasonic ranger

Install it

It builds on every board Mokxi compiles for.

In Mokxi it is built in: #include <NewPing.h> and the sketch compiles, with no download, no zip and no Library Manager.

On a real board, install "NewPing" by Tim Eckel from the Arduino IDE鈥檚 Library Manager (Sketch, Include Library, Manage Libraries), or add NewPing to lib_deps in PlatformIO. Mokxi follows the calls of release 1.9.7, so a sketch written here builds there too.

What to know in the simulator: ping_timer() does the whole ping and then calls the sketch鈥檚 function once, rather than from a timer interrupt.

ESP32-C3 路 Arduino Uno 路 Arduino Nano 路 Arduino Mega 2560 路 Arduino Leonardo 路 SparkFun Pro Micro 路 Arduino Micro 路 ESP32-C6 路 ATtiny85 路 Raspberry Pi Pico 路 Raspberry Pi Pico W 路 Seeed XIAO SAMD21 路 STM32 路 STM32 Nucleo-F411RE 路 STM32 Blue Pill 路 micro:bit V2 路 Arduino Uno R4 路 ESP32 DevKit 路 ESP32-S3-DevKitC-1 路 ESP8266 NodeMCU 路 Arduino Pro Mini 3.3 V 路 Seeed XIAO ESP32-C3 路 ESP32-C3 SuperMini 路 Seeed XIAO ESP32-C6 路 ESP32-DevKitC V4 路 LOLIN32 Lite 路 Wemos D1 R32 路 Cheap Yellow Display 路 TTGO T-Display 路 Seeed XIAO ESP32-S3 路 Arduino Nano ESP32 路 Arduino Nano RP2040 Connect 路 Seeed XIAO RP2040 路 Waveshare RP2040-Zero 路 Arduino Uno R4 WiFi

The calls you will use

In the order a sketch meets them.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE)

Creates the sensor with its pins and the farthest distance in centimeters worth waiting for (up to 500).

sonar.ping_cm()

One ping, returned in whole centimeters, or 0 when nothing came back within the maximum distance.

unsigned int cm = sonar.ping_cm();
if (cm == 0) Serial.println("out of range");
else Serial.println(cm);

sonar.ping_in()

The same in inches.

sonar.ping_median(5)

Five pings, failures dropped, the middle one returned as an echo time in microseconds.

sonar.convert_cm(echoTime)

Turns an echo time from ping() or ping_median() into centimeters.

sonar.ping_timer(echoCheck)

Starts a ping that calls echoCheck() when done; inside it, check_timer() is true and ping_result holds the echo time.

Example: Distance with an HC-SR04

On the Arduino Uno R3. It runs in the browser exactly as printed.

sketch.ino 路 Arduino Uno R3
#include <NewPing.h>

#define TRIGGER_PIN 12
#define ECHO_PIN 11
#define MAX_DISTANCE 200

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

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

void loop() {
  delay(50);
  Serial.print("Ping: ");
  Serial.print(sonar.ping_cm());
  Serial.println("cm");
}

Wiring

  • Arduino Uno R3 12 to Ultrasonic ranger TRIG
  • Arduino Uno R3 11 to Ultrasonic ranger ECHO
  • Arduino Uno R3 5V to Ultrasonic ranger VCC
  • Arduino Uno R3 GND to Ultrasonic ranger GND

Open it in the editor, wired and ready to run

Common errors and how to fix them

ping_cm() returns 0

Zero means no echo inside MAX_DISTANCE. Raise the maximum in the constructor if the target is far, and check the echo wire. Filter zeros out before averaging, or use ping_median(), which ignores them.

multiple definition of '__vector_7' when the sketch also uses tone()

On an Uno, NewPing鈥檚 timer code and tone() both claim Timer 2. If you do not use ping_timer(), comment out the timer functions as the NewPing docs describe, or use a tone library on another timer.

Readings are a few centimeters short or long

Sound speed changes with temperature. NewPing assumes about 20 C; for better accuracy take ping() or ping_median() and convert the time yourself with the speed of sound at your temperature.

Try NewPing without installing anything

Open the example, change the sketch, and keep your version in a free account.