NewPing Library for Arduino
Author:  Tim Eckel
Contact: tim@leethost.com


Navigation


History

ReleaseDateChanges
1.58/15/2012New ping_median() method does multiple pings and returns the median (digital filter).
1.47/14/2012Interface with sensors using only one Arduino pin.
1.36/8/2012Supports a timer-based ping method.
1.25/25/2012Rebuilt the ping timing code from scratch, now yields very accurate results.
1.15/16/2012Uses port registers for ultra-fast and lean code.
1.05/15/2012Initial Release.

Background

When I first received an ultrasonic sensor I was not happy with how poorly it performed. I soon realized the problem wasn't the sensor, it was the available ping and ultrasonic libraries causing the problem. The NewPing library totally fixes these problems, adds many new features, and breathes new life into these very affordable distance sensors.


Features

  • Works with many different ultrasonic sensor models: SR04, SRF05, SRF06, DYP-ME007 & Parallax PING)))™.
  • Option to interface with all but the SRF06 sensor using only one Arduino pin.
  • Doesn't lag for a full second if no ping echo is received like all other ultrasonic libraries.
  • Ping sensors consistently and reliably at up to 30 times per second.
  • Timer interrupt method for event-driven sketches.
  • Built-in digital filter method ping_median() for easy error correction.
  • Uses port registers when accessing pins for faster execution and smaller code size.
  • Allows setting of a maximum distance where pings beyond that distance are read as no ping "clear".
  • Ease of using multiple sensors (example sketch with 15 sensors).
  • More accurate distance calculation (cm, inches & uS).
  • Doesn't use pulseIn, which is slow and gives incorrect results with some ultrasonic sensor models.
  • Actively developed with features being added and bugs/issues addressed.


Download

Download here: Download NewPing Library

Put the "NewPing" folder in "libraries\".

In the Arduino IDE, create a new sketch (or open one) and select from the menubar "Sktech->Import Library->NewPing".


Constructor

NewPing sonar(trigger_pin, echo_pin [, max_cm_distance]);

Example:
NewPing sonar(12, 11, 200);

This initializes NewPing to use pin 12 for trigger output, pin 11 for echo input, with a maximum ping distance of 200cm. max_cm_distance is optional [default = 500cm].


Methods

  • sonar.ping(); - Send a ping, returns the echo time in microseconds or 0 (zero) if no ping echo within set distance limit
  • sonar.ping_in(); - Send a ping, returns the distance in inches or 0 (zero) if no ping echo within set distance limit
  • sonar.ping_cm(); - Send a ping, returns the distance in centimeters or 0 (zero) if no ping echo within set distance limit
  • sonar.ping_median(iterations); - Do multiple pings (default=5), discard out of range pings and return median in microseconds
  • sonar.convert_in(echoTime); - Converts microseconds to distance in inches
  • sonar.convert_cm(echoTime); - Converts microseconds to distance in centimeters
  • sonar.ping_timer(function); - Send a ping and call function to test if ping is complete.
  • sonar.check_timer(); - Check if ping has returned within the set distance limit.
  • timer_us(frequency, function); - Call function every frequency microseconds.
  • timer_ms(frequency, function); - Call function every frequency milliseconds.
  • timer_stop(); - Stop the timer.


Examples

Sample NewPing Sketch

  1. #include <NewPing.h>
  2.  
  3. #define TRIGGER_PIN  12
  4. #define ECHO_PIN     11
  5. #define MAX_DISTANCE 200
  6.  
  7. NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
  8.  
  9. void setup() {
  10.   Serial.begin(115200);
  11. }
  12.  
  13. void loop() {
  14.   delay(50);
  15.   int uS = sonar.ping();
  16.   Serial.print("Ping: ");
  17.   Serial.print(uS / US_ROUNDTRIP_CM);
  18.   Serial.println("cm");
  19. }

15 Sensors Example Sketch

  1. // ---------------------------------------------------------
  2. // This example code was used to successfully communicate
  3. // with 15 ultrasonic sensors. You can adjust the number of
  4. // sensors in your project by changing SONAR_NUM and the
  5. // number of NewPing objects in the "sonar" array. You also
  6. // need to change the pins for each sensor for the NewPing
  7. // objects. Each sensor is pinged at 33ms intervals. So, one
  8. // cycle of all sensors takes 495ms (33 * 15 = 495ms). The
  9. // results are sent to the "oneSensorCycle" function which
  10. // currently just displays the distance data. Your project
  11. // would normally process the sensor results in this
  12. // function (for example, decide if a robot needs to turn
  13. // and call the turn function). Keep in mind this example is
  14. // event-driven. Your complete sketch needs to be written so
  15. // there's no "delay" commands and the loop() cycles at
  16. // faster than a 33ms rate. If other processes take longer
  17. // than 33ms, you'll need to increase PING_INTERVAL so it
  18. // doesn't get behind.
  19. // ---------------------------------------------------------
  20. #include <NewPing.h>
  21.  
  22. #define SONAR_NUM     15 // Number or sensors.
  23. #define MAX_DISTANCE 200 // Max distance in cm.
  24. #define PING_INTERVAL 33 // Milliseconds between pings.
  25.  
  26. unsigned long pingTimer[SONAR_NUM]; // When each pings.
  27. unsigned int cm[SONAR_NUM]; // Store ping distances.
  28. uint8_t currentSensor = 0; // Which sensor is active.
  29.  
  30. NewPing sonar[SONAR_NUM] = { // Sensor object array.
  31.   NewPing(41, 42, MAX_DISTANCE),
  32.   NewPing(43, 44, MAX_DISTANCE),
  33.   NewPing(45, 20, MAX_DISTANCE),
  34.   NewPing(21, 22, MAX_DISTANCE),
  35.   NewPing(23, 24, MAX_DISTANCE),
  36.   NewPing(25, 26, MAX_DISTANCE),
  37.   NewPing(27, 28, MAX_DISTANCE),
  38.   NewPing(29, 30, MAX_DISTANCE),
  39.   NewPing(31, 32, MAX_DISTANCE),
  40.   NewPing(34, 33, MAX_DISTANCE),
  41.   NewPing(35, 36, MAX_DISTANCE),
  42.   NewPing(37, 38, MAX_DISTANCE),
  43.   NewPing(39, 40, MAX_DISTANCE),
  44.   NewPing(50, 51, MAX_DISTANCE),
  45.   NewPing(52, 53, MAX_DISTANCE)
  46. };
  47.  
  48. void setup() {
  49.   Serial.begin(115200);
  50.   pingTimer[0] = millis() + 75; // First ping start in ms.
  51.   for (uint8_t i = 1; i < SONAR_NUM; i++)
  52.     pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
  53. }
  54.  
  55. void loop() {
  56.   for (uint8_t i = 0; i < SONAR_NUM; i++) {
  57.     if (millis() >= pingTimer[i]) {
  58.       pingTimer[i] += PING_INTERVAL * SONAR_NUM;
  59.       if (i == 0 && currentSensor == SONAR_NUM - 1)
  60.         oneSensorCycle(); // Do something with results.
  61.       sonar[currentSensor].timer_stop();
  62.       currentSensor = i;
  63.       cm[currentSensor] = 0;
  64.       sonar[currentSensor].ping_timer(echoCheck);
  65.     }
  66.   }
  67.   // The rest of your code would go here.
  68. }
  69.  
  70. void echoCheck() { // If ping echo, set distance to array.
  71.   if (sonar[currentSensor].check_timer())
  72.     cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
  73. }
  74.  
  75. void oneSensorCycle() { // Do something with the results.
  76.   for (uint8_t i = 0; i < SONAR_NUM; i++) {
  77.     Serial.print(i);
  78.     Serial.print("=");
  79.     Serial.print(cm[i]);
  80.     Serial.print("cm ");
  81.   }
  82.   Serial.println();
  83. }


Information about this page

Last Modified: November 04, 2013, at 03:46 PM
By: psychephylax

Share