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

Awesome! That's great news. I'm most interested in human detection, but we're definitely on the same page. I have been getting some pretty accurate and precise readings with my maxbotix sensors using the crap (code) that I came up with recently, but there's always room for improvement. It's not in a library, but it works. For my purposes I don't even need to be that accurate, but I need it to be reliable. I have several ultrasonic sensors that I've been messing with, but I always get these stray readings. One or two are fine within a half second, but more than that mucks up my purpose. I will try to implement your library with my sensors (maxbotix) soon, and hopefully get some quality results.

TeslaIaint:
Awesome! That's great news. I'm most interested in human detection, but we're definitely on the same page. I have been getting some pretty accurate and precise readings with my maxbotix sensors using the crap (code) that I came up with recently, but there's always room for improvement. It's not in a library, but it works. For my purposes I don't even need to be that accurate, but I need it to be reliable. I have several ultrasonic sensors that I've been messing with, but I always get these stray readings. One or two are fine within a half second, but more than that mucks up my purpose. I will try to implement your library with my sensors (maxbotix) soon, and hopefully get some quality results.

The biggest problem with the other ultrasonic libraries is that they wait for up to a second for the ping echo to return. During that time, the ATmega is doing nothing else but waiting. It can return quickly if it "sees" something (or should I say "hears" something), but if not it basically just hangs. NewPing doesn't do that. And with the new timer interrupt code that will make it in the next release, there's even less down time. It's also just as easy to use as before too.

Tim

While I have my development library working using Timer1 interrupt, I'm not totally happy with it because Timer1 is also used for the servo library. The problem with using Timer2 is that it's only 8 bit so you can't do a long timeout event. I'm trying to do as much as possible event driven, but at the same time I don't want to cause too many conflicts. It looks like I'll be creating two new timer methods. Using the Timer1 method will allow a more full-featured event-driven ping scheduler. Using the Timer2 method will have reduced features but won't conflict with the servo library (Timer2 does conflict with the tone library, but that shouldn't be a deal-breaker for most). When using a timer you also lose PWM control on two pins, but again, having two timer options allows you to use the one that would conflict with the rest of your project the least amount. Keep in mind you can still use these pins, you just can't use them for PWM.

In any case, there's been no new updates because I want to make sure I'm heading in the right direction before I release something half-baked and then have to change things down the road which may require sketches to be adjusted. I'd rather avoid a situation where an old sketch doesn't work as-is with a new library release. I hope to have something to release by Thursday, but that's if I have no snags.

Tim

The problem with using Timer2 is that it's only 8 bit so you can't do a long timeout event.

You could add a counter in the timer2 ISR that will check only every 10 overflows (sort of cascading)

volatile byte counter = myPreferedValue;
void ISR()
{
  if (counter-- == 0)
  {
    do your check
    counter = myPreferedValue;
  }
}

does that make sense?

robtillaart:

The problem with using Timer2 is that it's only 8 bit so you can't do a long timeout event.

You could add a counter in the timer2 ISR that will check only every 10 overflows (sort of cascading)

volatile byte counter = myPreferedValue;

void ISR()
{
  if (counter-- == 0)
  {
    do your check
    counter = myPreferedValue;
  }
}




does that make sense?

Very true, I was hoping to avoid making things overly complex.

On that note, I've decided to only use Timer2 in NewPing. Even though Timer1 was a little cleaner, I believe using Timer1 is a deal-breaker as the servo library uses Timer1 and ultrasonic sensors and servos are often found on the same project. So, this still makes the library cleaner as it doesn't need the clutter of both Timer1 and Timer2 functions that basically do the same thing (not to mention the existing ping method which uses the old method). 3 different ping methods that all did the same thing was kind of overkill anyway.

As a bonus, the next release of NewPing will include general-use Timer2 interrupt methods that you could use in non-ping parts of your sketch. I needed to break the timer interrupts up into individual functions anyway as they would be used multiple times, and why not at the same time allow these functions to be used in the rest of your sketch. For that matter, you could use NewPing just for the simple Timer2 interrupt methods, and it is very simple.

Tim

NewPing v1.3 Released, download here

New in v1.3

Big feature addition, event-driven ping! Uses Timer2 interrupt, so be mindful of PWM or timing conflicts messing with Timer2 may cause (namely PWM on pins 3 & 11 on Arduino, PWM on pins 9 and 11 on ATmega, and Tone library). Simple to use timer interrupt functions you can use in your sketches totaly unrelated to ultrasonic sensors (don't use if you're also using NewPing's ping_timer because both use Timer2 interrupts). Loop counting ping method deleted in favor of timing ping method after inconsistant results kept surfacing with the loop timing ping method. Conversion to cm and inches now rounds to the nearest cm or inch. Code optimized to save program space and fixed a couple minor bugs here and there. Many new comments added as well as line spacing to group code sections for better source readability.

NOTE: For Teensy/Leonardo (ATmega32U4) the library uses Timer4 instead of Timer2. Also, only 16Mhz microcontrollers are supported with the timer methods, which means the ATmega8 and ATmega128 will not work with the timer methods. However, the standard ping method should work just fine on 8Mhz microcontrollers.

Tim

Thank you for all your hard work! I will definitely try the new version out soon!

Many thanks for doing this.

I was researching which sensors to buy.

NewPing v1.3 came just in time to help me make the right decision.

Cheers

how can i use the library with ultrasonic ks103 sensor?
www.dauxi.com/KS10X-V110_EN.pdf
thank you

how can i use the library with ultrasonic ks103 sensor?

With great difficulty; it's an I2C device.

yonatan36:
how can i use the library with ultrasonic ks103 sensor?
www.dauxi.com/KS10X-V110_EN.pdf
thank you

Do you already have the ks103 or is there a reason you want to use this model instead of the other, more typical ultrasonic sensors like the SR04?

Tim

Hi Tim,
Yes, I have it...

In which case, you're stuck with whatever algorithm is implemented in the device's firmware.

Great work on the library! I thought I might use this thread for a bit of troubleshooting.

My HC-SR04 is doing some very bizarre things and I'm lost. When using newPing and it's included newpingexample sketch, the sensor returns "0 cm" and there is no reaction to changes in proximity to objects. I tried using the simplest code I could find which doesn't require libraries (pasted below), but the same thing happens, this time reporting strange negative distances (-39 through - 45). I've found that changing the voltage supply effects the numbers, but only once did I get it to correctly report distance and very briefly. Is it possible the sensor has been damaged in some way? I'm using an Uno Rev 3 and a macbook pro (10.6.8 ) for config.

/*
  HC-SR04 Ping distance sensor]
  VCC to arduino 5v GND to arduino GND
  Echo to Arduino pin 13 Trig to Arduino pin 12
*/

int echoPin = 13; 
int trigPin = 12; 

void setup() { 
  Serial.begin (9600); 
  pinMode(trigPin, OUTPUT); 
  pinMode(echoPin, INPUT); 
} 

void loop() { 
  int duration, cm; 
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(20); 
  digitalWrite(trigPin, HIGH); 
  delayMicroseconds(20); 
  digitalWrite(trigPin, LOW); 
  duration = pulseIn(echoPin, HIGH); 
  cm = duration / 29 / 2;
 /* Sound velocity=29cm/microsec,
    then divide by 2 because of the return time */
  Serial.print(cm); 
  Serial.println(" cm"); 
  delay(500); 
}

NewWorldScientist:
Great work on the library! I thought I might use this thread for a bit of troubleshooting.

My HC-SR04 is doing some very bizarre things and I'm lost. When using newPing and it's included newpingexample sketch, the sensor returns "0 cm" and there is no reaction to changes in proximity to objects. I tried using the simplest code I could find which doesn't require libraries (pasted below), but the same thing happens, this time reporting strange negative distances (-39 through - 45). I've found that changing the voltage supply effects the numbers, but only once did I get it to correctly report distance and very briefly. Is it possible the sensor has been damaged in some way? I'm using an Uno Rev 3 and a macbook pro (10.6.8 ) for config.

If the unmodified NewPingExample sketch or the sketch you posted don't work, I would guess it's a faulty sensor. It seems you're doing everything correctly.

Tim

teckel:

I've only been keeping up now and then on this thread; I have yet to try the library, but I have to say it seems like an awesome improvement. I was wondering, though, if you were planning on:

  1. Adding the original PING sensor from Parallax to it
  2. Add code for the Polaroid/Senscomp 6500 sensor

???

I think the first should be done before the second (if the second is done at all), simply because there are some people out there using PING sensors with the Arduino, and it could potentially benefit from this library.

The second would only be worthwhile if it could support both the actual Senscomp 6500, as well as hacked Polaroid camera modules; these hacked modules are described in various places around the web, but the most recent version was done in an issue of Servo magazine not too long ago. In this version, it was described how to get the "old school" hack to work properly with the Arduino (as the original hack wasn't compatible with the Arduino in some manner). Then again, not many people likely purchase the Senscomp 6500 for the Arduino (they aren't cheap new), and most people probably don't hack old Polaroid cameras either (as it is cheaper and easier to buy the mass-produced dual-element modules).

Maybe the Maxbotix sensors should be done instead...?

:smiley:

Has anyone used this library in an obstacle avoiding robot sketch? I have a simple obstacle avoiding sketch that uses an old ultrasonic library, it works. But I wanted to try it with this library. Can I use "Distance = srf06.ping_cm();" in a sketch without the pingtimer/pingspeed code? Or do I have to use the "pingTimer" and "pingSpeed" like in the example? This makes it much harder to use in a sketch. I tried writing a function that returns the distance but I can't get it to work (I'm not much of a programmer).

I have read up on the prev posts. and i have to say i am impressed. I have downloaded the V.1.3 and i have to say ...... beautiful. very good work Tim.

Now my question is how to implement this with an obstacle avoiding sketch. yes similar to the question posted by Bajidi

SANTI

Here is the minimum amount of sketch you need to use the Newping library.

#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() {
  }

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.
    int cm = sonar.ping_cm();  // Send out the ping, get the results in centimeters.
    }
}

This is the part that saves the results to a variabable named "cm". You could change "cm" to distance, length, or fred if it makes you happy.

 int cm = sonar.ping_cm();  // Send out the ping, get the results in centimeters.

cr0sh:
I've only been keeping up now and then on this thread; I have yet to try the library, but I have to say it seems like an awesome improvement. I was wondering, though, if you were planning on:

  1. Adding the original PING sensor from Parallax to it
  2. Add code for the Polaroid/Senscomp 6500 sensor

I believe the Parallax PING))) sensor would almost work with my library as-is. The only difference would be that the trigger/echo pin would need to switch from input to output as the same pin is used for both. I don't have the sensor to test this, but it appears software-wise the interface is identical except for using a unified pin for both trigger/echo. It would only need a few lines of code modification, and it would be easy to automatically detect that it was a PING))) sensor when the same trigger and echo pin was specified.

If someone has this sensor, I'd be more than willing to make a slight modification to the library for you to test.

The Polaroid/Senscomp 6500 sensor also seems to be similar to the SR04. It does appear that there could be a slight trigger difference (leave the trigger high while sensing?). Again, I don't have this sensor to test. But, this sensor also appears to be not nearly as popular. I can't even find an Arduino library for it.

cr0sh:
Maybe the Maxbotix sensors should be done instead...?

I believe the MaxBotix MaxSonar sensors use an analog, PWM, and serial interface. None of which really match well with the current library interface method. Serial (like I2C) would be out for sure, but it would be possible to implement an analog or PWM interface. Again, I don't have this sensor so I can't really do much with it. Someone have one willing to loan me for a couple weeks?

Also, there's other ultrasonic sensors that use the a I2C interface. These I don't currently plan on supporting. Not because there's anything wrong with them, but because each sensor's I2C commands are totally different. Maybe a PingI2C library just for these sensors that are specialized with the proper commands for each sensor.

Tim