Arduino Forum

Using Arduino => Sensors => Topic started by: teckel on May 16, 2012, 01:17 am

Title: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.7
Post by: teckel on May 16, 2012, 01:17 am
NewPing Library Project Homepage (https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home)

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:

New in version 1.8:
Added support for non-AVR microcontrollers. For non-AVR microcontrollers, advanced ping_timer() timer methods are disabled due to inconsistencies or no support at all between platforms. However, standard ping methods are all supported. Added new optional variable to ping(), ping_in(), ping_cm(), ping_median(), and ping_timer() methods which allows you to set a new maximum distance for each ping. Added support for the ATmega16, ATmega32 and ATmega8535 microcontrollers. Changed convert_cm() and convert_in() methods to static members. You can now call them without an object. For example: cm = NewPing::convert_cm(distance);

Download:
Download NewPing v1.8 (https://bitbucket.org/teckel12/arduino-new-ping/downloads/)

Show Your Appreciation:
Help future development by making a small donation (the teckel@bex.net payee is correct).
(https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=99J6Y4WCHCUN4&lc=US&item_name=Arduino%20New%20Ping&item_number=Arduino%20New%20Ping&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted)

Common Problem Help:
15 Sensors Example Sketch (Multiple Sensors) Help (https://bitbucket.org/teckel12/arduino-new-ping/wiki/Help%20with%2015%20Sensors%20Example%20Sketch)
"vector_7" Error on Compile Help (https://bitbucket.org/teckel12/arduino-new-ping/wiki/Multiple%20Definition%20of%20%22__vector_7%22%20Error)

Example Sketch:
Code: [Select]
#include <NewPing.h>
#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 sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

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

void loop() {
  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
  Serial.print("Ping: ");
  Serial.print(sonar.convert_cm(uS)); // Convert ping time to distance and print result (0 = outside set distance range, no ping echo)
  Serial.println("cm");
}


New in version 1.7:
Removed support for the Arduino Due and Zero because they're both 3.3 volt boards and are not 5 volt tolerant while the HC-SR04 is a 5 volt sensor. Also, the Due and Zero don't support pin manipulation compatibility via port registers which can be done (see the Teensy 3.2).

New in version 1.6:
Corrected delay between pings when using ping_median() method. Added support for the URM37 sensor (must change URM37_ENABLED from false to true). Added support for Arduino microcontrollers like the $20 32 bit ARM Cortex-M4 based Teensy 3.2. Added automatic support for the Atmel ATtiny family of microcontrollers. Added timer support for the ATmega8 microcontroller. Rounding disabled by default, reduces compiled code size (can be turned on with ROUNDING_ENABLED switch). Added TIMER_ENABLED switch to get around compile-time "_vector_7" errors when using the Tone library, or you can use the toneAC, NewTone or TimerFreeTone libraries. Other speed and compiled size optimizations.

New in version 1.5:
Added ping_median() method which does a user specified number of pings (default=5) and returns the median ping in microseconds (out of range pings ignored). This is a very effective digital filter. Optimized for smaller compiled size (even smaller than sketches that don't use a library).

New in version 1.4:
You can now interface with all but the SRF06 sensor using only one Arduino pin. Added support for the Parallax PING)))™ sensor. You can also interface with the SRF06 using one pin if you install a 0.1uf capacitor on the trigger and echo pins of the sensor then tie the trigger pin to the Arduino pin (doesn't work with Teensy). To use the same Arduino pin for trigger and echo, specify the same pin for both values. Various bug fixes.

New in version 1.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.

New in version 1.2:
Lots of code clean-up thanks to Adruino Forum members. Rebuilt the ping timing code from scratch, ditched the pulseIn code as it doesn't give correct results (at least with ping sensors). The NewPing library is now VERY accurate and the code was simplified as a bonus. Smaller and faster code as well. Fixed some issues with very close ping results when converting to inches. All functions now return 0 only when there's no ping echo (out of range) and a positive value for a successful ping. This can effectively be used to detect if something is out of range or in-range and at what distance. Now compatible with Arduino 0023.

New in version 1.1:
Changed all I/O functions to use low-level port registers for ultra-fast and lean code (saves from 174 to 394 bytes). Tested on both the Arduino Uno and Teensy 2.0 but should work on all Arduino-based platforms because it calls standard functions to retrieve port registers and bit masks.  Also made a couple minor fixes to defines.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent
Post by: Jujo on May 16, 2012, 04:48 pm
Very good job, man!!!!
Two questions:
- is it possible to use multiple ultrasonic sensors? i.e 4 sensors?
- with multiple sensors and a distance between 10 and 20 cm how fast can be the readings?
Thanks
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent
Post by: cyclegadget on May 16, 2012, 06:38 pm

  Nice job! I just got 4 of those sensors, and I have one hooked up at home. I will can't wait to try it out!
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent
Post by: teckel on May 16, 2012, 07:54 pm

Very good job, man!!!!
Two questions:
- is it possible to use multiple ultrasonic sensors? i.e 4 sensors?
- with multiple sensors and a distance between 10 and 20 cm how fast can be the readings?
Thanks


YES!  The NewPing library is designed with multiple sensors in mind.  It's one of the reasons I created the library.  With the other ping/ultrasonic libraries, if there's no ping echo it waits a full second for the reply.  During that time, the Arduino is doing nothing, it's like a delay(1000).  Multiply that by 3 if you have 3 sensors.  So, you're waiting for 3 full seconds doing nothing if there's no pings.  Imagine an autonomous bot where you add a delay(3000) right in the middle of the sketch.  A lot can happen in 3 full seconds, or the bot can just sit there for 3 seconds to figure out which way to go.  Unacceptable.

I plan on creating a proper sample sketch using multiple sensors and also creating another library specifically optimized for 3 sensors.  But, here's basically what you would do:

Code: (Two sensor example) [Select]

#include <NewPing.h>

NewPing sonar1(11, 12, 200); // Sensor 1: trigger pin, echo pin, maximum distance in cm
NewPing sonar2(9, 10, 200); // Sensor 2: same stuff

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

void setup() {
 // Do other stuff here
 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
 }
 // Do other stuff here, notice how there's no delays in this sketch, so you have processing cycles to do other things :)
}


The above code is incomplete and doesn't do anything with the ping results (ready to add your own code).  But, it should give you an idea of what to do.

As to your second question, I suggest waiting at least 35ms between pings per sensor to avoid possible echo issues.  This isn't a library limitation or something that can be made faster by setting a shorter maximum distance.  The pinging frequency has to do with the speed of sound and the sensor specs.  You can, however, get away with making this faster if you need to.  My sensors are a little hard of hearing and can't detect the maximum 500cm.  So, I've successfully pinged every 25ms without a problem.  Never really tried to see how quickly it would work as typically in a real-world situation 10 times a second is plenty fast as your sketch is also doing other things too.

What you gain by setting the maximum distance to a lower value is not how fast you can ping. What you gain is how much time your sketch is off in limbo doing nothing waiting for the ping reply.  This allows your sketch to do multiple things without waiting for the ping echo (like in the other ping and ultrasonic libraries out there).  Here's an example.  If you use the 500cm maximum distance, the Arduino could set idle for up to 34ms for each ping.  If you only care about reading distances 20cm or less, the most the Arduino would wait for a ping would be 1.4ms.  Therefore, the Arduino has time to do other things.  Basically, the Arduino can better multitask if you set a shorter maximum distance.  But, due to the speed of sound, and sensor specs, you can't ping faster even if you set the maximum distance to a very low value, you still need to wait for the previous ping to fade or you'll get echo readings.

Let me know if you have any other questions or issues.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent
Post by: Jujo on May 16, 2012, 09:12 pm
Thanks for your answer. Very clear. So, if I have 4 sensors the minum elapsed is 35 ms for the readings and Arduino time. I start reading the first sensor, the second, the third and the forth. If the distance is 20 cm it take 1.4ms x 4 = 5.6 ms. I have almost 30 ms for Arduino to do other things and after restart next reading. But in my experience a normal algo in Arduino, without too much serial monitor printing, take 10-15 ms. If you don't print in the serial monitor the time is always under 10 ms. So 15-20 ms are lost waiting for new sensor reading to avoid the echo.Shame.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent
Post by: terryking228 on May 16, 2012, 10:10 pm
Hi Tim,

Great work! I will be trying this out Real Soon!!!

There are quite a few "HC-S04" labelled modules around. Have you tested any variety??

Here are a couple I have: http://goo.gl/VZkSy  

The one labelled SRF-06 is said by the supplier to have temperature compensation. It does have a different circuit board / chips.  

I'll send you one of each of the HC-SR04 and SRF-06 modules if you want to test them and see if you see any differences.. drop me a PM or email terry@yourduino.com

I'm writing a library for these: http://goo.gl/FWMjI  and I'd love to try some cool mapping ideas with your code...

DISCLAIMER: Mentioned stuff from my own shop...

OTHER QUESTION: Your example is for Arduino IDE 1.0  Does the library work for both 0023 and 1.0??
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent
Post by: teckel on May 16, 2012, 11:20 pm

Thanks for your answer. Very clear. So, if I have 4 sensors the minum elapsed is 35 ms for the readings and Arduino time. I start reading the first sensor, the second, the third and the forth. If the distance is 20 cm it take 1.4ms x 4 = 5.6 ms. I have almost 30 ms for Arduino to do other things and after restart next reading. But in my experience a normal algo in Arduino, without too much serial monitor printing, take 10-15 ms. If you don't print in the serial monitor the time is always under 10 ms. So 15-20 ms are lost waiting for new sensor reading to avoid the echo.Shame.


With 4 sensors, you would ping each one with a minimum of 35ms between each ping.  So, 35 x 4 = 140ms to ping 4 sensors.  Therefore, you could ping all 4 sensors 7 times a second.  As your maximum distance is only 20cm, and at that range the MAX it would wait is 1.4ms to get the ping results per sensor, the most processing time used to wait for pings would be around 40ms per second (1.4 x 4 x 7 = 39.2), with 960ms per second for other tasks.  Basically, with a 20cm range, the ping process only uses a maximum of 4% of the Arduino's processing time.  That's also the max, as if the sensor detects something closer, it will use even less.  That's also assuming you ping every 35ms.  If you don't need pings 7 times a second, it would be even less.  Also keep in mind that this time is not lost to processing, but simply waiting for a pin to go high.  It is a shame, but a good illustration of how fast the Arduino is and how slow the speed of sound is.

With that said, the NewPing library is much smarter and my example sketches are more event driven than the others out there.  Looking at my examples, you can tell that I'm not much of a fan of sequential programming (where's the "delay" some would say looking at my code).  The only sequential part of the NewPing library and my example sketches is the actual listening for the ping using pulseIn.  That's something I'm working on, and will be more important with my future Ping3 library designed to ping 3 sensors.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent
Post by: teckel on May 17, 2012, 12:47 am

Hi Tim,

Great work! I will be trying this out Real Soon!!!

There are quite a few "HC-S04" labelled modules around. Have you tested any variety??

Here are a couple I have: http://goo.gl/VZkSy  

The one labelled SRF-06 is said by the supplier to have temperature compensation. It does have a different circuit board / chips.  

I'll send you one of each of the HC-SR04 and SRF-06 modules if you want to test them and see if you see any differences.. drop me a PM or email terry@yourduino.com

I'm writing a library for these: http://goo.gl/FWMjI  and I'd love to try some cool mapping ideas with your code...

DISCLAIMER: Mentioned stuff from my own shop...

OTHER QUESTION: Your example is for Arduino IDE 1.0  Does the library work for both 0023 and 1.0??



I have (3) HC-SR04's from two different sources.  One from Amazon and two direct from China.  All work fairly similar.  I believe the SRF05 is compatible in mode 1 (2 wire) with NewPing, adding support for PING))) would be fairly easy (1 wire) as would mode 2 (1 wire) of the SRF05.  Then there's the SRF02, which is a totally different animal as it uses either I2C or serial so it would need a totally different library.  It appears the SRF-06 is a 2 wire device so my guess would be that it would work very well with the NewPing library.  I'd love to test your sensors, as I'd like to grow NewPing into a library used for all ultrasonic sensors.  I'll PM you.

How I can see this working going forward is to make the NewPing library compatible with all the different ultrasonic interfaces (1 wire, 2 wire, I2C and serial) and compatible with as many sensor models as possible.

I'm an Arduino newb, coming in after the 1.0 release.  So, I never used the 0023 platform.  I would think at this point supporting 0023 wouldn't be too important.  I know there's some old sketches out there that won't compile in 1.0 and using my library may be useful.  But, it seems like everything has moved to 1.0 fairly quickly and almost all libraries I see are all written only for 1.0 these days with 0023 stuff being un-linked or listed as legacy, don't use.  I wouldn't have a huge problem installing 0023 to address compatibility problems, but not sure if it's really needed at this point.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent
Post by: cyclegadget on May 17, 2012, 01:21 am

  Report back: Success!!!  I tried your sample sketch on IDE 23 and 1.0.    I got an error with 23, it said it could not find NewPing.h.    I then put the same library and sketch into 1.0 and it compiled fine. Next, I modified the sketch to print the output from the sensors and also added a delay to slow the data to a readable level.

Here is the modified sketch that I tested with my 2 sensors.

Code: [Select]
#include <NewPing.h>

NewPing sonar1(12, 13, 200); // Sensor 1: trigger pin, echo pin, maximum distance in cm
NewPing sonar2(10, 11, 200); // Sensor 2: same stuff

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

void setup() {
  Serial.begin(9600);
  // Do other stuff here
  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();
    Serial.println(in1);
  }
  if (millis() >= pingTimer2) {
    pingTimer2 = pingTimer1 + (pingSpeed / 2); // Make sensor 2 fire again 50ms after sensor 1 fires
    int in2 = sonar2.ping_in();
    Serial.println(in2);
    // Both sensors pinged, process results here
  }
  delay(1000);
  // Do other stuff here, notice how there's no delays in this sketch, so you have processing cycles to do other things :)
}

Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 17, 2012, 05:48 am
First off, yes, it's designed for Arduino 1.0 only.  I'm not sure if at this point development for old versions is really required.

Anyway, I have a bit of a problem with your sketch. You use a delay!  Really, you should try to avoid using a delay at all cost, and the sketch is built to not need to use it.  The entire problem with the other ping/ultrasonic libraries out there is that because they can add up to a second of delay, it breaks your event-driven sketch.

If you want to slow it down, simply change the pingSpeed, that's what it's there for.  It appears you want to only do a ping once a second, so set pingSpeed to 1000 and remove the delay.  My guess is that your goal is to have both sensors ping as close to the same time as each other, then print the results, and do that once per second.  Here's the proper event-driven code to do that:

Code: [Select]

#include <NewPing.h>

NewPing sonar1(11, 12, 200); // Sensor 1: trigger pin, echo pin, maximum distance in cm
NewPing sonar2(9, 10, 200); // Sensor 2: same stuff

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

void setup() {
 Serial.begin(9600);
 pingTimer1 = millis() + pingSpeed; // Sensor 1 fires after 1 second (pingSpeed)
 pingTimer2 = pingTimer1 + 35; // Sensor 2 fires 35ms later
}

void loop() {
 if (millis() >= pingTimer1) {
   pingTimer1 += pingSpeed; // Make sensor 1 fire again 1 second later (pingSpeed)
   in1 = sonar1.ping_in();
 }
 if (millis() >= pingTimer2) {
   pingTimer2 = pingTimer1 + 35; // Make sensor 2 fire again 35ms after sensor 1 fires
   in2 = sonar2.ping_in();
   // Both sensors pinged, process results here
   Serial.print(in1);
   Serial.print(" - ");
   Serial.println(in2);
 }
 // Do other stuff here, notice how there's no delays in this sketch, so you have processing cycles to do other things :)
}


This code will ping both sensors once per second as close in time to each other as possible, then output the results.  It also will never get in a situation where it could have a 2 second delay.  It will always fire exactly every 1 second.

Hope that helps better understand the event-driven programming method and why it's so important for real-world applications.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: AWOL on May 17, 2012, 09:19 am
You've got two virtually-identical constructors; you could eliminate code by defaulting "max_cm_distance" to "MAX_SENSOR_DISTANCE", couldn't you?

Code: [Select]
int NewPing::convert_cm(int echoTime) {
if (!echoTime) return false;
else return echoTime / US_ROUNDTRIP_CM;
}

If "echoTime" is zero, then "echoTime / US_ROUNDTRIP_CM" is also zero; no need to test up front - slightly longer execution time, shorter code.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: robtillaart on May 17, 2012, 10:24 am

Agree with AWOL's proposal , especially as the original code mixes type (false=bool and ints)

you can even make it a macro:

#define convert_cm(echotime)  ((echoTime) / US_ROUNDTRIP_CM)
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: AWOL on May 17, 2012, 11:05 am
I'm not really sure the "volatile" qualifiers are necessary, except for "_echoInput", either.

"pulseInNew" may as well be "inline"
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: terryking228 on May 17, 2012, 11:22 am
Hi, I got it to compile under 0023.  Modify the beginning of newping.h like this:

---------------------( COPY )--------------------------
#ifndef NewPing_h
#define NewPing_h
#endif

#if defined(ARDUINO) && ARDUINO >= 100
   #include "Arduino.h"
#else
   #include "WProgram.h"
-----------------( END COPY )----------------------
This includes the right system .h file...


Hmmm. Maybe that ends up with the #endifs wrong??  But it works? Maybe someone 1/3 my age who knows about this could check it....

Maybe the Arduino check should go first??

..."And the first one now will later be last, for the times they are a'changing "
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 17, 2012, 04:22 pm

You've got two virtually-identical constructors; you could eliminate code by defaulting "max_cm_distance" to "MAX_SENSOR_DISTANCE", couldn't you?


I created two constructors to be compatible with existing ping/ultrasonic libraries that only pass 2 variables.  I would expect users to use the one that sets the maximum distance.  I also wouldn't expect someone to use both in the same sketch, so there's no wasted compiled code space as only one would be compiled.  I would love to consolidate the two, as they're basically identical.  But, I lack the knowledge of C++ to accommodate a constructor that has a different number of variables to pass while keeping the same constructor name.  I come from very long PHP programming background but haven't touched C in at least 20 years.  In PHP I would do something like this:

Code: [Select]
function NewPing(trigger_pin, echo_pin, max_cm_distance=MAX_SENSOR_DISTANCE) {...}


Code: [Select]
int NewPing::convert_cm(int echoTime) {
if (!echoTime) return false;
else return echoTime / US_ROUNDTRIP_CM;
}

If "echoTime" is zero, then "echoTime / US_ROUNDTRIP_CM" is also zero; no need to test up front - slightly longer execution time, shorter code.


Inexperience on my part and confusion with other languages.  I think of false as not the same as zero.  false !== 0.  If false === 0 (strict) in Arduino, that changes many things.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: AWOL on May 17, 2012, 04:31 pm
Code: [Select]
function NewPing(trigger_pin, echo_pin, max_cm_distance=MAX_SENSOR_DISTANCE)
Yup, that's pretty much how you would do it in NewPing.h.
Code: [Select]
NewPing(int trigger_pin, int echo_pin, int max_cm_distance = MAX_SENSOR_DISTANCE);

Even if you couldn't consolidate in this way, you should always factor the common code into a single function.

Quote
I think of false as not the same as zero

The C/C++ paradigm is that zero is false, and everything else is true.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 17, 2012, 06:28 pm

---------------------( COPY )--------------------------
#ifndef NewPing_h
#define NewPing_h
#endif

#if defined(ARDUINO) && ARDUINO >= 100
   #include "Arduino.h"
#else
   #include "WProgram.h"
-----------------( END COPY )----------------------


Wouldn't it be?:

Code: [Select]

#ifndef NewPing_h
#define NewPing_h

#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include "WProgram.h"
#endif


Also, did you try this with v1.1 which uses the shift registers?

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 17, 2012, 06:57 pm


Agree with AWOL's proposal , especially as the original code mixes type (false=bool and ints)

you can even make it a macro:

#define convert_cm(echotime)  ((echoTime) / US_ROUNDTRIP_CM)



After learning that false===0 in C++, I've had to rework some things.  Basically, I want a ping to return false (zero) if there's no ping echo within the distance allowed.  Also, if there is a ping echo, the result needs to be >0.  We don't want to confuse a <1 inch ping echo with infinity as this difference would be very important to what you're using the sensor for.

In an case, I've reworked a bunch of the code to accommodate this and to give expected results.  Here's the macro that's used for both cm and inch conversion:

#define _convert(echoTime, conversionFactor) (max(echoTime / conversionFactor, (echoTime ? 1 : 0)))

echoTime is obviously the microsecond time and conversionFactor is either US_ROUNDTRIP_CM or US_ROUNDTRIP_IN.  It may appear that it's overly complex with code reduction possible.  But, I need to make sure 0="no ping echo" and we never get a 0 for a really close range (happens with inches).  If there's a better way do write this macro, let me know.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 17, 2012, 07:13 pm

I'm not really sure the "volatile" qualifiers are necessary, except for "_echoInput", either.

"pulseInNew" may as well be "inline"


Without the "volatile" it won't compile, which is why I used it.  Feel free to correct me if I'm wrong.

You're right, I should have made pulseInNew inline, in a hurry and it was late I guess.  I've made it inline now.  But, that's a part of the code I need to totally rework as I'd really like to see it totally event driven (or an option to have it event driven at least).  I really hate delays or small loops that wait for an event without processing something else.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: robtillaart on May 17, 2012, 07:14 pm
An echoPing can only be positive as any distance is positive .

That makes it ideal to use the negative values as error codes, but those should be in the primary ping function

something like ..
Code: [Select]

...
 if (time > MAXTIME) return -100;
 if (other error) return -200;
 // etc
 return time;
}


thinking along that line, the conversion function to cm should only accept unsigned ints for echoTime.

Code: [Select]
unsigned int NewPing::convert_cm(unsigned int echoTime)
{
 return (echoTime + US_ROUNDTRIP_CM/2) / US_ROUNDTRIP_CM;   // added rounding
}
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: AWOL on May 17, 2012, 08:34 pm
Quote
Without the "volatile" it won't compile, which is why I used it.

Except for the echo pin, you could cast it away.
It isn't necessary for the data direction registers or the trigger pin.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 17, 2012, 08:55 pm

An echoPing can only be positive as any distance is positive .

That makes it ideal to use the negative values as error codes, but those should be in the primary ping function


True, but the logic is not with the ping echo, it's with the conversion to inches and cm.  And this is where it can be zero as the sensor can read something closer than an inch, which yields a zero.  Technically, it should never happen with cm.  But, I'd rather go the safe route.

Making errors negative is basically what I'm doing, but with zero as the error value.  Which is why the code is written that way, to accommodate the zero error indicator.  Making the error a negative doesn't remove the need for that code.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 17, 2012, 09:10 pm

Quote
Without the "volatile" it won't compile, which is why I used it.

Except for the echo pin, you could cast it away.
It isn't necessary for the data direction registers or the trigger pin.


When i remove the volatile I get the following error on compile:

Code: [Select]
error: invalid conversion from 'volatile uint8_t*' to 'uint8_t*'

I didn't just add them on a whim, the compiler told me to or it wouldn't compile.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: AWOL on May 17, 2012, 09:15 pm
No-one  said you added them on a whim, but you can get rid of the error message with a simple cast.
The only reason to have volatile qualifier is for polling loops on registers, and the only register you poll is the one associated with the echo pin.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 17, 2012, 10:05 pm

No-one  said you added them on a whim, but you can get rid of the error message with a simple cast.
The only reason to have volatile qualifier is for polling loops on registers, and the only register you poll is the one associated with the echo pin.


Gotcha.  I assumed there was some very good reason why it was asking for a volatile qualifier.  The only value now with a volatile qualifier is *_echoInput

With that said, it didn't change my code size at all, so I suspect the compiler optimized the code identically both with and without the volatile qualifier.  Or, maybe I just got lucky and the compiled code is just coincidentally the same length.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: cyclegadget on May 18, 2012, 12:45 am

@teckel,

  I had the sensors already plugged in on a bread board so, I wiped the code additions together so I could see the results. Thank you for pointing out the ability to time pings using the bit of code you already had in the sketch, in my rush I missed the clear comments that you had in the sketch for timing the pings. I will not use delay on my next usage! :)

Thanks for the work!

Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: robtillaart on May 18, 2012, 10:30 am
Quote
True, but the logic is not with the ping echo, it's with the conversion to inches and cm.  And this is where it can be zero as the sensor can read something closer than an inch, which yields a zero.  Technically, it should never happen with cm.  But, I'd rather go the safe route.


thats why you should include rounding in the conversion functions (or do mililmeters, or 1/16th)


I had a closer look at the conversion functions and you should revisit them:

Speed of sound is 340.29 m/sec => US_ROUNDTRIP_CM = 58.77  

that means that  US_ROUNDTRIP_CM  should be rounded to 59  iso 58 and US_ROUNDTRIP_IN 149 iso 148?

These rounding errors add up !!

Small experiment with different conversion functions
Code: [Select]
void setup()
{
 Serial.begin(9600);
}

unsigned int x;

void loop()
{
 for (int i=0; i<=30000; i+=1000)
 {
   Serial.print(i);
   Serial.print(",\t");
   
   x = convert_cm0(i);
   Serial.print(x);
   Serial.print(",\t");
   
   x = convert_cm1(i);
   Serial.print(x);
   Serial.print(",\t");
   
   x = convert_mm(i);
   Serial.print(x);
   Serial.print(",\t");

   x = convert_cm2(i);
   Serial.print(x);
   Serial.println();
 }
 while(1);
}

// reference
unsigned int convert_cm2(unsigned int echoTime)
{
 unsigned long us_roundtrip_100meter = 587734;
 unsigned long distance = (echoTime*1e4 + us_roundtrip_100meter/2)/ us_roundtrip_100meter;
 return (unsigned int) distance ;
}

// original with rounding
unsigned int convert_cm0(unsigned int echoTime)
{
 return (echoTime+29)/ 58;   // added rounding
}

// using 59 ?
unsigned int convert_cm1(unsigned int echoTime)
{
 return (echoTime + 29)/ 59;   // added rounding
}

// use millimeters
unsigned int convert_mm(unsigned int echoTime)
{
 return (echoTime*10L + 294)/ 588;   // added rounding
}


Output
0,   0,   0,   0,   0
1000,   17,   17,   17,   17
2000,   34,   34,   34,   34
3000,   52,   51,   51,   51
4000,   69,   68,   68,   68
5000,   86,   85,   85,   85
6000,   103,   102,   102,   102
7000,   121,   119,   119,   119
8000,   138,   136,   136,   136
9000,   155,   153,   153,   153
10000,   172,   169,   170,   170
11000,   190,   186,   187,   187
12000,   207,   203,   204,   204
13000,   224,   220,   221,   221
14000,   241,   237,   238,   238
15000,   259,   254,   255,   255
16000,   276,   271,   272,   272
17000,   293,   288,   289,   289
18000,   310,   305,   306,   306
19000,   328,   322,   323,   323
20000,   345,   339,   340,   340
21000,   362,   356,   357,   357
22000,   379,   373,   374,   374
23000,   397,   390,   391,   391
24000,   414,   407,   408,   408
25000,   431,   424,   425,   425
26000,   448,   441,   442,   442
27000,   466,   458,   459,   459
28000,   483,   475,   476,   476
29000,   500,   492,   493,   493
30000,   517,   508,   510,   510


The 58 code gives 7 cm too much at 510 cm  (~1.4 % error)
The 59 code gives 2 cm too little at 510 cm (~0.5% error)
The mm code gives no error at 510 cm (<= 0.2%)

The "mm" code needs long math where the "59"code only needs int math,

conclusion =>
use 59 iso 58 as it has a lower a systematic error (factor 3) with the same codesize & speed.

Same exercise to be done for inches too :)
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 18, 2012, 05:46 pm

Quote
True, but the logic is not with the ping echo, it's with the conversion to inches and cm.  And this is where it can be zero as the sensor can read something closer than an inch, which yields a zero.  Technically, it should never happen with cm.  But, I'd rather go the safe route.


thats why you should include rounding in the conversion functions (or do mililmeters, or 1/16th)

I had a closer look at the conversion functions and you should revisit them:

Speed of sound is 340.29 m/sec => US_ROUNDTRIP_CM = 58.77  

that means that  US_ROUNDTRIP_CM  should be rounded to 59  iso 58 and US_ROUNDTRIP_IN 149 iso 148?

These rounding errors add up !!


I knew this was going to happen...

I originally had a longer comment about the speed of sound in my library, but removed it as it seemed a little too preachy and bordered on a rant.  Basically, it talked about how there's actually some debate as to the speed of sound, if you can believe it.  We can measure the speed of light and time within the smallest margins to track your location down to 3 meters with cheap GPS technology, but there's a debate on how fast sound travels and what influences that speed.

Google reports the speed of sound as 340.29m/s.  The speed Google reports is only true when the temperature is 59 degrees (not a typical temp in most situations).  Wikipedia gives the speed as 343.2m/s in "dry air" at 68 degrees, yet the humidity, pressure, altitude, etc. makes no difference in the speed (only the temperature affects the speed).  The actual speed of sound at 73 degrees (a fairly typical testing temperature) is 344.838m/s.  See this page for details: http://www.sengpielaudio.com/calculator-speedsound.htm

I'm going to use 73 degrees as the standard, as I consider 73 a good average temperature in most situations and works out to a number very close to an integer: 57.998.  So, the first problem with converting time to distance is everyone has a different opinion on how fast sound travels, and it really is different for different temperatures.  Using 58 for US_ROUNDTRIP_CM is actually almost perfectly accurate at 73 degrees.  Your 58.77 value would only be accurate if it was 59 degrees, which I believe is a little cold for real-world situations.  If that's your current temperature, by all means, change US_ROUNDTRIP_CM to 58.77.

The next problem is that I believe there's some overhead or delay either before the ping or reading the echo.  Some sensors' documentation state this delay, but most do not.  Actual measurements confirm this, showing times being way off at close distances but getting more accurate at longer distances.  This indicates that there's some processing overhead going on, which makes small readings off, and longer readings more accurate.  I've actually already done this testing and calculation and for my sensors I would add 97 microseconds to make the results closer to accurate over the full range of the sensor.

So, a more accurate conversion from microseconds to cm assuming 73 degrees would be cm=(microseconds+97)/57.998.  The adding of this 97 microseconds will be addressed at some point in my library, once I have compiled enough sensors to actually confirm this is a fairly fixed value for multiple devices by different manufactures.

Next... There's the issue of the actual pulseIn timing code in Arduino.  I'm not 100% confident the technique is "sound" (no pun intended).  While I've tried to streamline the pulseIn function, I still don't like it.  It's done in a sequential in-line manner with a loop instead of event-driven.  How it does the timing is based on the processing cycles for the loop, not time.  I intend on looking into this further and hopefully writing an event-driven version of pulseIn that is still (basically) accurate but also doesn't send the program off into a loop rendering the processor useless while it waits for a ping echo.

Next... These sensors really can't get a measurement out to 500cm.  It's more like 400cm or less.  Some quote 500cm, so I figured I should make that the max, just in case.  So, while it's true calculation errors get larger at longer distances, in the real-world it's not quite as drastic.

Finally, there's the issue of using floating point values which require additional libraries to be compiled taking up program space and additional processor cycles at execution time.  That's why I used integers instead of fractions.  It seems silly to make US_ROUNDTRIP_CM 57.998, when the accuracy of the sensor is +/- 0.3cm, we're guessing at the temperature, we know the sensor has some overhead, and the timing code is in question.

If we could assume that pulseIn was perfectly accurate, the correct full calculation would be as follows (it would also require a temperature sensor):

cm=(us+97)/(331.5*sqrt(1+(c/273.15)));  // us=microseconds, c=degrees celsius

So in conclusion...  This is why I used 58 for US_ROUNDTRIP_CM.  It's also why I have a paragraph after this define in NewPing.h which says:

Code: [Select]
// ---------------------------------------------------------------------------
// Ballpark numbers for US_ROUNDTRIP_CM and US_ROUNDTRIP_IN were used. Feel free to change if more
// accurate readings for your testing temperature and situation are needed.  The values don't need
// to be integers.  But, using integers will save program space.  And honestly, we're talking
// microseconds here.  If we're off by a few dozen microseconds one way or another does it really
// matter? The HC-SR04 isn't that accurate to begin with to fuss too much with this.
// ---------------------------------------------------------------------------


So, if your testing environment is 59 degrees, feel free to change US_ROUNDTRIP_CM to 58.77 and take the performance and program space hit.  Or, leave it at 58 and enjoy the fairly close to accurate results.

I warned you this topic was preachy and a rant. ;-)
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: terryking228 on May 18, 2012, 07:03 pm
Hi,
Great subject; I really like this kind of detailed discussion about a good subject... Thanks for the work writing the library.

Tim, one of the sensors we were talking about has a built-in temperature sensor: This one: http://goo.gl/Ox2rP

This is the one that has both UART mode and Pulse/echo mode.  The temperature measurement only works in UART mode.. The docs I have say:
---------------------( COPY )--------------------------
Temperature function only in UART mode. TX send 0X50 trigger temperature measurement. When temperature measurement is completed, the module will return a byte temperature ( tDATA ), The actual temperature is tDATA-45 . For example, by TX sending 0X50 ,  RX received 0x45 , then the temperature at this time is [69 ( 0x45 to 10 decimal value) -45] = 24 degrees C
-----------------( END COPY )----------------------

Of course temperature can be measured with a DS18B20, or etc also...

Maybe you can actually do temp compensation?? Maybe only important for OutdoorBots...

Sensors should be there in 2 or 3 days...
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: AWOL on May 18, 2012, 07:36 pm
Mostly I'm ok with rough figures from sonars.
It is usually just
1) Too close, anchors on
2) I can get through there
3) Full speed ahead
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: robtillaart on May 18, 2012, 07:44 pm
@teckel
Thanks for the explanation!, good point as I did not investigate the temperature in it.

Quote
yet the humidity, pressure, altitude, etc. makes no difference in the speed (only the temperature affects the speed).


Humidity does make a difference, too. Furthermore the effect of temperature and humidity depends on the frequency of the sound.

see this publication for the math details - http://www.rane.com/pdf/ranenotes/Enviromental_Effects_on_the_Speed_of_Sound.pdf - (updated link)

To get a optimal pulseIn you should play with Timer1 as it can count in HW in steps of 1/16 us. That's as precise as Arduino gets. Use an IRQ to get the edges of the pulse and do a diff on the countervalues. See some of my experiments in this thread - http://arduino.cc/forum/index.php/topic,96971.45.html -
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 20, 2012, 06:22 pm

@teckel
Thanks for the explanation!, good point as I did not investigate the temperature in it.

Quote
yet the humidity, pressure, altitude, etc. makes no difference in the speed (only the temperature affects the speed).


Humidity does make a difference, too. Furthermore the effect of temperature and humidity depends on the frequency of the sound.


You're correct with humidity, I misspoke.  I meant to say at some point that humidity makes a slight difference.  You could add humidity into the calculations, but most of that could be discounted in the margin of error of the sensor itself.  And, the distance the sensor can read makes humidity mostly trivial under most situations.

I guess my point was really that using close whole integers is probably good enough for most purposes.  If not, use the ping function which outputs the time in microseconds and do your own calculations using a temperature sensor and optionally even a humidity sensor if your readings need to be that precise.  But, if your readings really need to be that precise, you probably should use a different ranging sensor.

With all this said, I do plan on looking further into this overhead delay and possibly adding a constant in the calculations if it's found that this delay is a constant.  I need to build a testing jig with distance measurements to accurately test multiple sensors in a very controlled manor. But, I'm not even going to do that until the pulseIn is rewritten as that could have an effect on these readings.  I could also add a microsecond to cm and inch conversion where you could also specify the temperature from a temperature sensor.  I do plan on sticking with using integers for basic conversions to save space and speed.  If more precise values can be verified, I'll add those to the code as an option for those who are already using floating point calculations in their sketch or don't have a code space issue.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: robtillaart on May 20, 2012, 09:18 pm
wrt floating point, keep the code in the integer/long range. Optionally do the math in millimeters (multiply all with 10) and bring it back to cm in the end (divide by 10) That gives higher precision without the overhead of the float. Did that in one of the conversion variations (prev post).

wrt Humidity, we discussed a year(?) ago measuring the depth of a water pit (well?). There the humidity was close to 100% so it affected the ping sensor readings to the max, so in the end the working allways depends on the context ;)

Quote
I could also add a microsecond to cm and inch conversion where you could also specify the temperature from a temperature sensor.  I do plan on sticking with using integers for basic conversions to save space and speed.

imho set the temperature seperately to choose the divider to use from a small lookup table. Temp does not change that often, so conversion time will be minimized, no need to do the lookup agaiin and again.

(snippet, you get the idea)
Code: [Select]

byte table[] = { ...,57,58,59,60, ...}
div = 58; // default
rnd = div/2;  //rnd is short for rounding

setTemperature(int F) 
{
  F = F/20;
  div = table[F];
  rnd = div/2;
}

unsigned int convert_cm(unsigned int echoTime)
{
  return (echoTime + rnd)/ div;
}




Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 21, 2012, 06:46 am

wrt floating point, keep the code in the integer/long range. Optionally do the math in millimeters (multiply all with 10) and bring it back to cm in the end (divide by 10) That gives higher precision without the overhead of the float. Did that in one of the conversion variations (prev post).

wrt Humidity, we discussed a year(?) ago measuring the depth of a water pit (well?). There the humidity was close to 100% so it affected the ping sensor readings to the max, so in the end the working allways depends on the context ;)


This is what the ping function is for, so you can do your own calculations based on microseconds as you see fit.  The ping_cm and ping_in are designed to be fast, lite and "good enough" for most situations.  After all, these kinds of sensors are typically used to provide "too close", and "clear ahead" readings, not really exact measurements.  If I could make an accurate calculation, I would.  It's simply not possible to be accurate to the mm, so a calculation like that would be pointless.  It's silly to have a ping_mm function if it's off by 15mm, no?  My goal is to be accurate to the cm, which with these sensors and how pulseIn works will be a real challenge.  mm resolution is a pipe dream, I suggest a laser sensor if that's what you need.

Basically, if you need some unique calculation that's accurate down to the mm, use the ping function and real-world calibration from your own unique sensor.  But, be warned.  Even if your formula is accurate, and you account for temperature and humidity, your result will still be off by as much as a cm or even more as there's other problems with how the readings are timed and the margin of error in the sensor itself.

And once again, this is why I made the statement that I did in my code, that I'm using integers and if you want to use something else, change the numbers.  Or better yet, use the ping function and use your own conversion function for your needs.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: terryking228 on May 21, 2012, 07:24 am
Tim, This is an approach that could perhaps be taken more often with libraries in general: Expose relevant internal (previously private) variables for the user who wishes to do additional calculations.

Maybe the library could even be structured so that if a user does that, the code for further/final calculations in the "usual" application is not compiled?

I'm still semi-illiterate about library details and conventions so this is just conjecture.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: robtillaart on May 21, 2012, 08:22 pm
@Terry
Every published library is open, so users can allways "roll their own" variation of the library. I think Tim does a very good job keeping the lib as simple as possible because that means small footprint and performance most of the time. My additions and ideas is just searching the "edge of the possible" :)

@Tim
You should use the link to this thread in your library so people can reread the arguments somewhere in the future. e.g. add a header like
Code: [Select]
//
//    FILE: newPing.cpp
//  AUTHOR: Tim Eckel
//    DATE: 2012-05-xx
// VERSION: 1.1
//
// PUPROSE: new implementation of ping)))
// LINK: http://...
// HISTORY:
// 1.0: ...
// 1.1: ...
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: terryking228 on May 21, 2012, 09:08 pm
Hi, Rob..
You are always  (cut-paste) on the "edge of the possible"  :)

Many Arduino users have no idea of what the source of a library looks like, or why it has that structure, or how to force it to recompile. They are happy (and capable) using a documented library.  But maybe if they could access the library functions at both a lower and higher level it would be useful. Maybe.

I'm not sure what side of the divide I'm on, or even where it is...

I really glad you guys are digging into this.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 21, 2012, 09:52 pm

Tim, This is an approach that could perhaps be taken more often with libraries in general: Expose relevant internal (previously private) variables for the user who wishes to do additional calculations.

Maybe the library could even be structured so that if a user does that, the code for further/final calculations in the "usual" application is not compiled?

I'm still semi-illiterate about library details and conventions so this is just conjecture.


Terry, that's exactly how I see it.  I think the primary goal of the NewPing library is to measure the ping/echo time and distance as easily, quickly and accurately as possible.  But, when we get into advanced distance conversion, the requirement to consider temperature and to a lesser extent humidity take it outside the scope of an ultrasonic/ping library as other sensors are required.  For those with this need, the NewPing library provides the user with the low-level ping/echo timing.  And those with this need and knowledge of what other sensors are needed should already know the equation they need to use.

Not that I'm going to wash my hands of this and off-load it.  There's just more primary issues, like making pulseIn event-driven and a generally more accurate echo time sensor first.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 21, 2012, 10:37 pm

@Terry
Every published library is open, so users can allways "roll their own" variation of the library. I think Tim does a very good job keeping the lib as simple as possible because that means small footprint and performance most of the time. My additions and ideas is just searching the "edge of the possible" :)

@Tim
You should use the link to this thread in your library so people can reread the arguments somewhere in the future. e.g. add a header like
Code: [Select]
//
//    FILE: newPing.cpp
//  AUTHOR: Tim Eckel
//    DATE: 2012-05-xx
// VERSION: 1.1
//
// PUPROSE: new implementation of ping)))
// LINK: http://...
// HISTORY:
// 1.0: ...
// 1.1: ...



Thanks for the suggestions!

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 23, 2012, 09:58 pm
Thanks to Terry King and YourDuino (http://YourDuino.com/) I did a round of range testing with 6 ultrasonic/ping sensors and the results were not as I expected.  I tested with 3 different models, (4) SF04, (1) SRF05, (1) SRF06.  The testing environment was in an air conditioned room at 75 degrees.  I tested at distances of 5cm, 10cm, 25cm, 50cm, and 100cm.  Longer distances were not tested in this round.  I believe the accuracy within 100cm or important as that's within the primary measurement distance.  Beyond 100cm it's not as much of an issue in most situations.  Once the pulseIn echo code is reworked, I'll do round 2 of testing out to a further distance.

The good news is that the sensors were all very consistent.  With all the SF04 and SRF05 generating nearly identical results (makes sense as the PCBs are nearly identical).  The SRF06 uses different components and yields slightly different measurements as a result.  It does appear to be a slightly better sensor (makes less clicking noise, hardly no lag, and results closer to actual speed of sound).  The maximum distance of the SRF06 seemed to be slightly lower, but that will be answered in round 2 of testing.

The results don't fit at all with the speed of sound calculations previously being used.  For the SF04 and SRF05 sensors, the calculation from microseconds to cm is:
cm = (microseconds + 37) / 48

For the SRF06 sensor, the calculation is:
cm = (microseconds + 5) / 51

Using these calculations, I could accurately measure any distance in the 5cm to 100cm range with all 6 sensors.  Albeit, not even close to speed of sound at this temperature, which should be right around cm = microseconds / 58.  If it was simply a long sensor lag, the additional microseconds added in the equation would be much higher, which they're not.

I have two theories as to why this is happening:
1) The pulseIn function is simply way off.  It's not even measuring time, but counting processor cycles, so there's a good possibility the time conversion is wrong.
2) Because I'm using port registers the code is faster.  And, since the formulas used to compute pulseIn are not based on port register manipulation but using the known slow higher-level digitalWrite command that's where the error is.  This doesn't seem likely as while digitalWrite is slow, it's not THAT slow.

At this point, I think diving into the pulseIn code and replacing it is a wise choice.  Then at least I'll have some other information to figure out the source of the time discrepancy.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 23, 2012, 11:35 pm
Rewrote the pulseIn to use micros() instead of loop counting.  With that change, I got accurate data that matches exactly with the speed of sound.  So, the problem was with pulseIn.  However, I'm not sure if the problem is how it calculates time (counting processor cycles) or it has to do with the time it takes for the sensor to send out a ping.  In any case, it doesn't matter as I've completely re-written the code to use simple timing which works great.  There's not yet an option for the ping to be event driven.  But, it is much faster and more accurate now.

I should be releasing v1.2 later tonight.

Tim

Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: terryking228 on May 24, 2012, 06:12 pm
Quote
Rewrote the pulseIn to use micros() instead of loop counting.  With that change, I got accurate data that matches exactly with the speed of sound.  So, the problem was with pulseIn.


Beautiful, Tim.  You have challenged lots of assumptions with this and it's really good news that you are understanding what's happening. We'll all be listening for your next round!

Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: robtillaart on May 24, 2012, 07:51 pm
Quote
Rewrote the pulseIn to use micros() instead of loop counting.

Be aware that micros() always round its value to a multiple of 4.

Counting the loops in pulsein works quite well, however if there are interrupt handled during this it will definitely give a wrong (too low) reading. This could (partially) explain why you need a smaller divisor in your formulas.
This "trick" is used especially to be able to read pulselengths smaller than 4 micros() precission.

Hope to see the code soon!




Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent - v1.1
Post by: teckel on May 25, 2012, 12:20 am

Quote
Rewrote the pulseIn to use micros() instead of loop counting.

Be aware that micros() always round its value to a multiple of 4.

Counting the loops in pulsein works quite well, however if there are interrupt handled during this it will definitely give a wrong (too low) reading. This could (partially) explain why you need a smaller divisor in your formulas.
This "trick" is used especially to be able to read pulselengths smaller than 4 micros() precission.

Hope to see the code soon!


Let's put it this way.  The pulseIn function is from 460 to 7120 microseconds off because of the way ultrasonic sensors work.  Basically, the echo port state takes that long to settle and pulseIn counts that time.  So, I think I'll settle for only 4 microseconds off. ;-)

I may release the code in the source both ways so if you want to try it the other way, you can uncomment it.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on May 25, 2012, 08:53 am
New in version 1.2:

Lots of code clean-up thanks to Adruino Forum members. Rebuilt the ping timing code from scratch, ditched the pulseIn code as it doesn't give correct results (at least with ping sensors). The NewPing library is now VERY accurate and the code was simplified as a bonus. Smaller and faster code as well. Fixed some issues with very close ping results when converting to inches. All functions now return 0 only when there's no ping echo (out of range) and a positive value for a successful ping. This can effectively be used to detect if something is out of range or in-range and at what distance. Now compatible with Arduino 0023.

Download NewPing v1.2 (http://code.google.com/p/arduino-new-ping/downloads/list)

By default, it uses micros() to do the ping echo timing.  But, I also included alternate code that uses loop counting (similar to what pulseIn uses).  It's streamlined, but follows the same basic concept as pulseIn.

Let me know what you think, and if you have any issues or suggestions.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: robtillaart on May 26, 2012, 11:36 am
Nice job Tim
It took some time to find points for improvement ;)

Quote
All functions now return 0 only when there's no ping echo

That calls for a
Code: [Select]
#define  NOECHO  0
makes the code more readable

(style remark)
adding a few blank lines in your code might improve readability


Comparing against 0 is faster and makes code a few bytes smaller
Code: [Select]

// Alternate, uses loop counting to time ping echo.
unsigned int NewPing::ping()
{
unsigned long maxLoops = microsecondsToClockCycles(_maxEchoTime + MAX_SENSOR_DELAY) / CLOCK_CYCLES;
unsigned long maxLoops2 = microsecondsToClockCycles(_maxEchoTime) / CLOCK_CYCLES;

// Use port registers to trigger a ping.
*_triggerOutput &= ~_triggerBit;
delayMicroseconds(2);
*_triggerOutput |= _triggerBit;
delayMicroseconds(10);
*_triggerOutput &= ~_triggerBit;

// Set a timeout and wait for the echo pin to clear
while (*_echoInput & _echoBit)
if (maxLoops-- == 0) return NOECHO;

        // Wait for the ping to start.
while (!(*_echoInput & _echoBit))
if (maxLoops-- == 0) return NOECHO;

// Ping started, wait for the ping echo to return.
while (*_echoInput & _echoBit)
if (maxLoops2-- == 0) return NOECHO;

// Calculate ping time, 16 = clock cycles of routine overhead.
return clockCyclesToMicroseconds(numloops * CLOCK_CYCLES + 16);
}



Still don't like this one...

#define NewPingConvert(echoTime, conversionFactor) (max(echoTime / conversionFactor, (echoTime ? 1 : 0)))

can be improved by (1) adding rounding and (2) working in millimeters as proposed before.

The granularity of measurement = 4 micros(), in 4 micros sound travels approx  1.35 millimeter, or about  1/7 of a centimeter. that's almost 3 bits of precision, assuming the last 2 are noise your lib should be able to measure 0.5cm == 5mm steps  (1/10th inch) without problems.




Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on May 29, 2012, 06:09 am

Code: [Select]

// Ping started, wait for the ping echo to return.
while (*_echoInput & _echoBit)
if (maxLoops2-- == 0) return NOECHO;

// Calculate ping time, 16 = clock cycles of routine overhead.
return clockCyclesToMicroseconds(numloops * CLOCK_CYCLES + 16);

Comparing against 0 is faster and makes code a few bytes smaller


This is with the loop counting ping method, which I don't suggest using, and is mostly pulseIn with slight changes to work correctly with ultrasonic sensors.

Also, your code doesn't quite work, as it must count the loops to figure out the distance in the final loop.  Also, numloops is not defined.  I tried to implement the corrected version of your code suggestion, but it was actually 2 bytes longer, so one would expect a little slower as well.

I was, however, able to optimize the loop counting ping method to save around 44 bytes.  See below:

Code: [Select]

// Alternate timer, uses loop counting to time the ping echo.
unsigned int NewPing::ping() {
unsigned long numloops = 0;
unsigned long cpu_speed = microsecondsToClockCycles(10);
unsigned long maxLoops = (_maxEchoTime + MAX_SENSOR_DELAY) * cpu_speed / CLOCK_CYCLES / 10;
unsigned long maxLoops2 = _maxEchoTime * cpu_speed / CLOCK_CYCLES / 10;
*_triggerOutput &= ~_triggerBit;
delayMicroseconds(2);
*_triggerOutput |= _triggerBit;
delayMicroseconds(10);
*_triggerOutput &= ~_triggerBit;
while (*_echoInput & _echoBit)
if (numloops++ == maxLoops) return NO_ECHO;
while (!(*_echoInput & _echoBit))
if (numloops++ == maxLoops) return NO_ECHO;
numloops = 1;
while (*_echoInput & _echoBit)
if (numloops++ == maxLoops2) return NO_ECHO;
return clockCyclesToMicroseconds(numloops * CLOCK_CYCLES);
}



Still don't like this one...

#define NewPingConvert(echoTime, conversionFactor) (max(echoTime / conversionFactor, (echoTime ? 1 : 0)))

can be improved by (1) adding rounding and (2) working in millimeters as proposed before.

The granularity of measurement = 4 micros(), in 4 micros sound travels approx  1.35 millimeter, or about  1/7 of a centimeter. that's almost 3 bits of precision, assuming the last 2 are noise your lib should be able to measure 0.5cm == 5mm steps  (1/10th inch) without problems.


If you'd like to suggest an alternative, please provide specific code as I can't read your mind and won't try to guess either.

Also, keep in mind that mm conversion is worthless as the sensor is not accurate enough to measure down to the mm (only accurate to 6-7mm).  Further, doing the math down to the mm level would not be more accurate because temperature is not being considered and the effect of temperature can be a few cm.  In other words, a more complex formula will not yield more accurate results, simply take more program space with no benefit.

Not sure why you're not happy with just changing US_ROUNDTRIP_CM to a fraction or get the microsecond result from ping() and use your own magic conversion code. Am I missing something?  Using the sensors in the real world I can't get 1/10th inch results, how exactly are you doing this?  Or, is it just a theory you have?

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: robtillaart on May 29, 2012, 04:47 pm
Thanks for pointing out the error in my code - 3 posts back - numloops get nowhere incremented  :smiley-red:

Quote
please provide specific code as I can't read your mind


#define NewPingConvert(echoTime, conversionFactor) (max(echoTime / conversionFactor, (echoTime ? 1 : 0)))

add rounding

#define NewPingConvert(echoTime, conversionFactor)  (max( (echoTime+conversionFactor/2) / conversionFactor, (echoTime ? 1 : 0)))


Quote
Using the sensors in the real world I can't get 1/10th inch results, how exactly are you doing this?  Or, is it just a theory you have?

Yes, it is theory to search for what can be reached with the sensors/ code.

You made a good point that the fluctuations due to temperature are large so working in mm makes less/no sense.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on May 29, 2012, 11:47 pm

add rounding

#define NewPingConvert(echoTime, conversionFactor)  (max( (echoTime+conversionFactor/2) / conversionFactor, (echoTime ? 1 : 0)))


Now I believe I understand what you're getting at.  You want to round, say, 10.6cm up to 11cm instead of doing the normal truncate of 10.6cm down to 10cm.  I guess what I was thinking was that it doesn't make much sense to round when dealing with cm because the margin of error is already almost a cm.  But with inches, I can see where rounding could be logical.  I'll do some testing, but probably incorporate it.

I've also been optimizing the loop counting timer and I've got it down to only 8 to 18 bytes longer than the micros() timer.  But, the loop counter will never work for event-driven, so I believe eventually I'll remove it from the source.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on May 30, 2012, 07:02 am
v1.3 will remove the loop counting timing method from NewPing.  I've found that the compiler optimizes the compiled code with inconsistent results.  Sometimes the loop is 17 instructions, other times it's 25 instructions, without changing the loop code.  I tried to nail it down, but it kept drifting all over the place every time I made a change to the code (even well outside the loop).  I'm also worried about different Arduino hardware also changing the the number of instructions in the loops at compile time.  I use Teensy hardware, and while it seemed to match the loop instructions with the Arduino Uno, I just no longer trust that it will the next time I compile, or if compiled for different hardware.

The goal all along was to only have one timer, I included both in v1.2 because I wasn't sure which would end up being best.  And to be honest, the loop counting method could never be made event-driven, so it's days were always numbered as making NewPing totally event driven is one of my primary goals.  And, now that the loop counting code is gone, that's exactly what I'm going to focus on, making NewPing event-driven.  Also, building event-driven 2 and 3 sensor array functions in NewPing.  Finally, a hybrid ping/servo scanner that incorporates the event-driven NewPing with event-driven servo control for fast and fluid scanning while still freeing up the ATmega to do other things.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: robtillaart on May 30, 2012, 07:50 am
Quote
Sometimes the loop is 17 instructions, other times it's 25 instructions, without changing the loop code.

have you tried to make these vars volatile so the compiler would not optimize?
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on May 30, 2012, 02:35 pm
I believe volatile would only be useful if the variables were being changed outside the loop so the compiler would assume they're not being changed and it makes them a constant.  But in this case, they are indeed being changed inside the loop, so I can't imagine that the compiler would assume that.  Actually, if it was assuming that, the code wouldn't work.  Also, there are some values that could be a constant, like the max loop variables.

Seriously, 17 to 25 instructions is a HUGE swing.  When I started seeing odd results I added code that would calculate and display the instruction count.  17, 19, 20, 23, 25...  It was like there was no rhyme or reason to it.

Maybe I'll look into it some more.  But, the loop counting wouldn't work with an event-driven routine anyway so it eventually had to go.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: fred_dot_u on May 31, 2012, 02:40 am
In the process of searching for the HC-SR04 in the forum, this thread has popped up as the most useful resource. I've downloaded the library and run the demo code which works just fine unmodified. One strange aspect is that when it's uploaded to my Uno (1.0), the first measurement appears valid, while all others run to zero. If I press the reset button, all is good until next code upload.

Should I jump to the newer version for my device and if so, what complications can I expect?
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on May 31, 2012, 04:22 am

In the process of searching for the HC-SR04 in the forum, this thread has popped up as the most useful resource. I've downloaded the library and run the demo code which works just fine unmodified. One strange aspect is that when it's uploaded to my Uno (1.0), the first measurement appears valid, while all others run to zero. If I press the reset button, all is good until next code upload.

Should I jump to the newer version for my device and if so, what complications can I expect?


There's no compatibility issues with moving to the latest version of the library.  There's also some bug fixes in the later releases so I would highly suggest upgrading.

My guess is that something else is going wrong, however, as the demo code works but your code is not working correctly.  There's no obvious reason that I can think of that would explain your situation.  So, the best bet is if the latest version of the library still doesn't work, you should post your code source so others or myself can see what the problem is.  I have an Uno and it's one of the platforms I use for testing (I also have a Teensy 2.0).  I really only test with Arduino v1.0.  I have Arduino 0023 on only one of my development machines and all I really do with 0023 is load the demo to make sure it works.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: fred_dot_u on May 31, 2012, 10:52 am
It's too early in the day for me to perform the upgrade, but I will do as suggested. "My code" is the demo code packaged with the library, unchanged in any way. The only action I had to perform for my sensor was to ensure that I had the correct pins connected, which was easy enough. I'll probably do the upgrade this afternoon and see how that affects the need to reset.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on May 31, 2012, 04:17 pm

It's too early in the day for me to perform the upgrade, but I will do as suggested. "My code" is the demo code packaged with the library, unchanged in any way. The only action I had to perform for my sensor was to ensure that I had the correct pins connected, which was easy enough. I'll probably do the upgrade this afternoon and see how that affects the need to reset.


Your sensor says SR04 on it, right?

If it's not working with the demo code, another possibility is the sensor.  I have several SR04 sensors, but one is just not right.  It likes to give 0cm readings, it's either hard of hearing, soft spoken, or there's some kind of logic problem.  As punishment, and to insure I don't pull my hair out thinking it's my code, I wrote with a fine tip Sharpie on the sensors "Bad" - "Robot".  To verify the problem wasn't my library, I tried another ping library as well as direct code I wrote without a library with the same result.  It basically only works closer than about 50cm, then it gets all wonky.  Of course, it was one of the sensors I got on eBay direct from China for $2, so it's kind of expected.  I keep it around because I figure other people purchase these $2 sensors that are probably also defective.  So, I should try to make the library work as best as I can with a defective sensor.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: cyclegadget on May 31, 2012, 06:47 pm

 
Quote
It basically only works closer than about 50cm, then it gets all wonky


I bought some ebay sensors that I think were rated for 70cm. They seem to work to 65cm and then put out a "0" for distance. I got them cheap and for what I want to do it is ok, but I will have to deal with the 0 output when nothing is in the way.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on May 31, 2012, 07:49 pm


 
Quote
It basically only works closer than about 50cm, then it gets all wonky


I bought some ebay sensors that I think were rated for 70cm. They seem to work to 65cm and then put out a "0" for distance. I got them cheap and for what I want to do it is ok, but I will have to deal with the 0 output when nothing is in the way.


The "0" distance is designed to be a "false" (all clear, no ping) reading (0==false).  That makes it easy for you to do a condition on the output.  Basically, if it returns a number, there's something in the way.  If it returns false, it's all clear.  You wouldn't want the library to report back 65cm if there was no ping, because how would you know if there was an object 65cm away or nothing in the way?

You shouldn't have to "deal with the 0 output".  The library is giving you a 0 so you know the ping didn't find anything.  The "0" is a feature, not something you should need to deal with.  Keep in mind that the closest reading is >0, not 0.  If you put your hand almost right against the sensor it will still give you a positive result.

In the next release the "0" is replaced with NO_ECHO.  You "could" change NO_ECHO from 0 to 2850 (50cm x 57us/cm) or whatever if you really wanted to.  It would then be possible to set the maximum distance to 50cm and NO_ECHO to 2850 and then a ping would return a result from 1-50 (never a zero).  But keep in mind that if you get a 50cm, you wouldn't know if there was something 50cm away, or if it was all-clear.  You wouldn't really know till 49cm that there was something in the way.

Maybe I'm missing something?  Or maybe the reason for the "0" (false) result was unclear?

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: cyclegadget on May 31, 2012, 08:03 pm
Quote
Maybe I'm missing something?  Or maybe the reason for the "0" (false) result was unclear?


  I did like that the output was 0 when nothing was in the way because it was at least predictable. I did not realize that you set-up the library to do that on purpose.

I like the idea of true/false based on 0 or non0 that will make it easier to work out the logic for dodging objects.

Keep up the good work!
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: fred_dot_u on Jun 01, 2012, 03:06 am


Your sensor says SR04 on it, right?

If it's not working with the demo code, another possibility is the sensor.  I have several SR04 sensors, but one is just not right.  It likes to give 0cm readings, it's either hard of hearing, soft spoken, or there's some kind of logic problem.  As punishment, and to insure I don't pull my hair out thinking it's my code, I wrote with a fine tip Sharpie on the sensors "Bad" - "Robot".  To verify the problem wasn't my library, I tried another ping library as well as direct code I wrote without a library with the same result.  It basically only works closer than about 50cm, then it gets all wonky.  Of course, it was one of the sensors I got on eBay direct from China for $2, so it's kind of expected.  I keep it around because I figure other people purchase these $2 sensors that are probably also defective.  So, I should try to make the library work as best as I can with a defective sensor.

Tim


The sensor does read HC-SR04 between the transducers, yes.  I'm not sure that I'm getting a proper understanding of versions. A search for updates for my Uno gave me an IDE update from 1.0 to 1.0.1 which has been completed. Is there anything else to update/change? I was not able to find a reference to 0223 that made sense to me. Some references to linux but I'm using win7 platform.

With the demo code, it is still necessary to hit the on-board reset button to get data, but if it's the sensor that's faulty and that's the only shortcoming it is going to display, I can tolerate that for the present.

All the benefits of NewPing and the most beneficial to me is the ease of use. I'll be measuring about four times an hour, so speed isn't critical. A 24 inch range is well within the limitations of this device. The rest of this project is "fluff" and fine tuning and fun.

Is there more to an "update" than what I've described above? Where else to check version information if there is more to it?

thanks
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on Jun 01, 2012, 09:34 am

The sensor does read HC-SR04 between the transducers, yes.  I'm not sure that I'm getting a proper understanding of versions. A search for updates for my Uno gave me an IDE update from 1.0 to 1.0.1 which has been completed. Is there anything else to update/change? I was not able to find a reference to 0223 that made sense to me. Some references to linux but I'm using win7 platform.

With the demo code, it is still necessary to hit the on-board reset button to get data, but if it's the sensor that's faulty and that's the only shortcoming it is going to display, I can tolerate that for the present.

All the benefits of NewPing and the most beneficial to me is the ease of use. I'll be measuring about four times an hour, so speed isn't critical. A 24 inch range is well within the limitations of this device. The rest of this project is "fluff" and fine tuning and fun.

Is there more to an "update" than what I've described above? Where else to check version information if there is more to it?

thanks


When you were talking about upgrading, I figured you meant upgrading the NewPing library, not Arduino.  Arduino 1.0.1 is the latest, 0023 is the previous release before 1.0.  Some people still use 0023 for older sketches/libraries that don't work on 1.0.  You can run 0023, 1.0, and 1.0.1 on the same machine, so it does provide nice options for legacy code.

You said "I've downloaded the library and run the demo code which works just fine unmodified."  Which sounds like the demo works fine, right?  You suggest that you modified the demo, and then it doesn't work correctly.  Which sounds like the problem is with the changes.  Could you try the unmodified demo code again?  If that works, I would need to know exactly what modifications you made, as they appear to be the problem.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: fred_dot_u on Jun 01, 2012, 11:22 am
I think I've been confusing in my expressions. The most recent activity was to update/upgrade from 1.0 to 1.0.1 and I've not had 023 ever. When I discovered NewPing, I felt it was an easier library to use and to understand than my limited experience with ultrasonic.h library.

The demo code was uploaded and the serial monitor displays one line of non-zero distance then displays continuing zero distance figures, regardless of real world conditions. I suspect the non-zero distance is an anomaly. If I press the reset button on the Uno, the serial monitor displays non-zero distance figures.

I'm going to load the code later today that uses the ultrasonic.h library to see if the results are the same. I'm suspecting that the device is at fault, as you suggested.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: cyclegadget on Jun 01, 2012, 01:24 pm

You may have the trigger and echo wires backwards. I have did it 2 or 3 times already and it didn't damage anything.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on Jun 02, 2012, 01:04 am
I've successfully created an interrupt-driven ping function and added it to my development NewPing.  I'm probably going to add a few different interrupt types to satisfy different needs.  This first one uses the timer1 interrupt.  It works fine, but I'm not overly happy with one aspect and I'm hoping someone with experience has some insight.

In the sketch, it's currently being called like this:

Code: [Select]
void setup() {
  sonar.ping_timer1(); // This calls the ping
}

// Timer1 interrupt (I'm using prescale at 64 with the interrupt at 7 counts, in other words, every 28 microseconds this function is called).
ISR(TIMER1_OVF_vect) {
  if (sonar.ping_check()) {  // Check to see if we got a ping echo.
    Serial.print("Ping: ");
    Serial.print(sonar.convert_cm(sonar.ping_result));  // Print the result
    Serial.println("cm");
  }
}


Again, it works great.  But, what I'd really like to do is clean it up a bit for the end-user.  Instead, I'd like it to look like the following:


Code: [Select]
void setup() {
  sonar.ping_timer1(echoCheck); // This calls the ping and sets the interrupt function to "echoCheck".
}

void echoCheck() {
  if (sonar.ping_check()) {  // Check to see if we got a ping echo.
    Serial.print("Ping: ");
    Serial.print(sonar.convert_cm(sonar.ping_result));  // Print the result
    Serial.println("cm");
  }
}


Functionally, identical, just a little easier to understand for the end user.  I understand the basic concept of adding the ISR(TIMER1_OVF_vect) in the library and setting it, but I just can't seem to get it to work without a compiler error.  So, I went out looking for someone else who's done something similar and found the TimerOne library (http://code.google.com/p/arduino-timerone/downloads/list).  The library is fairly simple so it's an easy read.  Specifically, I'm interested in how he does the ISR(TIMER1_OVF_vect).  I've tried to duplicate it, but it just won't compile.  I could give my errors, but I've tried so many different ways that I've had maybe a half dozen different errors.  I think I've nailed down where my problem is to here:

Code: [Select]
TimerOne Timer1;    // preinstatiate

ISR(TIMER1_OVF_vect)          // interrupt service routine that wraps a user defined function supplied by attachInterrupt
{
   Timer1.isrCallback();
}


Anyone know what this "preinstatiate" is?  I would think I could in the case of NewPing do the following:

Code: [Select]
ISR(TIMER1_OVF_vect)          // interrupt service routine that wraps a user defined function supplied by attachInterrupt
{
   NewPing.isrCallback();
}


But, no.  Anyone have any tips or could point me in the right direction on how I should implement having a function call set a function and wrap it insde an interrupt service routine?

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on Jun 02, 2012, 01:31 am
15 minutes after I post all that, I think I have it figured out.  I did some snooping around in Arduino.h and WInterrupts.c and I believe this works:

Code: [Select]
void (*intFunc)();

ISR(TIMER1_OVF_vect) {
if(intFunc) intFunc();
}


With the ping_timer1 doing this:

Code: [Select]
void NewPing::ping_timer1(void (*userFunc)(void)) {
intFunc = userFunc;


Note to self, go snooping in the Arduino code for tips in the future.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: TeslaIaint on Jun 02, 2012, 03:14 am
Hi Tim,
What object do you use to for your ultrasonic sensors to sense? Could you describe the conditions? I'm gonna try your library soon on my maxbotix sensor soon. It's wired the same way, so hopefully it works.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: robtillaart on Jun 02, 2012, 09:29 am

Better do not use print statements in interrupt routines as they take relative long times, while interrupts are made for fast responses.

every 28 microseconds this function is called).
ISR(TIMER1_OVF_vect) {


That means the code is re-entered every 28 micros.

the print statements wil take  - 12 bytes * 10 bits / 115200 = about 1 millisecond  // 10 includes start and stop bit, actually it is higher.

1 millisecond means ~35 times reentered.

Needs some rethinking I guess ...
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on Jun 02, 2012, 10:44 am

Hi Tim,
What object do you use to for your ultrasonic sensors to sense? Could you describe the conditions? I'm gonna try your library soon on my maxbotix sensor soon. It's wired the same way, so hopefully it works.


Objects can be named whatever you want, and you can use any number of objects.  I use "sonar" for the object name in the Example Sketch (http://code.google.com/p/arduino-new-ping/wiki/Example_Sketch).  But, in the Two Ping Sensors Example Sketch (http://code.google.com/p/arduino-new-ping/wiki/Two_Sensor_Example) I use "sonar1" and "sonar2" for the object names. I would imagine that most people would use "ping", "radar", "sonar", "ultrasonic" or something like that for the object name.  But, you could have the object named "maxbotix" and have any number of objects defined, think "look_left", "look_right", "look_ahead".

The only condition is NO_ECHO, which is defined to 0 (false) meaning there was either no ping, or the ping was outside the set range.  Basically, the NO_ECHO (false) condition is that there wasn't a ping.  Other than that, it returns the distance or the ping time (depending on what method you used).

With the next release, there will also be at least one type of interrupt-based ping.  The event-driven methods won't have a NO_ECHO condition.  Because, as it's event-driven, there will only be an event when there's a ping echo within the range specified (the only condition will be that there's something in range).  Basically, the goal of the event-driven methods is that you set a range to say 100cm and then you're off to the rest of your sketch, doing whatever the real goal of your sketch is.  When the ping condition is met (something within 100cm let's say) you then do whatever action is needed in your sketch.  You may have different things you need the sketch to do depending on what the ping distance was.  That's up to your sketch to figure out.

Basically, there's two conditions, NO_ECHO (false) and echo (the distance to the object).  For the interrupt methods, there's only "alarm" conditions, that something is in range, and obviously what that range is.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on Jun 02, 2012, 11:01 am

Better do not use print statements in interrupt routines as they take relative long times, while interrupts are made for fast responses.


That's true. But, by the time the ping_check is called and it's been satisfied, the timer interrupt has already been canceled.  So, the user is free to do whatever they want with the result.  Heck, they can go right back to adding delay(2000) statements in their code for all I care! ;-)

But seriously, what you're not seeing in my little code snippet is what happens in the library before a true condition is met.  It doesn't make total sense with what I posted as it wasn't the full code.  But, be assured that I've made provisions so Serial.print or even long delays won't break anything.  To insure things work for the average joe coder, my development test not only has those 3 print calls, but 6, and I added a delay(1000) in for good measure, and it still works just fine as the timer interrupt has already been canceled.

But, thanks for pointing out a potential deal-breaker if I hadn't thought about that already.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: TeslaIaint on Jun 02, 2012, 01:29 pm
Hi Tim,
I meant to ask what kind of physical objects do you put in front of your sensors to test them?
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on Jun 02, 2012, 11:13 pm

Hi Tim,
I meant to ask what kind of physical objects do you put in front of your sensors to test them?


Wall, chair, hand, box, coffee cup, etc.  It will seriously see anything, even a fast moving object.  One of my goals was to make the library fast enough where you quickly swing your hand in front of the sensor and it would detect it.  As you can do pings every 37 milliseconds, it can sense a very fast moving object.  Not a bullet, but plenty fast for just about any bot situation I can think of.

On the topic of these sensors on a bot.  One of the reasons I starting writing this library was because one of my end goals was to create a fairly fast moving bot that could have several ultrasonic sensors that would work in combination that could quickly map out an environment and make fast decisions on direction without ever having to stop, delay, back-up, delay, turn, delay, move forward.  If we can get readings 10 times a second from 3 sensors at different angles and use an algorithm to convert that data to a frontal map, I believe fairly effective navigation can be achieved.  But, that's another library for another day...

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: TeslaIaint on Jun 03, 2012, 07:09 am
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.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on Jun 03, 2012, 08:34 am

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
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on Jun 06, 2012, 07:23 am
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
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: robtillaart on Jun 06, 2012, 07:43 pm
Quote
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)

Code: [Select]

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


does that make sense?
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.2
Post by: teckel on Jun 07, 2012, 06:49 am

Quote
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)

Code: [Select]

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
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 08, 2012, 08:38 am
NewPing v1.3 Released, download here (http://code.google.com/p/arduino-new-ping/)

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
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: cyclegadget on Jun 08, 2012, 01:24 pm


Thank you for all your hard work! I will definitely try the new version out soon!
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: trendski on Jun 10, 2012, 04:40 pm
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
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: yonatan36 on Jun 10, 2012, 07:39 pm
how can i use the library with ultrasonic ks103 sensor?
www.dauxi.com/KS10X-V110_EN.pdf
thank you
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: AWOL on Jun 10, 2012, 08:20 pm
Quote
how can i use the library with ultrasonic ks103 sensor?
With great difficulty; it's an I2C device.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 11, 2012, 07:07 am

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
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: yonatan36 on Jun 12, 2012, 11:00 am
Hi Tim,
Yes, I have it...

Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: AWOL on Jun 12, 2012, 11:02 am
In which case, you're stuck with whatever algorithm is implemented in the device's firmware.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: NewWorldScientist on Jun 14, 2012, 04:55 pm
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.

Code: [Select]

/*
  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);
}


Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 14, 2012, 05:51 pm

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
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: keeper63 on Jun 15, 2012, 04:19 am
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...?

:D
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: E40racer on Jun 17, 2012, 04:50 pm
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).
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: SANTIMO on Jun 18, 2012, 05:26 am
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
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: cyclegadget on Jun 18, 2012, 03:13 pm

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

Code: [Select]

#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.

Code: [Select]
int cm = sonar.ping_cm();  // Send out the ping, get the results in centimeters.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 18, 2012, 05:34 pm

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.


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
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 18, 2012, 06:26 pm

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).


In the attempt to use IMHO "proper" coding (not using the all too popular dreaded "delay" command), I may have confused some looking for the more typical Arduino code with the typical "delay" commands.  I have an alternative agenda with NewPing, to make people think a little outside the box and try to avoid the "delay"s.  Anyway, following is maybe an easier to understand sketch that uses old-school "delay" commands with NewPing:

Code: [Select]
#include <NewPing.h>

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on ping sensor.
#define ECHO_PIN     11  // 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 srf06(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

void setup() {
}

void loop() {
   // Send out the ping, get the results in centimeters.  Obviously, nothing is being done with this value, your existing sketch would process this information.
   int distance = srf06.ping_cm();

   delay(100);  // Do nothing for 1/10th of a second.  Poor ATmega, it could do 160,000 instructions in this time.
}


There's still a huge advantage in using the NewPing library even using the above sketch.  With other ultrasonic libraries (and I assume the one you're using now) if the sensor doesn't get an echo, the Arduino is just sitting there waiting for a full second for the results (which never arrives).  During this time, no new processing is happening.  A second is a VERY long time, you could be doing 16 million instructions in that time.  With the above sketch, the longest it will sit waiting for an echo is about 30ms (because the maximum distance is set to 200cm).  Therefore, if you implement NewPing in your existing sketch it should seem much faster and consistent when the sensor is not getting a ping echo.  Making your sketch event-driven would further speed up your sketch and allow you to avoid using "delay" commands.  But, NewPing doesn't require this, and your sketch will benefit even if you still use delays.

The "ping_timer" and "check_timer" methods along with the resulting "ping_result" value is a totally different way of interfacing with the sensor.  This can further make your sketch event-driven which frees up more processing cycles to do other things in your sketch.  It may be a little more advanced, but is really not that hard.  Here's an ultra-simple example (you would enter your own robot control code as the sketch does nothing as-is).

Code: [Select]
#include <NewPing.h>

#define TRIGGER_PIN  12 // Arduino pin tied to trigger pin on ping sensor.
#define ECHO_PIN     11 // Arduino pin tied to echo pin on ping sensor.
#define MAX_DISTANCE 50 // Maximum distance we want to ping for (in centimeters). I set this to 50cm because in a robot situation you probably don't care about an object 200cm away.

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

void setup() {
   // Set robot to drive forward.
}

void loop() {
   srf06.ping_timer(echoCheck); // Set the function you want to call to check for a ping
   delay(100);  // Do nothing for 1/10th of a second.  Poor ATmega, it could do 160,000 instructions in this time.
}

void echoCheck() { // Timer2 interrupt calls this function every 24uS where you can check the ping status.
     if (srf06.check_timer()) { // This is how you check to see if the ping was received.
         // Detected object within 50cm of robot, call turn function here.  srf06.convert_cm(srf06.ping_result) would be the distance in cm if you need it for your sketch.
     }
}


I hope these scripts make the different methods of NewPing more clear for some.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 18, 2012, 06:31 pm

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


At a minimum, you can just drop this library in to your existing code and use it instead of the old ultrasonic/ping library you're using now.  The syntax of the constructor and methods are designed to match those of other libraries so in most cases it should be very simple to swap.  If you have an existing sketch, you could post it and I'd show you how easy it is to switch things over.  Or, just post the important parts like the library call, constructor, and calls to your existing library.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: duxiaoshi on Jun 19, 2012, 03:17 pm
great job... i use the library in my project and test my robot.
i have 15 SRF05 sonar sensors on the bot. I set pingSpeed 200ms, and pingInterval 35ms, but sometimes i get big value or negative value.  
Code: [Select]
#include <NewPing.h>
#define MAX_DISTANCE 200

NewPing sonar0(41, 42, MAX_DISTANCE);
NewPing sonar1(43, 44, MAX_DISTANCE);
NewPing sonar2(45, 20, MAX_DISTANCE);
NewPing sonar3(21, 22, MAX_DISTANCE);
NewPing sonar4(23, 24, MAX_DISTANCE);
NewPing sonar5(25, 26, MAX_DISTANCE);
NewPing sonar6(27, 28, MAX_DISTANCE);
NewPing sonar7(29, 30, MAX_DISTANCE);
NewPing sonar8(31, 32, MAX_DISTANCE);
NewPing sonar9(34, 33, MAX_DISTANCE); //10
NewPing sonar10(35, 36, MAX_DISTANCE); //11
NewPing sonar11(37, 38, MAX_DISTANCE);
NewPing sonar12(39, 40, MAX_DISTANCE);
NewPing sonar13(50, 51, MAX_DISTANCE);
NewPing sonar14(52, 53, MAX_DISTANCE);

#define pingSpeed      100
#define pingInterval   35
#define SONAR_NUM      15
unsigned long pingTimer[SONAR_NUM];

void setup()
{

 Serial.begin(115200);
 pingTimer[0] = millis() + pingSpeed;
 for(int i = 0; i < SONAR_NUM - 1; i++) {
   pingTimer[i+1] = pingTimer[i] + pingInterval;
 }
}

void loop()
{
 int cm[15];
 unsigned long time = millis();
 if (millis() >= pingTimer[0]) {
   pingTimer[0] += pingSpeed;  
   cm[0] = sonar0.ping_cm();
 }
 if (millis() >= pingTimer[1]) {
   pingTimer[1] = pingTimer[0] + pingInterval;  
   cm[1] = sonar1.ping_cm();
 }
 
 if (millis() >= pingTimer[2]) {
   pingTimer[2] = pingTimer[1] + pingInterval;    
   cm[2] = sonar2.ping_cm();
 }  
 
 if (millis() >= pingTimer[3]) {
   pingTimer[3] = pingTimer[2] + pingInterval;
   
   cm[3] = sonar3.ping_cm();

 }

 if (millis() >= pingTimer[4]) {
   pingTimer[4] = pingTimer[3] + pingInterval;

   cm[4] = sonar4.ping_cm();

 }
 
 if (millis() >= pingTimer[5]) {
   pingTimer[5] = pingTimer[4] + pingInterval;
   
   cm[5] = sonar5.ping_cm();
 }
 
 if (millis() >= pingTimer[6]) {
   pingTimer[6] = pingTimer[5] + pingInterval;

   cm[6] = sonar6.ping_cm();
 }
 
 if (millis() >= pingTimer[7]) {
   pingTimer[7] = pingTimer[6] + pingInterval;
   cm[7] = sonar7.ping_cm();
 }
 
 if (millis() >= pingTimer[8]) {
   pingTimer[8] = pingTimer[7] + pingInterval;
   cm[8] = sonar8.ping_cm();
 }
 
 if (millis() >= pingTimer[9]) {
   pingTimer[9] = pingTimer[8] + pingInterval;
   cm[9] = sonar9.ping_cm();
 }
 
 if (millis() >= pingTimer[10]) {
   pingTimer[10] = pingTimer[9] + pingInterval;
   cm[10] = sonar10.ping_cm();
 }
 
 if (millis() >= pingTimer[11]) {
   pingTimer[11] = pingTimer[10]+ pingInterval;
   cm[11] = sonar11.ping_cm();
 }
 
 if (millis() >= pingTimer[12]) {
   pingTimer[12] = pingTimer[11]+ pingInterval;
   cm[12] = sonar12.ping_cm();
 }

 if (millis() >= pingTimer[13]) {
   pingTimer[13] = pingTimer[12]+ pingInterval;
   cm[13] = sonar13.ping_cm();
 }

 if (millis() >= pingTimer[14]) {
   pingTimer[14] = pingTimer[13]+ pingInterval;
   cm[14] = sonar14.ping_cm();
   for(int i = 0; i < 15; i++) {
     Serial.print("Ping");
     Serial.print(i);
     Serial.print(": ");
     Serial.print(cm[i]);
     Serial.print("cm");
   }
   Serial.println();
 }  
}


The ping12 result like this :

Ping12: 3328cm
Ping12: 12288cm
Ping12: -24544cm

my code is not simple and clean, and i'd like to know how to use NewPing to slove 15 sonar sensors problem
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: AWOL on Jun 19, 2012, 03:23 pm
Code: [Select]
if (millis() >= pingTimer[13]) {
    pingTimer[13] = pingTimer[12]+ pingInterval;
    cm[13] = sonar13.ping_cm();
  }

Your code would be an awful lot shorter if you formed another array of the sonar objects.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: duxiaoshi on Jun 19, 2012, 06:23 pm

Code: [Select]
if (millis() >= pingTimer[13]) {
    pingTimer[13] = pingTimer[12]+ pingInterval;
    cm[13] = sonar13.ping_cm();
  }

Your code would be an awful lot shorter if you formed another array of the sonar objects.


thanks for your advise, and i want to shorter my code. But i don't know how to form NewPing object array. Counld you tell me how to do?
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: JesterSig on Jun 19, 2012, 07:13 pm
I've been using a parallax ping))) using the way described in the tutorial, but I would like to start optimizing my code. I am already using timing events instead of delays between ping measurements to allow processing between ping measurements. I also understand the arduino may hang up to a second while waiting for an echo to not arrive. I believe this is due to the default timeout in the pulseIn command. Is there any difference between just changing this timeout to a maximum distance and using your library (other than the interrupt method)?

For example
duration = pulseIn(pingPin, HIGH, 5800)  // 29 us per centimeter * 200 cm max distance
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 19, 2012, 08:38 pm

I've been using a parallax ping))) using the way described in the tutorial, but I would like to start optimizing my code. I am already using timing events instead of delays between ping measurements to allow processing between ping measurements. I also understand the arduino may hang up to a second while waiting for an echo to not arrive. I believe this is due to the default timeout in the pulseIn command. Is there any difference between just changing this timeout to a maximum distance and using your library (other than the interrupt method)?

For example
duration = pulseIn(pingPin, HIGH, 5800)  // 29 us per centimeter * 200 cm max distance


First, setting a limit would greatly help your current sketch.  But, you have a bit of a math issue as 200cm is 400cm round-trip and the speed of sound in a typical indoor environment is closer to 28.5uS/cm.  If you wanted to set a maximum distance of 200cm, you should set it to around 11400uS, not 5800uS.  5800uS would be closer to 102cm max distance.

There's a few differences in NewPing over standard Ping/Ultrasonic libraries.  Off the top of my head:



So, changing your current sketch so pulseIn is set to a timeout of 11400 should noticeably improve your sketch.  But, using NewPing (especially if you used the interrupt events) would improve your sketch even more.

With that said, NewPing won't currently work with the Ping))) sensor as it uses the same pin for trigger and echo.  It shouldn't be a big deal to make NewPing compatible with the Ping))) sensor and I'd love to make it compatible.  So, if you're willing to give it a try, I could modify NewPing for you and have you try it out.

You should consider using the interrupt method of NewPing at some point also.  As you're already using timing events instead of delays, using the interrupt method of NewPing would free up the ATmega instead of waiting up to 11400uS for a ping to echo back.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: JesterSig on Jun 19, 2012, 09:11 pm
Thanks so much for the fast reply! I've been trying to learn more about libraries and yours is one of the ones I've been playing with. Thanks for correcting my math, I'm sure I would have realized I forgot the return trip when I got home to actually test it. I also wasn't aware that port registers worked faster.

I'll probably come back to your library some time in the future when I want to add more sensors or to change over to interrupts. In the mean time I may try changing the library to work with the parallax ping. I don't mind stumbling around for a while to learn something.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 19, 2012, 11:05 pm

great job... i use the library in my project and test my robot.
i have 15 SRF05 sonar sensors on the bot. I set pingSpeed 200ms, and pingInterval 35ms, but sometimes i get big value or negative value.  

The ping12 result like this :

Ping12: 3328cm
Ping12: 12288cm
Ping12: -24544cm

my code is not simple and clean, and i'd like to know how to use NewPing to slove 15 sonar sensors problem


15 sensors!  Now THAT'S what I'm talking about as a perfect use for the NewPing library!

First, is this only happening for sensor 12?  If so, that could isolate the problem to something wrong with that sensor.

In any case, I believe the problem is that you're setting up the pings to happen 35ms apart, but then starting the loop process again in only 100ms.  This works for 2 sensors, as it only takes 35*2=70ms per cycle through all the sensors.  But, with 15, it would take at least 525ms to cycle through all 15 sensors (35*15=525).  Also, as AWOL stated, making an array of sonar objects makes the code a LOT shorter.  I also noticed you're not using the "time" variable and the "cm" array should be set outside loop().  Below is a streamlined version of your sketch.  I also converted it to use the timer event so it's more event driven:

Code: [Select]
#include <NewPing.h>

#define SONAR_NUM     15
#define MAX_DISTANCE 200
#define PING_INTERVAL 35 // Milliseconds between each sensor ping (35ms is about the minimum to avoid cross-sensor echos.  You could try making this as low as 29ms and see what happens).

const int pingCycle = PING_INTERVAL * (SONAR_NUM + 1); // This used to be PING_SPEED, pings as fast as possible.
unsigned long pingTimer[SONAR_NUM + 1]; // +1 for timer that displays results.
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0;  // Keeps track of which sensor is active.

NewPing sonar[SONAR_NUM] = {
 NewPing(41, 42, MAX_DISTANCE),
 NewPing(43, 44, MAX_DISTANCE),
 NewPing(45, 20, MAX_DISTANCE),
 NewPing(21, 22, MAX_DISTANCE),
 NewPing(23, 24, MAX_DISTANCE),
 NewPing(25, 26, MAX_DISTANCE),
 NewPing(27, 28, MAX_DISTANCE),
 NewPing(29, 30, MAX_DISTANCE),
 NewPing(31, 32, MAX_DISTANCE),
 NewPing(34, 33, MAX_DISTANCE), //10
 NewPing(35, 36, MAX_DISTANCE), //11
 NewPing(37, 38, MAX_DISTANCE),
 NewPing(39, 40, MAX_DISTANCE),
 NewPing(50, 51, MAX_DISTANCE),
 NewPing(52, 53, MAX_DISTANCE)
};

void setup() {
 Serial.begin(115200);
 pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting.
 for (uint8_t i = 0; i < SONAR_NUM; i++) {
   pingTimer[i+1] = pingTimer[i] + PING_INTERVAL;
 }
}

void loop() {
 for (uint8_t i = 0; i <= SONAR_NUM; i++) {
   if (millis() >= pingTimer[i]) {
     pingTimer[i] += pingCycle; // Set next time this sensor will be pinged.
     if (i == SONAR_NUM) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
     else {
        sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping.
       currentSensor = i; // Sensor being accessed.
       cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor.
       sonar[currentSensor].ping_timer(echoCheck); // Do the ping and wait for the echo interrupt.
     }
   }
 }
 // The rest of your code would go here.
}

void echoCheck() {
 if (sonar[currentSensor].check_timer()) { // Check to see if the ping was received.
   cm[currentSensor] = sonar[currentSensor].convert_cm(sonar[currentSensor].ping_result); // Set the sensor distance to the array.
 }
}

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
 for (uint8_t i = 0; i < SONAR_NUM; i++) {
   Serial.print(i);
   Serial.print("=");
   Serial.print(cm[i]);
   Serial.print("cm ");
 }
 Serial.println();
}


I don't have 15 sensors nor an Arduino Mega to totally test this sketch.  But, I did test it with 3 sensors and it worked.  Let me know how it works with your project.  Also, I'd love to see a picture of whatever you have going with 15 sensors.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: duxiaoshi on Jun 20, 2012, 07:33 am


great job... i use the library in my project and test my robot.
i have 15 SRF05 sonar sensors on the bot. I set pingSpeed 200ms, and pingInterval 35ms, but sometimes i get big value or negative value.  

The ping12 result like this :

Ping12: 3328cm
Ping12: 12288cm
Ping12: -24544cm

my code is not simple and clean, and i'd like to know how to use NewPing to slove 15 sonar sensors problem


15 sensors!  Now THAT'S what I'm talking about as a perfect use for the NewPing library!

First, is this only happening for sensor 12?  If so, that could isolate the problem to something wrong with that sensor.

In any case, I believe the problem is that you're setting up the pings to happen 35ms apart, but then starting the loop process again in only 100ms.  This works for 2 sensors, as it only takes 35*2=70ms per cycle through all the sensors.  But, with 15, it would take at least 525ms to cycle through all 15 sensors (35*15=525).  Also, as AWOL stated, making an array of sonar objects makes the code a LOT shorter.  I also noticed you're not using the "time" variable and the "cm" array should be set outside loop().  Below is a streamlined version of your sketch.  I also converted it to use the timer event so it's more event driven:

Code: [Select]
#include <NewPing.h>

#define SONAR_NUM     15
#define MAX_DISTANCE 200
#define PING_INTERVAL 35 // Milliseconds between each sensor ping (35ms is about the minimum to avoid cross-sensor echos.  You could try making this as low as 29ms and see what happens).

const int pingCycle = PING_INTERVAL * (SONAR_NUM + 1); // This used to be PING_SPEED, pings as fast as possible.
unsigned long pingTimer[SONAR_NUM + 1]; // +1 for timer that displays results.
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0;  // Keeps track of which sensor is active.

NewPing sonar[SONAR_NUM] = {
 NewPing(41, 42, MAX_DISTANCE),
 NewPing(43, 44, MAX_DISTANCE),
 NewPing(45, 20, MAX_DISTANCE),
 NewPing(21, 22, MAX_DISTANCE),
 NewPing(23, 24, MAX_DISTANCE),
 NewPing(25, 26, MAX_DISTANCE),
 NewPing(27, 28, MAX_DISTANCE),
 NewPing(29, 30, MAX_DISTANCE),
 NewPing(31, 32, MAX_DISTANCE),
 NewPing(34, 33, MAX_DISTANCE), //10
 NewPing(35, 36, MAX_DISTANCE), //11
 NewPing(37, 38, MAX_DISTANCE),
 NewPing(39, 40, MAX_DISTANCE),
 NewPing(50, 51, MAX_DISTANCE),
 NewPing(52, 53, MAX_DISTANCE)
};

void setup() {
 Serial.begin(115200);
 pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting.
 for (uint8_t i = 0; i < SONAR_NUM; i++) {
   pingTimer[i+1] = pingTimer[i] + PING_INTERVAL;
 }
}

void loop() {
 for (uint8_t i = 0; i <= SONAR_NUM; i++) {
   if (millis() >= pingTimer[i]) {
     pingTimer[i] += pingCycle; // Set next time this sensor will be pinged.
     if (i == SONAR_NUM) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
     else {
        sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping.
       currentSensor = i; // Sensor being accessed.
       cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor.
       sonar[currentSensor].ping_timer(echoCheck); // Do the ping and wait for the echo interrupt.
     }
   }
 }
 // The rest of your code would go here.
}

void echoCheck() {
 if (sonar[currentSensor].check_timer()) { // Check to see if the ping was received.
   cm[currentSensor] = sonar[currentSensor].convert_cm(sonar[currentSensor].ping_result); // Set the sensor distance to the array.
 }
}

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
 for (uint8_t i = 0; i < SONAR_NUM; i++) {
   Serial.print(i);
   Serial.print("=");
   Serial.print(cm[i]);
   Serial.print("cm ");
 }
 Serial.println();
}


I don't have 15 sensors nor an Arduino Mega to totally test this sketch.  But, I did test it with 3 sensors and it worked.  Let me know how it works with your project.  Also, I'd love to see a picture of whatever you have going with 15 sensors.

Tim


thanks, teckel :)
your code works well, no strange or negative value return. 

This is my robot.

two sensor in the front,  one in the back, two in the left and two in the right and two in each corner.
So it's 15 in all.

Now i'm working on how to avoid obstacle by these 15 sensors. I think the hard thing is how to combine these sensors data, and make decision to let bot run right way and avoid obstacle .

let the robot run autonomous and intelligent navigation is my final goal.( I have 9dof IMU sensor in bot and webcam in front to get the odometry data)
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 20, 2012, 09:10 pm

thanks, teckel :)
your code works well, no strange or negative value return. 

This is my robot.

two sensor in the front,  one in the back, two in the left and two in the right and two in each corner.
So it's 15 in all.

Now i'm working on how to avoid obstacle by these 15 sensors. I think the hard thing is how to combine these sensors data, and make decision to let bot run right way and avoid obstacle .

let the robot run autonomous and intelligent navigation is my final goal.( I have 9dof IMU sensor in bot and webcam in front to get the odometry data)


Glad to hear it works.  With that many sensors, it's a prefect situation to see how low you could set PING_INTERVAL before you started getting cross-sensor echo.  It should work if you change from 35ms to 29ms (which as a benefit also speeds up the total cycle time by 100ms).  But, if you're creative with the sensor order, you very well could make this much shorter.  For example, if the sensor ping order is on opposite sites of your robot where you're less likely to get an echo, you'll be able to set PING_INTERVAL lower without cross-sensor echo.  With two sensors in opposite directions, I was able to get accurate results with a PING_INTERVAL of only 8ms!  The advantage is that you could sample more frequently (about 8/second with 8ms interval instead of about 2/second with 35ms).  The disadvantage would be less time to do other things, like process 9dof data.  If the pings are in order around your robot, you probably cant get away with this as the adjacent sensor could get an echo from the previous sensor.

I've added the 15 sensors example sketch to the NewPing Wiki section for others that want to use a bunch of sensors and still have processing cycles to do other things.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 20, 2012, 11:04 pm
I was thinking about the Ping))) sensor and how simple it would be to implement in the NewPing library.  Then, I figured I'd try connecting a SR04 and SRF05 with the trigger and echo pins tied to just one Arduino pin, just like with the Ping))) sensor.  Guess what, with an adjusted library, it works perfectly.  Even works for crazy-fast ping rates of 8ms.

I figured that if the sensor's trigger pin got the output of the echo pin it would cause another trigger or basically screw things up.  Not the case.  Seems that either the echo output doesn't trigger an echo or the sensor turns off sensing of the trigger pin till it gets an echo or exceeds some time length.  Either way, it works, and works as far as I can tell, perfectly.

From my testing, you only need to use one Arduino pin to control an ultrasonic sensor.  At least the SR04, SRF05 and obviously the Ping))) which was designed to use one control pin.

Thoughts?
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 21, 2012, 04:23 am
Did a bunch of testing and the SRF06 will not work as-is using one pin.  However, the SR04 and SRF05 do work with the trigger and echo pins tied to a single Arduino pin.  It appears to work just as well as when using two Arduino pins.  Keep in mind, this is with my slightly modified library, not the release version.

Then I got to thinking; There's probably just a simple component like a diode on the SR04 and SRF05 which makes a one pin connection work.  I quickly figured there wasn't going to be an easy method using diodes alone.  Then I thought maybe a capacitor would isolate the sensor pins.  Sure enough, the SRF06 also works great using only one Arduino pin with just about any capacitor tied to the trigger and echo pins.

So, for the SR04 and SRF05 you can tie both the trigger and echo pins to one Arduino pin using no additional components.  And for the SRF06, tie the trigger and echo pins on the sensor together with a capacitor then tie the trigger pin on the sensor to the Arduino pin.  You don't use a capacitor for the SR04 or SRF05, just for the SRF06.

With duxiaoshi's 15 sensor project, this will save him 15 pins!  He could probably use a Teensy 2.0 "brain" now for that giant robot instead of a Arduino Mega.

I'd like to release v1.4 of NewPing with this one pin modification.  But before doing so, I need someone with a Ping))) sensor that can test it.  I want to test it with a Ping))) sensor first because I believe this modification will also make NewPing compatible with the Ping))) sensor.  If anyone has one and is willing to test, let me know.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: cyclegadget on Jun 21, 2012, 05:09 am

I don't have a Ping((( sensor but, your work is extremely commendable and your library has turned into a excellent project. Thanks for the hard work!
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: duxiaoshi on Jun 21, 2012, 10:29 am
yeah, it works when change PING_INTERVAL from 35 to 29.

And now one sonar in the front of bot is not assembled well. so I have only one sonar in the front and one sonar in the back.
I test two sonars on opposite sites of my bot,  with the PING_INTERVAL of 8 ms, and it work.
So i'll modify my code later to shorter the time.

and i have a question that where 35ms , 29ms,  8ms come from ,how it calulate.  The max distance is 2m, so the time of echo is  (2/340) * 2 = 12ms
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 21, 2012, 03:19 pm

yeah, it works when change PING_INTERVAL from 35 to 29.

And now one sonar in the front of bot is not assembled well. so I have only one sonar in the front and one sonar in the back.
I test two sonars on opposite sites of my bot,  with the PING_INTERVAL of 8 ms, and it work.
So i'll modify my code later to shorter the time.

and i have a question that where 35ms , 29ms,  8ms come from ,how it calulate.  The max distance is 2m, so the time of echo is  (2/340) * 2 = 12ms


The time calculations have nothing to do with what you set as the maximum ping distance.  Even if you set a max ping distance to 25cm, the sensor doesn't know that or do something differently.  All that happens is the library will only care about ping echo's within the 25cm range.  What still happens is the sensor sends out a ping and listens for an echo.  That ping echo can be detected from up to 400cm to 500cm away.

So, when one sensor sends out a ping, it can travel up to lets say a maximum of 500cm bounce, and come back and hit a different sensor that you may be reading for a ping echo at the time.  This would be cross-sensor echo.  When calculating the time, you always look at the sensor's maximum detection distance (lets say 500cm as that's what most spec).  500cm * 2 * 28.5uS/sec = 28,500 uS.  There's also around 450uS of delay before a ping starts with the SRF05, which works out to right around 29ms.  In theory, if a sensor is really only able to detect a ping at a maximum distance of 500cm, you could have two sensors right next to each other and ping at 29ms intervals and you should never get any misreadings from cross-sensor echo.

I typically say to ping every 33 to 35ms as a bit of a buffer, just to be sure.  Also, 33ms works out to 30 pings/second which is typically well faster than anyone needs for a single sensor.  Finally, thinking of the sketch being event-driven and doing other things, we'd want to give the ATmega other time to do other things in the sketch other than just ping the sensors.

Your situation is a bit different as you have so many sensors.  A complete sweep at 29ms would take 464ms, so you can only do about 2 sensor sweep cycles per second.  That may be fast enough, and allow time for your sketch to do the other things it needs to do.  Then again, maybe you need it to sweep faster.  The 8ms came from testing of a simple 2 sensor system (pointed in opposite directions) in a small room environment.  At 8ms, it still gave accurate readings without cross-sensor echo.  At 7ms, I started getting random results.  This test by no means is the final decision that 8ms between pings is safe.  It was just what I saw in my test.

For your robot, I would change the ping cycle to trigger the sensors on opposite sides of the robot and rotate around (like drawing a star).  That way, you could limit the possibility of cross-sensor echo and thereby lower the ping rate.  29ms should work really well and I doubt that you could get 8ms to work as reliably as 29ms.  But, maybe somewhere between 29 and 8 will work perfectly for your situation.  It also depends on how fast you need to cycle through the sensors.  If 2 sensor sweeps per second is fast enough, leave it at 29ms.  This gives your sketch more time to do other things than if you tried to make it 8ms.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 21, 2012, 11:38 pm
FYI, further testing and I'm having problems with the combination of a SRF06, using one pin, and using the Teensy hardware.  It works, but only about half the time.  I'm going to try a few things this evening and I'll let everyone know the results.  The plan is to post the new release in the forum for people to test before I release this version.  Specifically, testing it using only one Arduino pin.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: snailshoe on Jun 23, 2012, 06:20 am


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


I am having the same problem with two of my HC-SR04s. All I'm getting is a reading of 0cm regardless of what's in front of the sensor. These sensors both work with a different ultrasonic library. Does anyone have an idea of what may be causing this?
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: duxiaoshi on Jun 23, 2012, 04:27 pm


yeah, it works when change PING_INTERVAL from 35 to 29.

And now one sonar in the front of bot is not assembled well. so I have only one sonar in the front and one sonar in the back.
I test two sonars on opposite sites of my bot,  with the PING_INTERVAL of 8 ms, and it work.
So i'll modify my code later to shorter the time.

and i have a question that where 35ms , 29ms,  8ms come from ,how it calulate.  The max distance is 2m, so the time of echo is  (2/340) * 2 = 12ms


The time calculations have nothing to do with what you set as the maximum ping distance.  Even if you set a max ping distance to 25cm, the sensor doesn't know that or do something differently.  All that happens is the library will only care about ping echo's within the 25cm range.  What still happens is the sensor sends out a ping and listens for an echo.  That ping echo can be detected from up to 400cm to 500cm away.

So, when one sensor sends out a ping, it can travel up to lets say a maximum of 500cm bounce, and come back and hit a different sensor that you may be reading for a ping echo at the time.  This would be cross-sensor echo.  When calculating the time, you always look at the sensor's maximum detection distance (lets say 500cm as that's what most spec).  500cm * 2 * 28.5uS/sec = 28,500 uS.  There's also around 450uS of delay before a ping starts with the SRF05, which works out to right around 29ms.  In theory, if a sensor is really only able to detect a ping at a maximum distance of 500cm, you could have two sensors right next to each other and ping at 29ms intervals and you should never get any misreadings from cross-sensor echo.

I typically say to ping every 33 to 35ms as a bit of a buffer, just to be sure.  Also, 33ms works out to 30 pings/second which is typically well faster than anyone needs for a single sensor.  Finally, thinking of the sketch being event-driven and doing other things, we'd want to give the ATmega other time to do other things in the sketch other than just ping the sensors.

Your situation is a bit different as you have so many sensors.  A complete sweep at 29ms would take 464ms, so you can only do about 2 sensor sweep cycles per second.  That may be fast enough, and allow time for your sketch to do the other things it needs to do.  Then again, maybe you need it to sweep faster.  The 8ms came from testing of a simple 2 sensor system (pointed in opposite directions) in a small room environment.  At 8ms, it still gave accurate readings without cross-sensor echo.  At 7ms, I started getting random results.  This test by no means is the final decision that 8ms between pings is safe.  It was just what I saw in my test.

For your robot, I would change the ping cycle to trigger the sensors on opposite sides of the robot and rotate around (like drawing a star).  That way, you could limit the possibility of cross-sensor echo and thereby lower the ping rate.  29ms should work really well and I doubt that you could get 8ms to work as reliably as 29ms.  But, maybe somewhere between 29 and 8 will work perfectly for your situation.  It also depends on how fast you need to cycle through the sensors.  If 2 sensor sweeps per second is fast enough, leave it at 29ms.  This gives your sketch more time to do other things than if you tried to make it 8ms.

Tim



really busy these days. I have test 8ms intervals, and these is no cross echo, works well. I ping the oppsite sensors one by one ,so 8ms is enoungh, and 14 sensors can
be read in a very very short time. Nice work!
I'd like to look through the NewPing library again after i finish my project this month. Really good library and thanks again.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: snailshoe on Jun 24, 2012, 05:10 am



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


I am having the same problem with two of my HC-SR04s. All I'm getting is a reading of 0cm regardless of what's in front of the sensor. These sensors both work with a different ultrasonic library. Does anyone have an idea of what may be causing this?


Well, I tried the 15 sensor example, changed it for only one sensor, used different pins other than the default 12 and 13 and it works.  But the standard example one doesn't work for mine. Don't know why.

Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 25, 2012, 04:39 pm

I am having the same problem with two of my HC-SR04s. All I'm getting is a reading of 0cm regardless of what's in front of the sensor. These sensors both work with a different ultrasonic library. Does anyone have an idea of what may be causing this?


First, try using the example sketch below, it's the new example that's being included with NewPing.  Be sure you have the trigger and echo pins wired correctly.  Don't change anything in the example, even the pins used.

http://code.google.com/p/arduino-new-ping/wiki/Simple_NewPing_Example

Also, when you say you have a problem with two sensors, does that mean you have other sensors that work and two that do not?  I've found the SR04 sensors tend to have a terrible quality control.  Of the 4 that I have, only 1 I would say works correctly.  The other 3 work, but get all wonky at distances beyond 50cm.

Finally, just to make sure we're both using the same library, attached is my development version of NewPing (v1.4 pre-release).  Just replace these files with the ones already in the NewPing folder.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: deverett on Jun 28, 2012, 05:26 am


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.


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


I have 8 sonars on my robot, all SRF05 which I want to use in single pin mode. I'd be happy to test out a single pin version of the new library.

Dave Everett
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: snailshoe on Jun 28, 2012, 06:10 am


I am having the same problem with two of my HC-SR04s. All I'm getting is a reading of 0cm regardless of what's in front of the sensor. These sensors both work with a different ultrasonic library. Does anyone have an idea of what may be causing this?


First, try using the example sketch below, it's the new example that's being included with NewPing.  Be sure you have the trigger and echo pins wired correctly.  Don't change anything in the example, even the pins used.

http://code.google.com/p/arduino-new-ping/wiki/Simple_NewPing_Example

Also, when you say you have a problem with two sensors, does that mean you have other sensors that work and two that do not?  I've found the SR04 sensors tend to have a terrible quality control.  Of the 4 that I have, only 1 I would say works correctly.  The other 3 work, but get all wonky at distances beyond 50cm.

Finally, just to make sure we're both using the same library, attached is my development version of NewPing (v1.4 pre-release).  Just replace these files with the ones already in the NewPing folder.

Tim


At the moment, I only have the two sensors. There seems to be something wrong with one sensor. It works fine by itself, but as soon as I apply power to the second sensor, the reading of the first sensor shows that something is 5cm away. If I take power away from the second, the first sensor then works fine. With the new library and example sketch, everything else seems to be working. I'll have to get some more of the HC-SR04s and try them out.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 28, 2012, 06:50 am

I have 8 sonars on my robot, all SRF05 which I want to use in single pin mode. I'd be happy to test out a single pin version of the new library.


I attached the version of the library that works with only one pin to the message right before your post.  Here's a link to that message (two links at the bottom of the message):

http://arduino.cc/forum/index.php/topic,106043.msg838337.html#msg838337

For testing, you may want to start with communicating directly to all the sensors without the rest of the bot sketch.  I have a sample 15 sensor sketch that you could easily modify to test your 8 sensors.  The sketch can be found here:

http://code.google.com/p/arduino-new-ping/wiki/15_Sensors_Example

For 8 sensors, you would change SONAR_NUM to 8 and the "sonar" array to only have 8 NewPing objects.  To make them only use one sensor, simply make the trigger and echo pin numbers the same.  For example:

Code: [Select]
NewPing sonar[SONAR_NUM] = {
  NewPing(3, 3, MAX_DISTANCE),
  NewPing(4, 4, MAX_DISTANCE),
  NewPing(5, 5, MAX_DISTANCE),
... complete for rest of sensors ...


After the test is complete, you could then update your full bot sketch to work with the NewPing library.  For a simple non-event-driven example of how to implement the NewPing library, see this very basic "hello world" sketch (again, make the trigger and echo pins the same for one pin wiring):

http://code.google.com/p/arduino-new-ping/wiki/Simple_NewPing_Example

That is, unless your current bot sketch is already event-driven, in which case you may want to look more at the 15 sensor example sketch for how to implement it in your project.

Just so you know, I've tested this release with 5 sensors using only one Arduino pin each and it worked without a hitch.  The only exception is the SRF06 which needed a 0.1uf cap across trigger and echo.  So, if it works for 5 there's no reason it shouldn't work for 8 sensors.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 28, 2012, 06:58 am

At the moment, I only have the two sensors. There seems to be something wrong with one sensor. It works fine by itself, but as soon as I apply power to the second sensor, the reading of the first sensor shows that something is 5cm away. If I take power away from the second, the first sensor then works fine. With the new library and example sketch, everything else seems to be working. I'll have to get some more of the HC-SR04s and try them out.


You're not sharing pins to both sensors are you?  Or having the sensors face each other?

When you say as soon as you apply power to the second sensor, what exactly do you mean?  Do you have a sketch that's connected to these two sensors?  Could you share the sketch?

What it sounds to me like is that you're doing two things at once, or have two sensors connected together.  So each work on their own, but as soon as you try to use both there's a failure.  Seeing your sketch and how you have them wired up would help greatly.

For testing multiple sensors at once, I would suggest using the 15 sensors test sketch found here:

http://code.google.com/p/arduino-new-ping/wiki/15_Sensors_Example

For 2 sensors you would change SONAR_NUM to 2, and the "sonar" array would be changed to something like this:

Code: [Select]
NewPing sonar[SONAR_NUM] = {     // Sensor object array.
  NewPing(12, 11, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(10, 9, MAX_DISTANCE)
}


Obviously, the pins would need to be correctly entered or changed to match.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: deverett on Jun 28, 2012, 03:43 pm


I have 8 sonars on my robot, all SRF05 which I want to use in single pin mode. I'd be happy to test out a single pin version of the new library.


I attached the version of the library that works with only one pin to the message right before your post.  Here's a link to that message (two links at the bottom of the message):

http://arduino.cc/forum/index.php/topic,106043.msg838337.html#msg838337

For testing, you may want to start with communicating directly to all the sensors without the rest of the bot sketch.  I have a sample 15 sensor sketch that you could easily modify to test your 8 sensors.  The sketch can be found here:

http://code.google.com/p/arduino-new-ping/wiki/15_Sensors_Example

For 8 sensors, you would change SONAR_NUM to 8 and the "sonar" array to only have 8 NewPing objects.  To make them only use one sensor, simply make the trigger and echo pin numbers the same.  For example:

Code: [Select]
NewPing sonar[SONAR_NUM] = {
  NewPing(3, 3, MAX_DISTANCE),
  NewPing(4, 4, MAX_DISTANCE),
  NewPing(5, 5, MAX_DISTANCE),
... complete for rest of sensors ...


After the test is complete, you could then update your full bot sketch to work with the NewPing library.  For a simple non-event-driven example of how to implement the NewPing library, see this very basic "hello world" sketch (again, make the trigger and echo pins the same for one pin wiring):

http://code.google.com/p/arduino-new-ping/wiki/Simple_NewPing_Example

That is, unless your current bot sketch is already event-driven, in which case you may want to look more at the 15 sensor example sketch for how to implement it in your project.

Just so you know, I've tested this release with 5 sensors using only one Arduino pin each and it worked without a hitch.  The only exception is the SRF06 which needed a 0.1uf cap across trigger and echo.  So, if it works for 5 there's no reason it shouldn't work for 8 sensors.

Tim


Thanks Tim, I wasn't logged in before so I couldn't see the attachments. I'm currently rewiring with shielded cable to all the sensors so I hope to test the code late tomorrow. As you suggest it will be just the multi-sonar sketch trimmed down to 8.

I'll let you know the results.

Thanks again,
Dave Everett
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: deverett on Jun 29, 2012, 07:11 am
Tim,
So far everything is working fine with the single pin version. I've only had time to wire up 2 of the sonars so far.

Dave
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 29, 2012, 02:17 pm

Tim,
So far everything is working fine with the single pin version. I've only had time to wire up 2 of the sonars so far.

Dave


Basically, because the library is designed specifically to communicate with ultrasonic sensors instead of using stock commands like pulseIn, it waits for all the correct pin states between the trigger and echo stages.  So, it can both trigger and echo using the same Arduino pin because the output and input stages are clearly defined.

The idea came when I wired a sensors incorrectly (trigger and echo pins reversed) with no ill effect while looking at adding support for the Ping))) sensor which only uses 1 pin for both trigger and echo.  I knew it wouldn't break anything to try (from my incorrect wiring experience) and it also seemed logical that the sensor was only ever listening for a trigger during certain situations and only sending an echo output during other situations.  Sure enough, I believe 3 lines of code were modified and it worked perfectly.

On projects where you have multiple sensors (which many have) reducing the number of pins needed by half is huge.  Projects that at once needed a large Arduino Mega could be done with a thumbnail-sized Teensy 2.0.

Keep us updated!

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jun 29, 2012, 08:39 pm
I wanted to add that I have a HC-SR04 that doesn't work with NewPing 1.2, 1.3, or the 1.4 pre-release, using either the Simple NewPing Example Sketch or the 15-sensor example, modified for 1 HC-SR04.  It works fine with the example code at http://goo.gl/kJ8Gl though.

How can I help debug the library for the HC-SR04?

EDIT: Forgot to add that I'm using an Arduino Uno r3 with the v1.0 Arduino IDE.

EDIT2: I get 0cm like everyone else with an HC-SR04 reported. I even tried getting the raw timing data instead, in case it was an obscure bug in the distance conversion. Everything I get is 0.

EDIT3: In case it's helpful, I note that I can hear the HC-SR04 sending out its sonar pings when I try NewPing. So I would guess that the bug doesn't involve actually sending out the pings.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jun 30, 2012, 01:28 am

I wanted to add that I have a HC-SR04 that doesn't work with NewPing 1.2, 1.3, or the 1.4 pre-release, using either the Simple NewPing Example Sketch or the 15-sensor example, modified for 1 HC-SR04.  It works fine with the example code at http://goo.gl/kJ8Gl though.

How can I help debug the library for the HC-SR04?

EDIT: Forgot to add that I'm using an Arduino Uno r3 with the v1.0 Arduino IDE.

EDIT2: I get 0cm like everyone else with an HC-SR04 reported. I even tried getting the raw timing data instead, in case it was an obscure bug in the distance conversion. Everything I get is 0.

EDIT3: In case it's helpful, I note that I can hear the HC-SR04 sending out its sonar pings when I try NewPing. So I would guess that the bug doesn't involve actually sending out the pings.


I have (4) HC-SR04 sensors and they all work just fine with the Arduino Uno R3 using every library version of NewPing as well as every example sketch.  I've also run with Arduino 0023, v1.0 and have just switched to v1.0.1 all of which work.  So, I believe it's unfair to say "I get 0cm like everyone else with an HC-SR04 reported".  There's only a couple people that have reported a problem, it's running just fine for me with 4 different sensors, so not everyone is having a problem.

There's differences between my example sketches and the sketch at the link you provided.  For example, it's only doing 2 pings a second while my examples are typically doing 20 pings a second.  So, maybe your sensor can't ping that frequently.  To diagnose this, I've modified my example sketch to duplicate what that other example is doing.

Code: [Select]


#include <NewPing.h>

#define trigPin 12
#define echoPin 11

NewPing sonar(trigPin, echoPin);

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

void loop() {
 int distance = sonar.ping_cm();
 Serial.print(distance);
 Serial.println("cm");
 delay(500);
}


If this still doesn't work, it could be the VERY long trigger delay in the example you provided.  It's waiting 1000 microseconds when the sensor specs state it should only require 10 microseconds.  If your sensor is way out of spec, maybe it needs longer than 10 microseconds.  To change this in the NewPing library, look for the "delayMicroseconds(10)" in the NewPing.cpp file (line 48 in the 1.4 pre-release) and change it from 10 microseconds to 1000 microseconds.

If it still doesn't work, try changing the MAX_SENSOR_DELAY in the NewPing.h file from 18000 to 180000 (add a zero at the end).  This will give your sensor more time to finish the ping before waiting for the echo.  The longest I've ever measured is around a 17000 microsecond delay, but maybe your sensor requires longer.

If it's still not working for you, you could send me your sensor.  If I had the sensor, I could hopefully duplicate it and see what exactly is happening.  Of course, I'd send it back when I was done with the diagnosis.

Let me know what you find or if you want to send me the sensor for diagnosis.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: wrek on Jun 30, 2012, 02:11 am
HC-SR04 not working for me with the latest sketch.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: xerof on Jul 02, 2012, 09:23 am
Wow, I love the V1.4 with just the one pin required! - I started a project at the weekend, and solderd a long length of cable together, and at certain points only left 3 pins (+5,GND,Signal) - And it didn't work well. I was about to start chopping away at my cable to make room for another cable at each set interval untill I started reading this post again and noticed that about the v1.4 only needing one I/O pin, so you have saved me lots of work :)

I am using HR-S04 btw, and they seem to be working perfectly with the 1 pin v1.4

Cheers!
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 02, 2012, 03:38 pm

HC-SR04 not working for me with the latest sketch.


The HC-SR04 seem to be a real hit or miss in the quality department.  Or, there's several manufactures with different specs.  I have 4 of them, and they all work.

Try this, set MAX_SENSOR_DELAY in NewPing.h from 18000 to 180000 and in NewPing.cpp change "delayMicroseconds(10)" (line 48 in the 1.4 pre-release) to "delayMicroseconds(1000)".  And let me know if that changes anything.

Also, what Arduino hardware are you using and what sketches have you tried?

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 02, 2012, 06:17 pm
Hi!  Thanks for your reply.


I have (4) HC-SR04 sensors and they all work just fine with the Arduino Uno R3 using every library version of NewPing as well as every example sketch.  I've also run with Arduino 0023, v1.0 and have just switched to v1.0.1 all of which work.  So, I believe it's unfair to say "I get 0cm like everyone else with an HC-SR04 reported".  There's only a couple people that have reported a problem, it's running just fine for me with 4 different sensors, so not everyone is having a problem.

You're right - it was a poor choice of wording. I didn't mean to imply that every HC-SR04 owner had the "0cm" bug. I was trying to say that I had the same "0cm" bug that was reported here by other HC-SR04 owners. And it's certainly hard to diagnose problems like this if your HC-SR04s aren't showing the problem. Did you get them all from the same vendor?


There's differences between my example sketches and the sketch at the link you provided.  For example, it's only doing 2 pings a second while my examples are typically doing 20 pings a second.  So, maybe your sensor can't ping that frequently.  To diagnose this, I've modified my example sketch to duplicate what that other example is doing.
...
If this still doesn't work, it could be the VERY long trigger delay in the example you provided.  It's waiting 1000 microseconds when the sensor specs state it should only require 10 microseconds.  If your sensor is way out of spec, maybe it needs longer than 10 microseconds.  To change this in the NewPing library, look for the "delayMicroseconds(10)" in the NewPing.cpp file (line 48 in the 1.4 pre-release) and change it from 10 microseconds to 1000 microseconds.

If it still doesn't work, try changing the MAX_SENSOR_DELAY in the NewPing.h file from 18000 to 180000 (add a zero at the end).  This will give your sensor more time to finish the ping before waiting for the echo.  The longest I've ever measured is around a 17000 microsecond delay, but maybe your sensor requires longer.

I will look at that. I tried this investigation from the other direction, modifying that sketch I provided to do 20 pings per second with a 10 microsecond trigger delay. It still works in that sketch. Those two timings do not appear to explain the difference in behavior with NewPing. I will try changing MAX_SENSOR_DELAY in NewPing to see if that is a factor.


If it's still not working for you, you could send me your sensor.  If I had the sensor, I could hopefully duplicate it and see what exactly is happening.  Of course, I'd send it back when I was done with the diagnosis.

I may be able to do that, since I did buy a second sensor to try to compensate for the HC-SR04's occasional lie. (Sometimes reports out of range value when there is *definitely* something in range; sometimes reports in-range value when there is *definitely* nothing in range.) I'll also try my second sensor to see if it does or doesn't have the problem, but it appears to be the same exact build, and it's from the same reseller (so it may even be the same batch). I'll report back what I find.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 02, 2012, 06:32 pm

If it still doesn't work, try changing the MAX_SENSOR_DELAY in the NewPing.h file from 18000 to 180000 (add a zero at the end).  This will give your sensor more time to finish the ping before waiting for the echo.  The longest I've ever measured is around a 17000 microsecond delay, but maybe your sensor requires longer.

I tried in the 1.4 pre-release code base with 180000 microseconds MAX_SENSOR_DELAY and a 1000 microsecond delay between triggering HIGH and letting the HC-SR04 see this, and there was no change in behavior.

Are you using all 4 pins on your HC-SR04s, or are you using 3? You mentioned a recent optimization where you could do trigger and echo on the same pin. I'm using all 4 pins. Could that be the difference?

EDIT: I tried this with my second HC-SR04, but it's likely out of the same batch.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: xerof on Jul 02, 2012, 09:14 pm
I used 2 sensors with the 15 Sensor example sketch, and found that what I needed to do, it was too slow at picking up changes.

I reverted back to adding 2 seperate sensors, and doing 2 seperate checks, See code below:

Code: [Select]

#include <NewPing.h>


#define SONAR_NUM     2 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.


NewPing sonar_START(6,6, MAX_DISTANCE);
NewPing sonar_END(7,7, MAX_DISTANCE);

unsigned int pingSpeed = 30;  // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer[2];                // +1 for timer that displays results.


void setup()
{
  Serial.begin(9600);
  pingTimer[0] = millis() + 50;
  pingTimer[1] = millis() + 100;
/* Delays the start up per sensor, as I want to know the distance when it first starts up from the object - Running them at the same time causes issues. */
}

void loop()
{
  if (millis() >= pingTimer[0]) {
    pingTimer[0] += pingSpeed;
    startCheck();
  }
  if (millis() >= pingTimer[1]) {
    pingTimer[1] += pingSpeed;
    endCheck();
  }
}


void startCheck()
{
  int cm = sonar_START.ping_cm();
//Doing some code here
}

void endCheck()
{
  int cm = sonar_END.ping_cm();
//Doing some other code here
}



The above method, works quicker and more reliable than using the code from the 15 sketch example with changing NUM_SONOR to 2
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 03, 2012, 05:03 pm

I used 2 sensors with the 15 Sensor example sketch, and found that what I needed to do, it was too slow at picking up changes.

I reverted back to adding 2 seperate sensors, and doing 2 seperate checks, See code below:

Code: [Select]
#include <NewPing.h>

#define SONAR_NUM     2 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar_START(6,6, MAX_DISTANCE);
NewPing sonar_END(7,7, MAX_DISTANCE);

...


The above method, works quicker and more reliable than using the code from the 15 sketch example with changing NUM_SONOR to 2


Well, it may be faster, but only at the expense of possible cross-sensor echo issues as you're sometimes pinging only 10ms apart. Your pings are at 50, 80, 100, 110, 130, 140ms (some of those are only 10ms apart).  You could make the 15 sensor sketch faster by simply changing the PING_INTERVAL value to 10ms, but unless the sensors are pointing in opposite directions, you very well could get cross-sensor echo issues.

Also, your sketch doesn't use the timer interrupt method, which will free up your sketch to run other tasks at the same time it's doing the ping.  Basically, the 15 sensor sketch is event-driven (multitasking) even during the ping process.  This is a far more preferred method of programming.  You could also simplify your sketch by keeping the two sensor objects in an array so you wouldn't need two different if statements and two different functions to process the results.

Below is a modified version of the 15 sensor sketch that just uses 2 sensors, is event-driven (uses the timer interrupt method), but still allows a user to easily change for more than 2 sensors.  It also displays each ping result individually as you wanted.  The ping times are 29ms apart, which shouldn't cause any cross-sensor echo issues.  If you want to make them every 10ms, just change PING_INTERVAL from 29 to 10.  But, I would not suggest it unless you're sensors are pointing in opposite directions.  Here's the sketch:

Code: [Select]
#include <NewPing.h>

#define SONAR_NUM      2 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 29 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Timer array.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 255;        // Keeps track of which sensor is active (255 indicates starting position).

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

void setup() {
 Serial.begin(115200);
 pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
 for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
   pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void loop() {
 for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through the sensors.
   if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
     pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
     if (currentSensor < SONAR_NUM) {
       processResult(currentSensor);             // Previous sensor ping complete, do something with the results.
       sonar[currentSensor].timer_stop();        // Make sure previous timer is canceled before starting a new ping (insurance).
     }
     currentSensor = i;                          // Sensor being accessed.
     cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
     sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
   }
 }
 // The rest of your code would go here.
}

void echoCheck() { // If ping received, set the sensor distance to array.
 if (sonar[currentSensor].check_timer()) cm[currentSensor] = sonar[currentSensor].convert_cm(sonar[currentSensor].ping_result);
}

void processResult(uint8_t sensor) { // Do something with the results.
 Serial.print(sensor);
 Serial.print("=");
 Serial.print(cm[sensor]);
 Serial.println("cm ");
}
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 03, 2012, 05:10 pm


If it still doesn't work, try changing the MAX_SENSOR_DELAY in the NewPing.h file from 18000 to 180000 (add a zero at the end).  This will give your sensor more time to finish the ping before waiting for the echo.  The longest I've ever measured is around a 17000 microsecond delay, but maybe your sensor requires longer.

I tried in the 1.4 pre-release code base with 180000 microseconds MAX_SENSOR_DELAY and a 1000 microsecond delay between triggering HIGH and letting the HC-SR04 see this, and there was no change in behavior.

Are you using all 4 pins on your HC-SR04s, or are you using 3? You mentioned a recent optimization where you could do trigger and echo on the same pin. I'm using all 4 pins. Could that be the difference?

EDIT: I tried this with my second HC-SR04, but it's likely out of the same batch.


All of my HC-SR04 sensors work with both 2 pins and 1 pin, so it has nothing to do with the pins.  Who did you purchase your sensors from as I'd love to duplicate the problem.

Also see the attached file to this message.  This modified version of the library simulates the pulseIn function that's being used the example sketch you linked to (waits up to a second for a ping echo).  I would not suggest anyone else using this library, it's just meant for testing for those with a HC-SR04 that are giving 0cm results.  It's an inferior library just meant for testing.

Let me know how this works.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 03, 2012, 11:12 pm

All of my HC-SR04 sensors work with both 2 pins and 1 pin, so it has nothing to do with the pins.  Who did you purchase your sensors from as I'd love to duplicate the problem.

I got them from this vendor on Amazon http://www.amazon.com/gp/product/B0085MXZH0/ref=oh_details_o01_s00_i00

They're currently out of stock, so replacements you get may or may not be the same batch.


Also see the attached file to this message.  This modified version of the library simulates the pulseIn function that's being used the example sketch you linked to (waits up to a second for a ping echo).  I would not suggest anyone else using this library, it's just meant for testing for those with a HC-SR04 that are giving 0cm results.  It's an inferior library just meant for testing.

Let me know how this works.

I'll try that out tomorrow and report back. Thanks for your help!
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 04, 2012, 05:44 am

I got them from this vendor on Amazon http://www.amazon.com/gp/product/B0085MXZH0/ref=oh_details_o01_s00_i00

They're currently out of stock, so replacements you get may or may not be the same batch.


I got one from this vendor on Amazon:
http://www.amazon.com/Ultrasonic-Module-HC-SR04-Distance-Arduino/dp/B004U8TOE6/ref=pd_cp_e_1

Two others I got direct from China on eBay.  I forgot where the 4th one came from.  All work, but 3 are only stable to around 50cm.  This is the case with any library I use or if I use a sketch without a library.  So they're defective for sure, and 3 out of 4 being defective makes me question the quality of the HC-SR04 sensors.

I'd say the SRF05 is the best sensor.  Works perfectly and works with only one pin.  It's also easy to identify as it's the only ultrasonic sensor I know of that has 5 pins (one is not used).

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: AWOL on Jul 04, 2012, 08:26 am
Quote
It's also easy to identify as it's the only ultrasonic sensor I know of that has 5 pins

So does the SRF04.
SRF02 also has five pins, but it is I2C.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 04, 2012, 06:11 pm
I tried NewPingTest1, and I get one ping per second, returning 0cm each time. Is there a specific sketch you wanted me to use? I used the minimal sketch that does 20 pings per second in the loop() function.

This is with the sensor that works fine with that standalone code I linked to, even when I assign delays and timeouts that are consistent with the baseline NewPing.

If you're interested, I can mail it to you.  I have two of them, and I just ordered an HY-SRF05.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 05, 2012, 04:43 am

I tried NewPingTest1, and I get one ping per second, returning 0cm each time. Is there a specific sketch you wanted me to use? I used the minimal sketch that does 20 pings per second in the loop() function.

This is with the sensor that works fine with that standalone code I linked to, even when I assign delays and timeouts that are consistent with the baseline NewPing.

If you're interested, I can mail it to you.  I have two of them, and I just ordered an HY-SRF05.


That basic sketch is just fine.  The modified library basically waits up to 1 full second for the ping echo (which is what pulseIn does).  It's very interesting that it doesn't work for you yet we are running seemingly identical hardware.  The only variable is the sensor, so yes, it would be great if you could send it to me.  I'll message you my address.  I'm sure we can get to the bottom of this if I have a sensor with this issue in front of me to test.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: deverett on Jul 05, 2012, 10:45 am


Tim,
So far everything is working fine with the single pin version. I've only had time to wire up 2 of the sonars so far.

Dave


Basically, because the library is designed specifically to communicate with ultrasonic sensors instead of using stock commands like pulseIn, it waits for all the correct pin states between the trigger and echo stages.  So, it can both trigger and echo using the same Arduino pin because the output and input stages are clearly defined.

The idea came when I wired a sensors incorrectly (trigger and echo pins reversed) with no ill effect while looking at adding support for the Ping))) sensor which only uses 1 pin for both trigger and echo.  I knew it wouldn't break anything to try (from my incorrect wiring experience) and it also seemed logical that the sensor was only ever listening for a trigger during certain situations and only sending an echo output during other situations.  Sure enough, I believe 3 lines of code were modified and it worked perfectly.

On projects where you have multiple sensors (which many have) reducing the number of pins needed by half is huge.  Projects that at once needed a large Arduino Mega could be done with a thumbnail-sized Teensy 2.0.

Keep us updated!

Tim


Up to 6 sonars now, not a hitch. Also I think the reads are more stable as I get solid results even when the robot is moving. I currently have the update set at 80ms, but I'm about to take it back to 35ms as the number of sonars increases.

You do good work Tim.

Dave
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 05, 2012, 09:54 pm
I put my HC-SR04 sensor in the mail to Tim today. Hopefully it'll tighten the test cycle and benefit others who have HC-SR04 sensors. :)

My backup HC-SR04 is definitely less reliable than the one I shipped out, but it still "works" (for some value of "work"). I have digital filters in place to try to determine if a reading is true or not, so this mitigates the inherent issues with the sensor.

My code base can also create a virtual sensor from N actual sensors, and I was planning to do this to work around the unreliability, since it seemed unlikely that two sensors would be unreliable at the same moment in time (unless there are common environmental or power factors that cause this).  If the HY-SRF05 is more reliable, then I can probably start trusting the data more and tune the digital filters to be more lenient.

Is there any demand for virtual sensors as I described?  If so, I can work on turning what I have into a subclass of NewPing. It sounded like other people are using multiple sensors in non-redundant ways, and if the reliability solution really is "just buy an HR-SRF05" then maybe that effort would be wasted.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 07, 2012, 06:19 am

I put my HC-SR04 sensor in the mail to Tim today. Hopefully it'll tighten the test cycle and benefit others who have HC-SR04 sensors. :)

My backup HC-SR04 is definitely less reliable than the one I shipped out, but it still "works" (for some value of "work"). I have digital filters in place to try to determine if a reading is true or not, so this mitigates the inherent issues with the sensor.

My code base can also create a virtual sensor from N actual sensors, and I was planning to do this to work around the unreliability, since it seemed unlikely that two sensors would be unreliable at the same moment in time (unless there are common environmental or power factors that cause this).  If the HY-SRF05 is more reliable, then I can probably start trusting the data more and tune the digital filters to be more lenient.

Is there any demand for virtual sensors as I described?  If so, I can work on turning what I have into a subclass of NewPing. It sounded like other people are using multiple sensors in non-redundant ways, and if the reliability solution really is "just buy an HR-SRF05" then maybe that effort would be wasted.


Can't wait to get the sensor and figure out what's going on.  I hope to test and send back ASAP.

With properly working sensors, a virtual sensor from multiple sensors should not be required.  Sensors that actually work are very reliable and give consistent and accurate readings all the time.  I also have sensors that "work" but are clearly not 100% functional (this is with any library).  Mine having a problem seem to work to around 50cm, then get all wonky.

While I find that my SRF05 and SRF06 are more reliable, online I've also found at least two totally different kinds of SRF05 sensors.  Both have the same model number on them, but each are electronically different with different pinouts.  So, I don't want to totally endorse the SRF05 as superior, as it appears they're made my multiple manufactures with different specs.  Which is probably why there's some HC-SR04 sensors that "work" and probably why the HC-SR04 sensors you have don't work with my library, as they're made by a bunch of different manufactures, with different specs or quality control.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 07, 2012, 06:53 pm

Can't wait to get the sensor and figure out what's going on.  I hope to test and send back ASAP.

I'm still amazed you're volunteering to do this :) That's dedication!

If you find that the SR04 that I sent you behaves significantly differently than the ones you have, I would be happy for you to keep it for regression testing purposes. (I could potentially help write a regression test, too, although I've never tried making one for an Arduino library, and it couldn't be fully automated due to its nature.) I have a spare SR04 anyway, and they're cheap enough that I could just order more if I wanted more.


With properly working sensors, a virtual sensor from multiple sensors should not be required.  Sensors that actually work are very reliable and give consistent and accurate readings all the time.  I also have sensors that "work" but are clearly not 100% functional (this is with any library).  Mine having a problem seem to work to around 50cm, then get all wonky.

The sensor I'm sending you works up to 100cm (I didn't try longer distances), but it occasionally throws in an outlier of some kind, whether it's an in-range but wrong value while something is in the sensor's range, an out-of-range value while something is in range, or an in-range value while nothing is in range. I agree that if a sensor is working properly, it shouldn't do this. My original idea was to use virtual sensors to combat inherent unreliability issues with these cheap sensors (much like RAID was created to create reliability out of unreliable cheap parts), but if there are reliable sensors in the same family for the same price, I think I should just use those :)


While I find that my SRF05 and SRF06 are more reliable, online I've also found at least two totally different kinds of SRF05 sensors.  Both have the same model number on them, but each are electronically different with different pinouts.  So, I don't want to totally endorse the SRF05 as superior, as it appears they're made my multiple manufactures with different specs.  Which is probably why there's some HC-SR04 sensors that "work" and probably why the HC-SR04 sensors you have don't work with my library, as they're made by a bunch of different manufactures, with different specs or quality control.

Hmm. Any such variations with the SRF06 sensors?
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 07, 2012, 10:08 pm

Hmm. Any such variations with the SRF06 sensors?


It doesn't appear there's different types of SRF06 sensors.  But, I wouldn't be surprised if there were multiple manufactures.  Also, the SRF06 won't work using one pin unless you put a cap across the trigger and echo pins, and, even that doesn't work with the Teensy.  The ability to use only one pin is a huge advantage as in many projects multiple sensors are used and pins can be in short supply.  For that reason, I'd lean towards the SRF05, which for at least one manufacture is actually designed to be used with only one pin.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 08, 2012, 05:49 am


Can't wait to get the sensor and figure out what's going on.  I hope to test and send back ASAP.

I'm still amazed you're volunteering to do this :) That's dedication!

If you find that the SR04 that I sent you behaves significantly differently than the ones you have, I would be happy for you to keep it for regression testing purposes. (I could potentially help write a regression test, too, although I've never tried making one for an Arduino library, and it couldn't be fully automated due to its nature.) I have a spare SR04 anyway, and they're cheap enough that I could just order more if I wanted more.


Got your sensor today and had to plug it in to see what happens.  Connected to the Teensy 2.0, it works perfectly with both 2 and 1 pins.  Don't have a connector on this computer to connect to the Arduino R3, but I'll try it tomorrow on my primary system.  Turning out to be quite a good puzzle this is.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: karan2012singh on Jul 09, 2012, 04:06 am
hii,..i m using hc-sr04 ultrasonic sensor,..i m using the lastest version of ping,...all my connections are fine,,... and the code i m running is..
// ---------------------------------------------------------------------------
// Getting a reliable ping every 50 milliseconds isn't possible with other ping or ultrasonic libraries.
// These kinds of speeds work perfectly with the NewPing library. Even at the maximum sensor distance of
// 500cm, distance measurements can be done 20 times a second! If you set the maximum distance to 200cm
// as we have in this example sketch, even faster pings can be achieved. I suggest waiting at least 37
// milliseconds between pings to avoid previous ping echo issues, that translates to a maximum ping rate
// of around 27 times per second. Much better than the sometimes 1 ping a second with other libraries.
//

#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() {
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}

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.
Serial.print("Ping: ");
int cm = sonar.ping_cm(); // Send out the ping, get the results in centimeters.
Serial.print(cm); // Print the result (0 = outside the set distance range, no ping echo)
Serial.println("cm");
}
}
and the output coming is..
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
and continue....
i dont know why,..the sensor is just giving this output
plzz help
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 09, 2012, 04:38 am

hii,..i m using hc-sr04 ultrasonic sensor,..i m using the lastest version of ping,...all my connections are fine,,... and the code i m running is..
// ---------------------------------------------------------------------------
// Getting a reliable ping every 50 milliseconds isn't possible with other ping or ultrasonic libraries.
// These kinds of speeds work perfectly with the NewPing library. Even at the maximum sensor distance of
// 500cm, distance measurements can be done 20 times a second! If you set the maximum distance to 200cm
// as we have in this example sketch, even faster pings can be achieved. I suggest waiting at least 37
// milliseconds between pings to avoid previous ping echo issues, that translates to a maximum ping rate
// of around 27 times per second. Much better than the sometimes 1 ping a second with other libraries.
//

#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() {
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}

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.
Serial.print("Ping: ");
int cm = sonar.ping_cm(); // Send out the ping, get the results in centimeters.
Serial.print(cm); // Print the result (0 = outside the set distance range, no ping echo)
Serial.println("cm");
}
}
and the output coming is..
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
and continue....
i dont know why,..the sensor is just giving this output
plzz help


Try connecting it to pins 5 and 6 instead of 12 and 13.  Also, is there a clear shot in front of your sensors?  No wires or stuff in the way?  Sensor at the edge of your breadboard?  A user sent me a sensor that experienced the same problem on his Arduino, but on mine it works just fine.  So, I'm starting to think it's how it's being wired or what the environment is.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 09, 2012, 05:18 am

I'm still amazed you're volunteering to do this :) That's dedication!


Can't get your sensor to fail.  Works perfect no matter what I try (works better than my 3 semi-working sensors).  See my private message to start from the begining as we must be missing something basic here.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 09, 2012, 07:41 pm
I don't mind posting this in public, since it may benefit others, but I was accidentally using a Duemilenove (2009) board instead of an Uno R3  :smiley-red:

With the 2009 board, the sensor will send a ping, and status output goes to the serial port, but the distance reported is always 0cm.  Swapping out the board for an Uno R3 makes it all work with NewPing, and the 2009 board works fine with the code I linked to.  I assume that it's something about how NewPing compiles for the 2009's architecture.

I don't know *why* the 2009 board would have this issue, but at least this explains why my HC-SR04 *appeared* to be acting strangely.

To sum up:

2009 + NewPing + HC-SR04 = 0cm always
2009 + NewPing + HY-SRF05 = 0cm always
2009 + primitive code + HC-SR04 = works
2009 + primitive code + HY-SRF05 = works
UnoR3 + NewPing + HC-SR04 = works
UnoR3 + NewPing + HY-SRF05 = works
UnoR3 + primitive code + HC-SR04 = works
UnoR3 + primitive code + HY-SRF05 = works
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 09, 2012, 10:01 pm

I don't mind posting this in public, since it may benefit others, but I was accidentally using a Duemilenove (2009) board instead of an Uno R3  :smiley-red:

With the 2009 board, the sensor will send a ping, and status output goes to the serial port, but the distance reported is always 0cm.  Swapping out the board for an Uno R3 makes it all work with NewPing, and the 2009 board works fine with the code I linked to.  I assume that it's something about how NewPing compiles for the 2009's architecture.

I don't know *why* the 2009 board would have this issue, but at least this explains why my HC-SR04 *appeared* to be acting strangely.

To sum up:

2009 + NewPing + HC-SR04 = 0cm always
2009 + NewPing + HY-SRF05 = 0cm always
2009 + primitive code + HC-SR04 = works
2009 + primitive code + HY-SRF05 = works
UnoR3 + NewPing + HC-SR04 = works
UnoR3 + NewPing + HY-SRF05 = works
UnoR3 + primitive code + HC-SR04 = works
UnoR3 + primitive code + HY-SRF05 = works



I guess this is good news, as before it was quite a mystery.  My guess is that the Duemilanove 2009 board is somehow different with port registers.  Since NewPing uses all port register access and the primitive code uses all built-in high-level pin access commands the two are quite different.  Did the Duemilanove 2009 come in both ATmega168 and ATmega328?  Which do you have?

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 09, 2012, 10:50 pm

I guess this is good news, as before it was quite a mystery.  My guess is that the Duemilanove 2009 board is somehow different with port registers.  Since NewPing uses all port register access and the primitive code uses all built-in high-level pin access commands the two are quite different.  Did the Duemilanove 2009 come in both ATmega168 and ATmega328?  Which do you have?


Reading the chip silkscreening itself indicates that it's an ATmega328, which is consistent with the behavior in the IDE.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 10, 2012, 02:45 pm


I guess this is good news, as before it was quite a mystery.  My guess is that the Duemilanove 2009 board is somehow different with port registers.  Since NewPing uses all port register access and the primitive code uses all built-in high-level pin access commands the two are quite different.  Did the Duemilanove 2009 come in both ATmega168 and ATmega328?  Which do you have?


Reading the chip silkscreening itself indicates that it's an ATmega328, which is consistent with the behavior in the IDE.


So, the exact same processor as the Uno, darn...  I'm thinking that I'll create a couple different test libraries if you're willing to try each.  Probably one that replaces the ping echo detection with pulseIn to isolate the problem, then a few variations that do it a little differently.

Let me know if you're willing to do this, should be really quick and simple.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 10, 2012, 03:02 pm

So, the exact same processor as the Uno, darn...  I'm thinking that I'll create a couple different test libraries if you're willing to try each.  Probably one that replaces the ping echo detection with pulseIn to isolate the problem, then a few variations that do it a little differently.

Let me know if you're willing to do this, should be really quick and simple.

Even if it's not quick and simple, I'd be happy to help.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: piratadelestrecho on Jul 10, 2012, 06:42 pm
Hello Teckel.

First of all thanks a mil for your library I think is a lot of job and you are really kind sharing it with us.

I'm new to arduino and I have recently acquired a HC-SR04 sensor and I have donwloaded and installed your library for a test that I'm doing.

This is the little sketch that I'm running and I don't know if it's because I did something wrong but from time to time the sensor returns a 0 value.

Code: [Select]

#include <NewPing.h>

#define TRIGGER_PIN  7  
#define ECHO_PIN     6  
#define MAX_DISTANCE 200

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
int Range=200;
boolean Alarm=false;
int Counter = 1;
void setup() {
 Serial.begin(9600);
}

void loop() {
 
 Range = sonar.ping_cm();

delay(20);
 
 if (Range < 10) {

   Alarm = true;  
   Counter = 1;    
 }
 else if (Counter == 11) {
   Alarm = false;          
   Counter = 1;
 }
 
 if (Alarm)
   AlarmOn();
 
}

void AlarmOn(){
Serial.print("Intruso en:");  
Serial.println(Range);
Serial.print("Valor del contador:");  
Serial.println(Counter);  
 Counter++;
 
}


looking at the serial output I see that from time to time the sensor gets a 0 value and I don't know if it's a problem with my sketch or with the sensor itself...

Quote
Valor del contador:8
Intruso en:40
Valor del contador:9
Intruso en:40
Valor del contador:10
Intruso en loop:0
Intruso en:0
Valor del contador:1
Intruso en:39
Valor del contador:2
Intruso en:39
Valor del contador:3



I hope you can help thanks ;)
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 10, 2012, 07:04 pm

from time to time the sensor gets a 0 value


This seems to be an issue inherent to this family of sensors. I have worked with two HC-SR04s and one HY-SRF05, and each of them sometimes throws anomalous results. I have applied a "digital filter" to compensate for this behavior. Basically, wait for N similar results in a row before trusting the value. The sensors do lie occasionally, and your code should compensate for that.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: piratadelestrecho on Jul 10, 2012, 07:14 pm
Thanks for the reply @Human, I was thinking to use one of this as an alarm sensor for intruders but apparently these sensors doesnt seem very trustful :)

Regards,
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 10, 2012, 07:22 pm

Thanks for the reply @Human, I was thinking to use one of this as an alarm sensor for intruders but apparently these sensors doesnt seem very trustful :)

You may still be able to do this, depending on the distance to your target.  Specs for these sensors claim a 400cm range, but it doesn't seem that anyone is getting that. 100cm seems to be the max usable range.

In my case, my digital filter works very reliably.  You need to find the settings that work best for your specific sensor, but in my current build, I poll every 500ms and I believe in-range values if there are 2 in a row, and I believe out-of-range values if there are 7 in a row.  If your application doesn't require *immediate* response, then you could go this route.

Also, try not to use 0cm as the trigger for anything, since that's also considered out of range. (If you look at the sensor and see the emitter and receiver, it makes sense why you can't *actually* measure 0cm with it, so 0cm is never going to be a real distance.)
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 10, 2012, 08:57 pm

Thanks for the reply @Human, I was thinking to use one of this as an alarm sensor for intruders but apparently these sensors doesnt seem very trustful :)

Regards,


First, do you know that the NewPing library returns a value of "0" (all clear) when it doesn't detect anything?  So, a zero means that there's nothing within the range you set (in your sketch that would be 200cm).  It doesn't appear that your sketch is considering this.  Therefore, maybe your alarm if statement should be:

Code: [Select]

if (Range > 0 && Range < 10) {


Secondly, a delay of only 20 milliseconds is too short, you could get an echo from a previous ping.  Try changing your delay to 50 and see if that helps.  You probably shouldn't ping faster than once every 29ms.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: piratadelestrecho on Jul 11, 2012, 11:12 am


Thanks for the reply @Human, I was thinking to use one of this as an alarm sensor for intruders but apparently these sensors doesnt seem very trustful :)

Regards,


First, do you know that the NewPing library returns a value of "0" (all clear) when it doesn't detect anything?  So, a zero means that there's nothing within the range you set (in your sketch that would be 200cm).  It doesn't appear that your sketch is considering this.  Therefore, maybe your alarm if statement should be:

Code: [Select]

if (Range > 0 && Range < 10) {


Secondly, a delay of only 20 milliseconds is too short, you could get an echo from a previous ping.  Try changing your delay to 50 and see if that helps.  You probably shouldn't ping faster than once every 29ms.

Tim


Thank you @teckel after ignoring the 0 values, it's working perfectly!
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 11, 2012, 05:27 pm


So, the exact same processor as the Uno, darn...  I'm thinking that I'll create a couple different test libraries if you're willing to try each.  Probably one that replaces the ping echo detection with pulseIn to isolate the problem, then a few variations that do it a little differently.

Let me know if you're willing to do this, should be really quick and simple.

Even if it's not quick and simple, I'd be happy to help.


As I can't attach files to private messages, I'm going to post test libraries to this thread.  Everyone keep in mind that the official release library is always downloaded from the Google Project Hosting site, not this forum.  The attached library is not an enhanced version, it actually is removing features for testing purposes only.

First off, here's the short and sweet sketch we'll be using for the tests:

Code: [Select]
#include <NewPing.h>
#define trigPin 12
#define echoPin 11
NewPing sonar(trigPin, echoPin);

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

void loop() {
  Serial.print(sonar.ping());
  Serial.println(" uS");
  delay(100);
}


Find the attached "NewPingTestA.zip" library and replace the existing NewPing.* files in your libraries/NewPing folder.  The only thing that Test A does is replace the echo measuring with the default pulseIn command.  Because you stated you can hear the sensor firing, we're going to first assume that the trigger is happening correctly and the problem is with measuring the echo.  This first test should isolate the problem where we can then focus in on one area.

Let me know what happens.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 12, 2012, 06:29 pm

Find the attached "NewPingTestA.zip" library and replace the existing NewPing.* files in your libraries/NewPing folder.  The only thing that Test A does is replace the echo measuring with the default pulseIn command.  Because you stated you can hear the sensor firing, we're going to first assume that the trigger is happening correctly and the problem is with measuring the echo.  This first test should isolate the problem where we can then focus in on one area.

Let me know what happens.

I still hear a bunch of ticks, and I mostly get "0 uS" output over and over again. Now and then, nonzero values appear:

Code: [Select]

7494 uS
...
41944 uS
...
8251 uS
...
26104 uS


I haven't found a pattern yet that can make it produce nonzero output.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 12, 2012, 06:30 pm

Thank you @teckel after ignoring the 0 values, it's working perfectly!


This may not be sufficient. I've seen valid, in-range values (nonzero) reported by the HC-SR04 when nothing was in range. You could get false positives if all you do is ignore 0cm distances.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 12, 2012, 07:51 pm


Find the attached "NewPingTestA.zip" library and replace the existing NewPing.* files in your libraries/NewPing folder.  The only thing that Test A does is replace the echo measuring with the default pulseIn command.  Because you stated you can hear the sensor firing, we're going to first assume that the trigger is happening correctly and the problem is with measuring the echo.  This first test should isolate the problem where we can then focus in on one area.

Let me know what happens.

I still hear a bunch of ticks, and I mostly get "0 uS" output over and over again. Now and then, nonzero values appear:

Code: [Select]

7494 uS
...
41944 uS
...
8251 uS
...
26104 uS


I haven't found a pattern yet that can make it produce nonzero output.


Interesting...  Find the attached TestB - TestE libraries and test with the same sketch.  Each of these make slight changes and all work with the Uno.  Let me know if you start getting correct results (objects several inches from the sensor should give results in the hundreds).  It's still possible that none of these work for you, and if so that REALLY limits what the issue is, and I have a TestF library already ready to go.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: Human on Jul 12, 2012, 08:42 pm

Interesting...  Find the attached TestB - TestE libraries and test with the same sketch.  Each of these make slight changes and all work with the Uno.  Let me know if you start getting correct results (objects several inches from the sensor should give results in the hundreds).  It's still possible that none of these work for you, and if so that REALLY limits what the issue is, and I have a TestF library already ready to go.

A rebuild with each version (exit Arduino IDE; unzip a test version of NewPing inside ~/sketchbook/libraries/NewPing/; run IDE; load test sketch; upload to Duemilanove; open serial monitor) still outputs 0 uS, regardless of whether or not something is close to the sensor.  I can run each version for more time to see if I get any nonzero times, but I thought I'd report these results sooner rather than later.

I'm pretty sure my steps will explicitly re-build the NewPing library each time, but maybe I need to touch the sources, too.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05 and SRF06 sensors - v1.3
Post by: teckel on Jul 12, 2012, 10:16 pm


Interesting...  Find the attached TestB - TestE libraries and test with the same sketch.  Each of these make slight changes and all work with the Uno.  Let me know if you start getting correct results (objects several inches from the sensor should give results in the hundreds).  It's still possible that none of these work for you, and if so that REALLY limits what the issue is, and I have a TestF library already ready to go.

A rebuild with each version (exit Arduino IDE; unzip a test version of NewPing inside ~/sketchbook/libraries/NewPing/; run IDE; load test sketch; upload to Duemilanove; open serial monitor) still outputs 0 uS, regardless of whether or not something is close to the sensor.  I can run each version for more time to see if I get any nonzero times, but I thought I'd report these results sooner rather than later.

I'm pretty sure my steps will explicitly re-build the NewPing library each time, but maybe I need to touch the sources, too.


You should see the compiled size change slightly with each test library.  That's a good indicator that it's using a different library.

See the attached TestF library also.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05, SRF06, DYP-ME007 sensors - v1.3
Post by: Human on Jul 12, 2012, 10:20 pm
The test run I did earlier today isn't valid because I didn't notice the pin changes between the last test sketch and this one. (echo pin changed from 13 to 11).  After making that change, I am seeing distances being reported in the test library versions that I tried.  I wonder if there's a problem using pin 13 because it's also for the built-in LED.

I have to stop for today, but I tried NewPing 1.3 with this configuration, and I'm seeing distances there, too. I need to make sure I can consistently get results, but in the meantime, I'll investigate and see if I can try to make it fail again.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05, SRF06, DYP-ME007 sensors - v1.3
Post by: Human on Jul 13, 2012, 05:23 pm
I think I have good news, but it's not what either of us expected.

The "0cm" problem with the Duemilanove seems to be because of pin 13. The Duemilanove can't use pin 13 as the echoPin. It works fine on the Uno R3, but the Duemilanove doesn't like it. Changing it from pin 13 to pin 11 (and probably any other appropriate pin) makes NewPing work on the Duemilanove back to v1.3 and with the test versions you sent (at least the ones I re-tested).

I believe the previous example sketch version used pin 13, and you've changed it to be pin 11. If I had to guess, I'd say that the "0cm" bug was people on a Duemilanove (or similar) board using the example sketch and the example pins.

What do you think?
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05, SRF06, DYP-ME007 sensors - v1.3
Post by: Human on Jul 13, 2012, 05:56 pm
Assuming that pin 13 really is the reason why the Duemilanove wasn't working with NewPing, I wanted to work on a contribution to the project. Everyone's experiences with the HC-SR* family of sensors is that they're *mostly* reliable, but they occasionally throw out a false positive or false negative. I've put digital filters in my code so that I don't trust readings until they remain consistent for a window of time or number of pings. It occurs to me that this would be of general utility, as an optional way of using NewPing objects.

Some ideas of how I'd do this:


I think I'd start with #1 and see how it's received.

Would you like me to have a go at coding this up? Would you prefer that I subclass NewPing or extend NewPing with additional methods that enable/configure the digital filter option? My intent is to not change the existing API so as not to break any legacy code, and I think either approach could facilitate that.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05, SRF06, DYP-ME007 sensors - v1.3
Post by: Human on Jul 13, 2012, 10:10 pm
(I couldn't decide if I should post a new topic for this.  It's only of value to people who use NewPing with the HC-SR04 / SRF05 family of sensors.)

I have a pre-alpha, proof of concept class called ConsensusDistance that takes a pointer to a NewPing object and acts as a wrapper for it, returning distance values that are likely to be trustworthy and not anomalous. Currently, you can define how long of a "streak" you choose to trust for in-range and out-of-range readings, in milliseconds. If the sensor reads a streak of in-range values for the appropriate time, it returns the last distance read. Similarly, if the sensor reads a streak of out-of-range values (0), it returns a 0. There's also a setting for tolerance of distance between streaks. (A sufficiently recent streak of in-range values means that reading a single new in-range value is vetted by the previous streak.)

Is anyone interested in trying it out?

Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05, SRF06, DYP-ME007 sensors - v1.3
Post by: teckel on Jul 14, 2012, 12:43 am

Assuming that pin 13 really is the reason why the Duemilanove wasn't working with NewPing,


Pin 13 was my first guess as to the cause of the problem as there's an LED attached to it.  I've been suggesting to people to try different pin assignments and changed the default sketch to use pin 12 and 11 for a few weeks now.

With that said, I didn't ask you specifically not to use pin 13 for two reasons.  First, pin 13 works fine on the Uno and we both assumed you were using the Uno at the begining.  Secondly, the sketch you linked to at http://trollmaker.com/article3/arduino-and-hc-sr04-ultrasonic-sensor also uses pins 12 and 13.  So, to totally close this case, were you using the exact trollmaker sketch including using pins 12 and 13 or did you use that sketch but with different pins?  The TestF library is basically exactly the same as the trollmaker sketch.  If the Duemilanove really can't use pin 13 as a input, it shouldn't be able to with either the NewPing library or the trollmaker sketch (as it uses pin 13 for input).


I wanted to work on a contribution to the project. Everyone's experiences with the HC-SR* family of sensors is that they're *mostly* reliable, but they occasionally throw out a false positive or false negative. I've put digital filters in my code so that I don't trust readings until they remain consistent for a window of time or number of pings. It occurs to me that this would be of general utility, as an optional way of using NewPing objects.

Some ideas of how I'd do this:

  • 1) Sliding scale between responsive and trustworthy: Max responsiveness would provide no filter. Max trustworthiness would only trust a reading if there are no incompatible readings over a period of time, depending on whether we're trying to eliminate false positives or false negatives.

  • 2) "Best result in N ms": Similar to the above, except it only examines as many pings as it can in an N ms window. Should ensure that a filtered ping comes through in N ms, +/- some inherent latency

  • 3) Parameter-level tweaking: Open up all the configuration options to advanced users. They could specify a time-based filter or a filter that waits for N compatible pings in a row before believing the results.



I think I'd start with #1 and see how it's received.

Would you like me to have a go at coding this up? Would you prefer that I subclass NewPing or extend NewPing with additional methods that enable/configure the digital filter option? My intent is to not change the existing API so as not to break any legacy code, and I think either approach could facilitate that.


I don't ever remember seeing false positives or false negatives.  For example, if I put an object a foot away from the sensor it will show a distance every time.  It may fluctuate a bit as far as the distance, but will never give a 0 reading.  Likewise, if I set the maximum distance at 200cm and have it ping out at a wall that's 15 feet away, it will always get a 0 reading.  Some, have incorrectly interpreted this as incorrect.  But, this is the correctly designed behavior.  You wouldn't want the sensor to report back 200cm when there was something 400cm away as you've set the sensor to only listen for objects 200cm away or closer.  A reading of 200cm would tell you that something is 200cm away, when there is not.  Any object beyond the specified maximum distance is returned as 0, which means "all clear".  It's slightly different with the timer interrupt method as we don't create an event unless there's something in-range.

I used the below sketch with your HC-SR04 sensor.  It does VERY fast pings and displays a "." if it gets a ping within 200cm or an "0" if it gets no ping (zero).  It displays it in 80 columns so a lot of data can quickly be looked after the test is complete.  Each line ends with the ping microseconds for the final ping (kind of a test to make sure you're understanding what it's showing).

Code: [Select]
#include <NewPing.h>
#define trigPin 12
#define echoPin 11
NewPing sonar(trigPin, echoPin, 200);
byte i = 0;

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

void loop() {
  unsigned int us = sonar.ping();
  if (us==0) {
    Serial.print("0");
  } else {
    Serial.print(".");
  }
  i++;
  if (i==80) {
    Serial.print(" ");
    Serial.println(us);
    i=0;
  }
  delay(10);
}


I ran it for an hour pointing in the general area of my coffee cup and monitor sitting on my desk about 18 inches away and I got all periods, not a single "0".  A ping every 10ms for an hour is around 360,000 pings.  For the next test I turned the sensor around and pointed it towards a wall that was about 10 feet away.  I started the test and let it run for another hour and got nothing but zeros with no periods.

So, you may want to try the above sketch and a similar test before we try to filter false positives or false negatives that I can't even duplicate.  What I could see as useful is averaging.  Either a simple multi-sample average or a more complex standard deviation type calculation.  But, I question if this type of calculation is really outside the scope of an ultrasonic library as one could simply take the ping results and feed them to a standard deviation library to do the calculation.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: teckel on Jul 14, 2012, 06:46 am
NewPing v1.4 released, here's what's new:

You can now interface with all but the SRF06 sensor using only one Arduino pin. Added support for the Parallax PING)))™ sensor. You can also interface with the SRF06 using one pin if you install a 0.1uf capacitor on the trigger and echo pins of the sensor then tie the trigger pin to the Arduino pin (doesn't work with Teensy). To use the same Arduino pin for trigger and echo, specify the same pin for both values. Various bug fixes.

Download NewPing v1.4 (http://code.google.com/p/arduino-new-ping/downloads/list)

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05, SRF06, DYP-ME007 sensors - v1.3
Post by: Human on Jul 16, 2012, 06:28 pm

Pin 13 was my first guess as to the cause of the problem as there's an LED attached to it.  I've been suggesting to people to try different pin assignments and changed the default sketch to use pin 12 and 11 for a few weeks now.


Ok. I didn't come across that. I see that you did switch your sketch example at some point to use pin 12, but I'm sorry if I missed a general message about using different pins. In my case, because the "minimal pair" test was with NewPing vs without NewPing, NewPing itself appeared to be the issue, not the pin allocation.

Quote from: teckel

With that said, I didn't ask you specifically not to use pin 13 for two reasons.  First, pin 13 works fine on the Uno and we both assumed you were using the Uno at the begining.  Secondly, the sketch you linked to at http://trollmaker.com/article3/arduino-and-hc-sr04-ultrasonic-sensor also uses pins 12 and 13.  So, to totally close this case, were you using the exact trollmaker sketch including using pins 12 and 13 or did you use that sketch but with different pins?


I used pins 12 and 13 with both NewPing and the linked sketch. On the Duemilanove, it worked unless I used NewPing. On the Uno R3, it worked in both cases. If I switch from pin 13 to pin 11, the Duemilanove works with NewPing.

Quote from: teckel

The TestF library is basically exactly the same as the trollmaker sketch.  If the Duemilanove really can't use pin 13 as a input, it shouldn't be able to with either the NewPing library or the trollmaker sketch (as it uses pin 13 for input).


I didn't try that one at the time, since the pin switch resolved the problem I was having, but I just re-did the baseline tests now using the test sketch you sent me a couple of days ago to report timings.

Linked sketch with pins 12 and 13, Duemilanove = works
"TestF" NewPing library with pins 12 and 13, Duemilanove = works
v1.4 NewPing library with pins 12 and 13, Duemilanove = 0cm, 0uS

Quote from: teckel

I don't ever remember seeing false positives or false negatives.  For example, if I put an object a foot away from the sensor it will show a distance every time.  It may fluctuate a bit as far as the distance, but will never give a 0 reading.  Likewise, if I set the maximum distance at 200cm and have it ping out at a wall that's 15 feet away, it will always get a 0 reading.  Some, have incorrectly interpreted this as incorrect.  But, this is the correctly designed behavior.  You wouldn't want the sensor to report back 200cm when there was something 400cm away as you've set the sensor to only listen for objects 200cm away or closer.  A reading of 200cm would tell you that something is 200cm away, when there is not.  Any object beyond the specified maximum distance is returned as 0, which means "all clear".  It's slightly different with the timer interrupt method as we don't create an event unless there's something in-range.


I understand that 0cm is the return value for "out of range." As I explained to someone else in this thread, the sensor couldn't actually hear a ping from an object 0cm away, because it would either be blocking the emitter or the receiver, so 0cm makes perfect sense as "out of range."

At least one other person posted output from a run where he was getting values in the ~50cm range, with a 0cm value appearing anomalously. This mirrors the false negatives I've seen. The false positives are rarer, but they do happen, at least to me.

Even if your sensor/board/sketch/pin combination does not produce false positives or negatives, a digital filter is useful beyond that. If the *only* thing you want to do is leap to action as soon as the sensor state changes from out of range to in range, or from in range to out of range, that's one use case. Another use case is acting upon a "steady" state of some sort. In my case, aiming the distance sensor at my head while I walk on a treadmill, I don't *want* the sensor to leap to action as soon as it can't see my head. I may be leaning over to pick something up for a second, and I don't want it to conclude that I'm not walking anymore and shut the treadmill off.

Quote from: teckel

I used the below sketch with your HC-SR04 sensor.  It does VERY fast pings and displays a "." if it gets a ping within 200cm or an "0" if it gets no ping (zero).  It displays it in 80 columns so a lot of data can quickly be looked after the test is complete.  Each line ends with the ping microseconds for the final ping (kind of a test to make sure you're understanding what it's showing).


I'll give this a shot and report back. I'll try both "easy" objects like fixed-position objects with simple geometry and tricky objects like my moving head (about 60cm away from the sensor).
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05, SRF06, DYP-ME007 sensors - v1.3
Post by: Human on Jul 16, 2012, 07:11 pm

So, you may want to try the above sketch and a similar test before we try to filter false positives or false negatives that I can't even duplicate.

Preliminary results, tested against NewPing v1.4

Uno R3, pins 12&13 : SRF05 sensor. Other hardware (LEDs, servos, 1 5V-triggered relay) attached but not activated/powered. Tons of false negatives (0 appearing when something is in range). I tried increasing the delay to 50, and while it did help a little, it didn't resolve the false negatives.
Duemilanove, pins 12&11 : SR04 sensor. No other hardware attached. Tons of false negatives (0 appearing when something is in range). Same behavior as above with the delay change.

Nothing I aimed the sensors at produced a consistent output of periods.

Example output from the SR04/Duemilanove test, with an unmoving object about 10cm away:
Code: [Select]

.00..00.00...00...00......00..00.....00....00.00.....00.....00.00....00.00..00.. 615
00..00.00....00..00.00.....00.00.00.00.00.00.00..........00.00..00......00.00.00 0
...00.00....00.....00..........00.00.00....00...00.....00.00...00.00.00.....00.. 611
.00...00..00.00...00...00.00.00...00...00...00.00.00..00.......00..00...00..00.0 0
0..00...00.....00....00.00.00.00.00.00.00......00....00.....00.00...00.....00.00 0
.00..00...00...00.......00.00....00.00.......00........00..00...00...........00. 607
........00......00.00.00..00............00.......00.00...00.00.............00... 611
00.......00.00.00.....00.00.00.00....00.00................00..............00.... 607
......00..........00.00..00.00....00......00.00.00..00....00.....00...00.00..... 583
........00...........00.00....00..00..00...00..00..00.00..00.......00...00.00.00 0
.......00..00.00..00..00.00.....00...00.......00.00.00.....00.00.00..00......00. 611
..00..00...00.00..00..00.00...00.......00...00....00..00........00...00....00.00 0
.00...00..........00....00..00....00..00....00..00.00..00..00.00....00.......00. 611


I haven't come across false positives so far, but they are rare in my experience and not my main concern. They're rare enough that my digital filter trusts in-range values if it gets only two of them in a row, but it's common enough that I need to handle it, or my automation could turn itself on when nobody is around.

EDIT: BTW, the object I tested was my flat extended palm. I didn't have to try anything with tricky geometry (like my head, or one of my spare human heads).

EDIT2: I am still on the 1.0 IDE. I can try building and testing from the 1.0.1 IDE to see if there's a difference.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05, SRF06, DYP-ME007 sensors - v1.3
Post by: teckel on Jul 17, 2012, 02:32 pm

Preliminary results, tested against NewPing v1.4

Uno R3, pins 12&13 : SRF05 sensor. Other hardware (LEDs, servos, 1 5V-triggered relay) attached but not activated/powered. Tons of false negatives (0 appearing when something is in range). I tried increasing the delay to 50, and while it did help a little, it didn't resolve the false negatives.
Duemilanove, pins 12&11 : SR04 sensor. No other hardware attached. Tons of false negatives (0 appearing when something is in range). Same behavior as above with the delay change.


When I do the same test, I get nothing but periods.  Maybe try it while disconnecting the other hardware to see if it's a possible noise issue.  I would still not use pin 13 for input, even on the Uno.  Not that it's causing the problem, it's just probably not a good idea.  If you're out of pins, it would be better to swap pins 12 and 13 and use 13 for the trigger and 12 for the echo.

Also, it's possible that it's giving the zeros because the ping never initiated.  While the sensor specs say it only needs a 10uS high notch to trigger a pin, maybe some sensors need a little more.  I haven't seen this, but I'm thinking it's very possible.  Try changing the delayMicroseconds in line 46 and 48 of NewPing.cpp to 1000 each.  That should give it plenty of time to initiate the ping.

Are all these zeros the same thing you get when you use a different sensor library?  As other libraries may not return zero for a failed ping, you'd probably need to do an additional command to make the out of range a zero and in range a period.

Even if the false negatives are going to happen for you in any case; If you only want to know the distance, why not just filter out the zeros and just deal with the successful pings?  If you only want to know a distance, just ping frequently and ignore all the zeros.

Finally, I've been thinking of some type of averaging method in NewPing.  My thought was to do an odd number of pings like 3, 5 or 7, throw out the high and low value, and average the rest.  Obviously, taking into consideration zero results as well.  Then, it would give that average as the result.  It would be a poor man's standard deviation, creating smaller and faster code but yielding basically the same result. This would also fix your false negative results.  I'd rather locate the source of your problem instead, as that's a LOT of false negatives considering I get none.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05, SRF06, DYP-ME007 sensors - v1.3
Post by: Human on Jul 18, 2012, 05:28 pm

When I do the same test, I get nothing but periods.  Maybe try it while disconnecting the other hardware to see if it's a possible noise issue.

I've tried it on bare-bones setups with just the Arduino and the sensor, with a protoboard between the two.

Quote from: teckel

I would still not use pin 13 for input, even on the Uno.  Not that it's causing the problem, it's just probably not a good idea.  If you're out of pins, it would be better to swap pins 12 and 13 and use 13 for the trigger and 12 for the echo.

I'm using pins 12 and 7 currently on an Uno, and I'm still getting false negatives.

Quote from: teckel

Also, it's possible that it's giving the zeros because the ping never initiated.

Here's what I hear: I hear clicking occurring very rapidly as the test runs. The click pattern mirrors the '0' and '.' pattern, in that it speeds up when I get '.'s and slows down when I get '0's. If I had to guess, I'd say that there is some timeout involved, but I don't know whether it's not sending pings due to a timeout, or giving up on receiving them due to a timeout.

Quote from: teckel

While the sensor specs say it only needs a 10uS high notch to trigger a pin, maybe some sensors need a little more.  I haven't seen this, but I'm thinking it's very possible.  Try changing the delayMicroseconds in line 46 and 48 of NewPing.cpp to 1000 each.  That should give it plenty of time to initiate the ping.

That produced false positives far more often. The actual positives (in-range values while something was actually in range) became very rare.

Quote from: teckel

Are all these zeros the same thing you get when you use a different sensor library?  As other libraries may not return zero for a failed ping, you'd probably need to do an additional command to make the out of range a zero and in range a period.

I'll re-test with that other implementation, but I began to code for false positives and negatives based on my experience with it, not NewPing. Still, I'll see if I can get a comparison going.

I have another Uno arriving today, which I'll test just to see if my previous Uno isn't acting strangely, although my Duemilanove results paralleled what I got with the Uno, as long as pin 13 wasn't involved.

Quote from: teckel

Even if the false negatives are going to happen for you in any case; If you only want to know the distance, why not just filter out the zeros and just deal with the successful pings?  If you only want to know a distance, just ping frequently and ignore all the zeros.

The zeros are meaningful to me, too. I need to know if there's something in range or nothing in range and act accordingly. My specific application is a sensor aimed at where my head is if I'm on my treadmill desk. When I'm actually in walking position (in range, less than a specific distance), I turn a bunch of things on.  When I'm not in walking position (either in range, over a specific distance, or out of range), I turn a bunch of stuff off.

Quote from: teckel

Finally, I've been thinking of some type of averaging method in NewPing.  My thought was to do an odd number of pings like 3, 5 or 7, throw out the high and low value, and average the rest.  Obviously, taking into consideration zero results as well.  Then, it would give that average as the result.  It would be a poor man's standard deviation, creating smaller and faster code but yielding basically the same result. This would also fix your false negative results.  I'd rather locate the source of your problem instead, as that's a LOT of false negatives considering I get none.

That could be useful. I was thinking of doing something like that with a digital filter. I'm not sure yet which would best apply to the use case I was thinking of.

If you had an application that did something different at, say, 10cm vs 9cm, readings that oscillate between 9cm and 10cm would cause chaos. A digital filter that would return a consistent 9cm value or a consistent 10cm value would reduce this flailing. So, 9 10 9 9 10 10 10 10 might return 10, but 9 10 9 9 9 10 10 10 9 9 9 10 10 10 might not return yet, etc. Obviously it could be a concern if it's done in a blocking way, but in my case, 99% of the input to my logic is from the distance sensor. I do have pushbuttons, but given that the worst-case scenario of never returning from the filter is unlikely, I'd be fine with that. Your idea has the potential to do the same thing, but it wouldn't look for unbroken chains of consistent values. In the end, they may both do the same thing, though.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04, SRF05, SRF06, DYP-ME007 sensors - v1.3
Post by: Human on Jul 18, 2012, 06:31 pm

Quote from: teckel

Are all these zeros the same thing you get when you use a different sensor library?  As other libraries may not return zero for a failed ping, you'd probably need to do an additional command to make the out of range a zero and in range a period.

I'll re-test with that other implementation, but I began to code for false positives and negatives based on my experience with it, not NewPing. Still, I'll see if I can get a comparison going.


I switched to pins 7 and 8 for these tests.  Here are my two test sketch baselines:

Code: [Select]

#include <NewPing.h>
#define trigPin 7
#define echoPin 8
NewPing sonar(trigPin, echoPin, 200);
byte i = 0;

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

void loop() {
 unsigned int us = sonar.ping();
 if (us==0) {
   Serial.print("0");
 } else {
   Serial.print(".");
 }
 i++;
 if (i==80) {
   Serial.print(" ");
   Serial.println(us);
   i=0;
 }
 delay(10);
}


And the trollmaker sketch, modified to do the same test:

Code: [Select]

#define trigPin 7
#define echoPin 8

byte i = 0;

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

void loop() {
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(1000);
 digitalWrite(trigPin, LOW);
 
 unsigned int us = pulseIn(echoPin, HIGH);
 if (us==0) {
   Serial.print("0");
 } else {
   Serial.print(".");
 }
 i++;
 if (i==80) {
   Serial.print(" ");
   Serial.println(us);
   i=0;
 }
 delay(10);
}


I reverted to the v1.4 baseline for the NewPing tests.

For my flat surface tests, I varied distance (9cm, 22cm, and 40cm) and the ms delay in loop(). To summarize, a 10ms delay was insufficient for any distance and library. 20ms worked flawlessly in NewPing for distances 22cm and above but not 9cm. 20ms worked flawlessly for trollmaker at all distances tested. 40ms worked flawlessly for all distances and libraries tested.

EDIT: I tested flat objects at 50cm, too, and the results mirrored the 40cm distance tests.

Raw data:

Test Suite 1: Flat object 9cm away from emitter rim. Varied ms delay in loop().

10ms: I get false negatives in both sketches (~30% - 50%). The trollmaker sketch has fewer, but it's also slower.

20ms: very few false negatives (maybe 5%) in NewPing. There were 0 false negatives in the trollmaker sketch during the time I ran it.

40ms: no false negatives in NewPing during the time I ran it. There were 0 false negatives in the trollmaker sketch during the time I ran it.


Test Suite 2: Flat object 22cm away from emitter rim. Varied ms delay in loop().

10ms: I get false negatives in both sketches (~30% - 50%). The trollmaker sketch has fewer, but it's also slower.

20ms: no false negatives in NewPing during the time I ran it. There was 1 false negative in the trollmaker sketch during the time I ran it (at start; possible algorithm badness).

40ms: no false negatives in NewPing during the time I ran it. There was 1 false negative in the trollmaker sketch during the time I ran it (at start; possible algorithm badness).


Test Suite 3: Flat object 40cm away from emitter rim. Varied ms delay in loop().

10ms: I get false negatives in both sketches (~20% - 50%). The trollmaker sketch has many fewer, but it's also slower.

20ms: no false negatives in NewPing during the time I ran it. There was 1 false negative in the trollmaker sketch during the time I ran it (at start; possible algorithm badness).

40ms: no false negatives in NewPing during the time I ran it. There was 1 false negative in the trollmaker sketch during the time I ran it (at start; possible algorithm badness).


Next, I will test irregular objects at rest and at motion. (I do wish I had a spare human head.)
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: Human on Jul 18, 2012, 06:52 pm
Test with nonmoving human head stand-in.

9cm:
10ms, 20ms, 40ms -> same as flat surface results

22cm:
10ms, 20ms, 40ms -> same as flat surface results

40cm:
10ms, 20ms, 40ms -> same as flat surface results

50cm:
10ms, 20ms, 40ms -> same as flat surface results
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: Human on Jul 18, 2012, 08:02 pm
My testing indicates that a 10ms delay was always too short and a 20ms delay was too short for close objects (which is counter-intuitive to me) - at least for my SR04 sensor.

Increasing the delays in my larger code base reduced but did not eliminate my false negatives.  Testing with my actual head while as stationary as I could make it produced lots of false negatives, depending on what it bounced off.  In some cases, there were no false negatives.  Moving my head while not walking was problematic, too.  I suspect I will get more false readings while walking because this adds sensor vibration.

To sum up: Minimum delay between pings for my hardware was 40ms. I have some inherent false negatives due to the target shape, target motion, and sensor vibration in my application. I'm going to keep using my digital filter, unless I've missed some other solution. I'd be happy to share my filter with others if it's of general use.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: teckel on Jul 18, 2012, 08:55 pm

My testing indicates that a 10ms delay was always too short and a 20ms delay was too short for close objects (which is counter-intuitive to me) - at least for my SR04 sensor.

Increasing the delays in my larger code base reduced but did not eliminate my false negatives.  Testing with my actual head while as stationary as I could make it produced lots of false negatives, depending on what it bounced off.  In some cases, there were no false negatives.  Moving my head while not walking was problematic, too.  I suspect I will get more false readings while walking because this adds sensor vibration.

To sum up: Minimum delay between pings for my hardware was 40ms. I have some inherent false negatives due to the target shape, target motion, and sensor vibration in my application. I'm going to keep using my digital filter, unless I've missed some other solution. I'd be happy to share my filter with others if it's of general use.


Okay, so really the only problem is the delay between pings.  I'm not suprised that a 10ms delay causes a lot of problems.  I'm actually kind of suprised that I don't have a problem with a 10ms delay as that's really too quick (sensor is getting an echo from a previous ping).  It could be the environment I'm in absorbs more sound or maybe my ping emitters are not as strong as yours.  It also makes sense that a 20ms delay causes some problems, but not as many.

Because most of these ultrasonic sensors are designed to work up to 500cm away, that distance takes sound around 29ms to travel.  So, 29ms between pings is the fastest you should really ping a sensor.  If you ping faster, you risk getting an echo from a previous ping, causing the current ping to give a zero reading.

If we follow the baseline guide I've set for NewPing, and not delay less than 29ms between pings, my guess is that you will get basically no false negatives.  The reason that 20ms gave better results with the trollmaker sketch with close objects with a 20ms delay is that the NewPing library has a timeout value for the initiation of the echo sensor while trollmaker using pulseIn can wait up to a full second.  That timeout value in NewPing is the MAX_SENSOR_DELAY which is set to 18000us (18ms).  This is plenty long, and it should never really be an issue as long as you keep the pings 29ms apart.

Set the delay to 29ms in the sketch and see if you get any false negatives.  I would suspect you get basically none.

So the question is, were you all along trying to do pings too quickly which is why you concluded that the SR04 sensor gave many false negative readings?  All of my sample sketches show delays in the 33 to 35ms range with comments not to go quicker than 29ms.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: Human on Jul 18, 2012, 09:04 pm

Okay, so really the only problem is the delay between pings.

The only library problem, yes. (In either trollmaker or NewPing.) There is still, at least in my case, an integration problem, but NewPing and trollmaker's code are absolved of wrong-doing :)

Quote from: teckel

[...]
Set the delay to 29ms in the sketch and see if you get any false negatives.  I would suspect you get basically none.

Thanks for the explanation of the timings. I'll try 29ms to see if it works as well as 40ms did.

Quote from: teckel

So the question is, were you all along trying to do pings too quickly which is why you concluded that the SR04 sensor gave many false negative readings?  All of my sample sketches show delays in the 33 to 35ms range with comments not to go quicker than 29ms.

I've tried various delays throughout my development process, generally between 50ms and 1000ms, and none of them eliminated false negatives in my deployment environment. That's still a problem for me and why I need to apply a digital filter to the readings I get. Heads are just not ideal targets for the ultrasonic sensor, especially moving ones.

EDIT: BTW, I started at a 10ms delay because that was in your last test sketch. I don't think I tried a 10ms delay before then.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: Human on Jul 19, 2012, 08:01 pm
For me, any loop() delay >= 21ms yielded zero false negatives when testing stationary objects, between 1cm and 50cm from the sensor's emitter.

Is there any reason this should be?  Just a variation between specific hardware and the spec?  I don't mind using 39ms to be safe, but there seems to be a very harsh cutoff between the behavior at 20ms delay and the behavior at 21ms delay.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: cappyjack on Jul 24, 2012, 11:11 am
I am interested in using the new ping library but am concerned about the interrupt driven version. I am using an arduino uno, 2 parallax ping sensors mounted on servo motors (from Parallax). I want to drive each servo 180 deg to make a full 360 sweep as fast as I can. After each servo move, I want to ping a distance and use that value to play a small wav file. I put an Adafruit wav shield on my arduino and found that it uses the only 16 bit timer. The servo library from arduino uses it too. So I found another servo library that uses an 8 bit timer on the AT328 and I can play wavs and mover servos. I cannot get good pings all the time with the standard ping code.

It appears that the new ping libary uses the 16 bit timer, too. But, in the revision history, it appears that an earlier version does not. Is that correct? I would appreciate any suggestions. Thank you.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: teckel on Jul 27, 2012, 05:21 am

For me, any loop() delay >= 21ms yielded zero false negatives when testing stationary objects, between 1cm and 50cm from the sensor's emitter.

Is there any reason this should be?  Just a variation between specific hardware and the spec?  I don't mind using 39ms to be safe, but there seems to be a very harsh cutoff between the behavior at 20ms delay and the behavior at 21ms delay.


Yes, the sensor may very well timeout after at certain amount of time, and that timeout could be different for different sensor manufactures.  This is probably why it works at 1ms for me because my sensor probably resets as soon as it gets a ping echo while another model may not.

The limit I suggest using is 29ms, not 39ms.  That's based strictly on the speed of sound and the sensor range spec of 500cm.  29ms should be safe for just about every sensor because almost all have a maximum sensor distance spec of 500cm (and in reality in most cases it's less than this).  Lower than 29ms may work, but it very well may not work, or give non-reliable results (like  what you were experiencing).

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: teckel on Jul 27, 2012, 05:47 am

I am interested in using the new ping library but am concerned about the interrupt driven version. I am using an arduino uno, 2 parallax ping sensors mounted on servo motors (from Parallax). I want to drive each servo 180 deg to make a full 360 sweep as fast as I can. After each servo move, I want to ping a distance and use that value to play a small wav file. I put an Adafruit wav shield on my arduino and found that it uses the only 16 bit timer. The servo library from arduino uses it too. So I found another servo library that uses an 8 bit timer on the AT328 and I can play wavs and mover servos. I cannot get good pings all the time with the standard ping code.

It appears that the new ping libary uses the 16 bit timer, too. But, in the revision history, it appears that an earlier version does not. Is that correct? I would appreciate any suggestions. Thank you.


First, you don't need to use the timer interrupts at all with NewPing.  The default method doesn't use any of the timers and works just fine.  Via polling, you can still do very effective timed events without using timer interrupts at all.

If you're sketch is event-driven and you're trying to use a timer for the ping, NewPing offers an *option* of using timer 2, which is an 8bit timer.  It uses timer 2 because timer 1 is used with the standard servo library.

If you're not creating a multi-tasking event-driven sketch, you probably shouldn't be using NewPing's timer event method.  So, the question should really be, why do you think you need to use the timer interrupt method of NewPing?  Do you really have a need for it?  Is the rest of your sketch event-driven where it's justified and would be beneficial?

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: vcberta on Jul 27, 2012, 01:06 pm
Hi.

I tried to modify the NewPing15Sensors but i still get the same problem of

0=123cm 1=2cm 2=0cm
0=117cm 1=3cm 2=0cm
0=126cm 1=3cm 2=0cm
0=122cm 1=3cm 2=0cm
0=122cm 1=3cm 2=0cm
0=125cm 1=3cm 2=0cm
0=117cm 1=4cm 2=0cm


This is my code, some idea?
Code: [Select]
#include <NewPing.h>

#define SONAR_NUM     3 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 100 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 0;          // Keeps track of which sensor is active.

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

void setup() {
  Serial.begin(115200);
  pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
  for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
    pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }
  }
  // The rest of your code would go here.
}

void echoCheck() { // If ping received, set the sensor distance to array.
  if (sonar[currentSensor].check_timer())
    cm[currentSensor] = sonar[currentSensor].convert_cm(sonar[currentSensor].ping_result);
}

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
  for (uint8_t i = 0; i < SONAR_NUM; i++) {
    Serial.print(i);
    Serial.print("=");
    Serial.print(cm[i]);
    Serial.print("cm ");
  }
  Serial.println();
}


Thanks.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: teckel on Jul 27, 2012, 05:33 pm

Hi.

I tried to modify the NewPing15Sensors but i still get the same problem of

0=123cm 1=2cm 2=0cm
0=117cm 1=3cm 2=0cm
0=126cm 1=3cm 2=0cm
0=122cm 1=3cm 2=0cm
0=122cm 1=3cm 2=0cm
0=125cm 1=3cm 2=0cm
0=117cm 1=4cm 2=0cm


I assume the problem is that you're getting 0cm from the third sensor (sensor 2)?  It seems that sensor 0 and sensor 1 are giving realistic results.  Am I assuming correctly?  You don't specifically state the problem, only provide the results so one must assume what you're reporting as a problem.

If so, sensor 2 is reporting 0cm probably because you're using pin 11.  As the multi-sensor sketch uses the timer 2 interrupt, there could be issues using pins 3 and 11.  This is mentioned in the v1.3 release notes here:

Quote
New in v1.3 - Released 6/8/2012:
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 10 on Mega, and Tone library).


Also, as of v1.4 there's no need to use two Arduino pins.  Just specify the same trigger and echo pins in your sketch and wire from the Arduino pin to the trigger pin on the sensor, then from the trigger to echo pin of the sensor.  So, for 3 sensors you would only need to use 3 Arduino pins instead of 6 as you have it wired now.  Your pin assignment code would look something like this:

Code: [Select]
NewPing sonar[SONAR_NUM] = {
 NewPing(5, 5, MAX_DISTANCE),
 NewPing(8, 8, MAX_DISTANCE),
 NewPing(12, 12, MAX_DISTANCE)
};


Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: cappyjack on Jul 29, 2012, 04:03 pm
Thanks, Tim, for the reply.
      I am trying to get around short false readings from the Parallax ping sensor. I have the same thing with v 1.4 of NewPing as I do with the std. ping library. Around the middle of the servo sweep I get short readings, typically 15 cm, for a couple of servo moves. Curiously, the ping will read below 15 cm during this dead band. My space has no influence on the position of servo. I have moved it all around to see if I am getting bad readings from my environment. NewPing works fine on both sides of the dead band.  I have removed the servo from the project electrically (disconnect power and signal) and I still get low readings around the center of the sweep when I move it by hand. I have tried it on both servos and ping sensors. I have no idea how the servo position is effecting the ping sensor even when it is not moving and disconnected.
      My project is to sweep 360 deg around my sculpture pedestal with 2 servos and 2 pings. When someone comes close the wav shield plays a short file depending on distance and position. Any distance reading will trigger another wav file and if you walk the "right" way, the whole song will play. I got everything working and started to test when I discovered the short bad distances. I reduced the sketch to just the std. libraries and the short readings persist. I can manipulate them with delays and code but never get rid of them all. I hope that this description will aid you in suggesting how best to use NewPing. And ANY thoughts on the dead band of the servos would be greatly appreciated! Many Thanks!!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: cappyjack on Jul 30, 2012, 02:54 pm
Well, I found the source of the false short ping readings. I had placed the 2 sensors 5 & 10 cm away from the Arduino Uno (with wav shield) on my pedestal. Something on the board emits a directional noise that the sensors heard and misreported the distance as short. When I moved the sensors 20 cm away and put a piece of wood between them and the computer, the noise no longer spoofed the Ping sensors.  Thanks, everyone, for helping with suggestions. Tim - I am going to implement your new ping library next. I will post my results after testing.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: tehcereal on Jul 30, 2012, 02:59 pm
Hello,
First of all thank your published work.
I got my HC SR04 today and searched on the internet how to get all working. I came across your library and another source from trollmaker.com (http://trollmaker.com/article3/arduino-and-hc-sr04-ultrasonic-sensor/) (I have seen someone posted it before) It worked flawlessly. After that I wanted to try your library. I wired all the same using pins 12 and 11 but all I got in serial monitor was junk all in one row.
I used your sketch  in the example menu.
I have a UNO r3 clone and using the newest arduino IDE
I'm a beginner so please be patient  :smiley-mr-green:
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: teckel on Jul 31, 2012, 12:53 am

Well, I found the source of the false short ping readings. I had placed the 2 sensors 5 & 10 cm away from the Arduino Uno (with wav shield) on my pedestal. Something on the board emits a directional noise that the sensors heard and misreported the distance as short. When I moved the sensors 20 cm away and put a piece of wood between them and the computer, the noise no longer spoofed the Ping sensors.  Thanks, everyone, for helping with suggestions. Tim - I am going to implement your new ping library next. I will post my results after testing.


Glad to hear you got it working with the PING))) sensor.  I didn't test the library with this sensor and trusted a user who said it worked.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: teckel on Jul 31, 2012, 01:15 am

Hello,
First of all thank your published work.
I got my HC SR04 today and searched on the internet how to get all working. I came across your library and another source from trollmaker.com (http://trollmaker.com/article3/arduino-and-hc-sr04-ultrasonic-sensor/) (I have seen someone posted it before) It worked flawlessly. After that I wanted to try your library. I wired all the same using pins 12 and 11 but all I got in serial monitor was junk all in one row.
I used your sketch  in the example menu.
I have a UNO r3 clone and using the newest arduino IDE
I'm a beginner so please be patient  :smiley-mr-green:



Did you specify the correct BAUD rate as set in the sketch?  The NewPing example sketches uses 115200 while I believe the Trollmaker sketch uses 9600 BAUD.  If you don't select the correct speed as set in the sketch, you'll get garbage.  You could also set the BAUD rate in the NewPing sketch to 9600 as well, just as long as you set the same speed both in your sketch and in the serial monitor you will see the results.

Also, with NewPing you can use just one Arduino pin instead of two.  So, you can wire both the trigger and echo to Arduino pin 10, for example, which would look something like this example sketch:

http://code.google.com/p/arduino-new-ping/wiki/NewPing_Single_Pin_Sketch

Also, I would not suggest using the Trollmaker example as a basis for a sketch; There's several problems with it, including size and speed.  It's not even okay as a training example, because the HIGH notch is not to sensor specs at 1000 uS (should be 10uS).  It also doesn't insure that the trigger pin is LOW before starting the HIGH notch.  Basically, while it may work as an example, it's really not correct and you'll have problems when you try to implement it in a larger sketch.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: tehcereal on Jul 31, 2012, 08:22 pm
I tried the "one pin sketch" and it worked with the higher BAUD. It was probably the wrong BAUD fault for the garbage in the original sketch. I see what you mean for the trollmaker sketch, your seems much precise and it uses 15% less memory.
So stupid of me, not looking enough careful at the sketch.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: teckel on Aug 09, 2012, 08:13 am
I've been developing a new method in NewPing to do multiple pings, ignore pings that seem to be in error, and average the results.  I've implemented it several different ways, from a simple mean average, removing the min and max, and creating an array of ping distances with processing happening in a second pass.  To be honest, they all seem to give very similar (if not identical) results.  The exception is the simple mean average, which can give inaccurate results if the ping sample is small.

Because the other algorithms yield basically the same results, I've been focusing on using whatever algorithm results in the smallest code and uses the least amount of stack space.  I've got everything working quite well.  When using this method there's only a code penalty of around 300 bytes (only if you use the new average method, other methods create the same program size as before).

The algorithm looks at the first and second ping, if they're within 2cm it averages the two.  If the first two pings are greater than 2cm, it discards the first ping result.  It then averages the rest of the pings as long as they're within 2cm of the running average.  The only way this algorithm gives an inaccurate result is if there were two erroneous pings in a row, and these two were also the first two pings (very rare).  It's not the perfect, but seems to give almost identical results as fancy multiple pass digital noise filtering algorithms.

I'll be doing more testing and releasing it in the next several days.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: teckel on Aug 10, 2012, 07:30 am
Only a day has passed and I've gone a totally different direction with the new multiple ping (digital filter) method.  Come to find out, the algorithm I was focusing on yesterday was missing something. Once added, the code size went up over 100 bytes.  Because of this, I threw out the code and switched to a more advanced digital filtering.  The new algorithm saves the ping results in an array, insertion sorts the array, ignoring the NO_ECHOs finds the median, and finally calculates the mean from results within 4cm of the median.

It's a more effective digital filter and the code is tight.  I'm working on making it even better by trying to implement an online median algorithm which would eliminate the need to sort (although the insertion sort currently being used is also an online algorithm and *extremely* small).

Still tweaking and testing (shaved 44 bites from the compiled code while I was writing this post).

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: bilal_ahmad_21 on Aug 10, 2012, 07:53 am
my robot is working fine with just one single sonar and using that same old ping library
all i did was calibrating the time of servo movement with the time taken by sonar to take a reading
Code: [Select]
digitalWrite(trigPin, LOW);                   // Set the trigger pin to low for 2uS
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);                  // Send a 10uS high to trigger ranging

  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);                   // Send pin low again
  int distance = pulseIn(echoPin, HIGH);        // Read in times pulse
  distance= distance/58;  // Calculate distance from time of pulse
  delay(10);                            // Wait 50mS before next ranging


Here's the video of robot
http://www.youtube.com/watch?v=bsvpIkv4GbI&feature=plcp (http://www.youtube.com/watch?v=bsvpIkv4GbI&feature=plcp)
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: teckel on Aug 10, 2012, 09:17 am

my robot is working fine with just one single sonar and using that same old ping library
all i did was calibrating the time of servo movement with the time taken by sonar to take a reading
Code: [Select]
digitalWrite(trigPin, LOW);                   // Set the trigger pin to low for 2uS
 delayMicroseconds(2);
 digitalWrite(trigPin, HIGH);                  // Send a 10uS high to trigger ranging

 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);                   // Send pin low again
 int distance = pulseIn(echoPin, HIGH);        // Read in times pulse
 distance= distance/58;  // Calculate distance from time of pulse
 delay(10);                            // Wait 50mS before next ranging


I can see that your robot has problems at times which NewPing would fix.  Using the code listed will cause problems.  While you don't specifically ask for help, you must be wanting help resolving roblems I see in your video with your robot.

Switching out that code for my NewPing library will allow for faster pings and no long ping timeouts that I can see sometimes with the video of your robot.  It doesn't happen often because you have a wall around the area it's in.  But, if you didn't have that wall and it was in the wild, it would oddly pause at times.  I'm sure you've experienced this as I can see it in your video.  NewPing fixes this.

Further, you're not using event-driven programming so your robot is doing nothing when it could be doing something else (for example, multiple ping sensors or different types of sensors at the same time).  NewPing has an interrupt-driven ping method that allow you to do other things at the same time you're waiting for a ping echo.  For example, with NewPing your sketch could create a ping every 29ms while you rotate the servo.  When it received a ping echo it would trigger an interrupt that would turn your robot.  There would be no delays in your sketch so more processing could be done without resorting to slowing down the ping rate.

Hope that helps!

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: teckel on Aug 11, 2012, 08:11 am
Okay, I believe I've got the new digital filtering method down to as lean as it's going to get with all the kinks worked out.  For the coders out there, here's the method:

Code: [Select]
unsigned int NewPing::ping_ave(uint8_t it) {
int uS[it], last, median;
uint8_t i, j, cnt = 0;
unsigned long total = 0;
uS[0] = last = ping();   // Send first ping (done here to assist insertion sort).
for (i = 1; i < it; i++) {                                                    // Ping iterations.
if (last != NO_ECHO) cnt++;                                               // Array median tracking.
delay(PING_AVE_DELAY - ((last == NO_ECHO ? _maxEchoTime : last) / 1000)); // Delay between pings.
last = ping();                                                            // Send ping.
for (j = i; j > 0 && uS[j - 1] < last; j--) uS[j] = uS[j - 1];            // Insertion sort (big to small).
uS[j] = last;                                                             // Add last ping to array in correct order.
}
if (last != NO_ECHO) cnt++; // Array median tracking.
median = uS[cnt >> 1];      // Find median.
cnt = 0;                    // Reset counter.
for (i = 0; i < it; i++) {                           // Loop through results.
if (abs(median - uS[i]) < US_ROUNDTRIP_CM * 2) { // Exclude values outside +/-2cm range (digital noise).
total += uS[i];                              // Building truncated mean.
cnt++;                                       // Increment counter.
}
}
return (total / cnt); // Return the ping distance mean minus digital noise (truncated mean).
}


To actually implement it you would need to define PING_AVE_DELAY to 29 and add the method to the class (I set the iterations [it] to default to 5).  I know not everyone is adept at doing this, but this is a preview for those that are.  Also, if there's any statistical gurus out there that want to poke holes in my code, feel free (statistics is not my thing).

The method uses two passes to calculate a truncated mean with outliner pings removed (digital noise).  The first pass collects the pings, keeps track of successful pings, and sorts on-line using the very simple and fast insertion sort.  Before the second pass it then calculates the median ping (with the unsuccessful pings filtered out).

Once the median value is found, it then does another pass to calculate the truncated mean.  Outliner pings are those outside +/-2cm (these are not calculated as part of the mean).  Because insertion sort is done on-line instead of in another pass (like a typical bubble sort), even the max of 255 ping iterations can be done without any perceived slow-down (although 255 is a little excessive, 3-9 is typically plenty).  Insertion sort is *very* fast with a small quantity of values to sort.  So fast that highly complex sort algorithms like quicksort resort to insertion sort when there's only a few values to sort (like in this case).  Also, insertion sort has a very small stack footprint (only one variable) and extremely small code size (because it's so simple, 2 lines of code).  It's really the only sort to use on Arduino.

In laymen terms, the new method does a user-specified number of pings as fast as it can (29ms per ping) ignores out of range pings, sorts the ping values, gets the middle distance ping value, filters out pings outside +/-2cm of the middle distance ping, and returns the average of these pings in microseconds.

Code: [Select]
unsigned int us = sonar.ping_ave(); // Defaults to 5 iterations, returns the truncated mean in microseconds.
unsigned int us = sonar.ping_ave(3); // Do 3 iterations, returns the truncated mean in microseconds.
unsigned int cm = sonar.convert_cm(sonar.ping_ave(9)); // Do 9 iterations and get the truncated mean in cm.


A few explanations about the method specific to the programming.  First, some things may not appear as clean as they could be.    In many cases this is done to make the code smaller once compiled.  By making these changes around 100 bytes was saved on the final compiled code.  I believe this is a fair compromise with the limited memory in the ATmega.  Secondly, there are some items that may not be statistically perfect.  An example is the median when there's an even number of values.  The code only picks one median value, even if there technically should be the average of two.  This again was done to reduce compiled code size and it also doesn't make much difference as there's a lot of fuzzy logic in a truncated mean anyway.

Basically, the function could be re-worked to be more clear, logical, and maybe slightly more statistically accurate.  But, that's technically how the function started.  I tweaked it over the course of a few days to try and squeeze as many bytes as I could out of it.

With that said, if there's something wrong, a suggestion, or another performance tweak that doesn't make the compiled code larger, please let me know (that's one of the reasons I'm posting the method before it's released).

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4
Post by: teckel on Aug 11, 2012, 08:32 am
Here's also a simplified version that just finds the median.

Code: [Select]

unsigned int NewPing::ping_median(uint8_t it) {
int uS[it], last;
uint8_t j, i = 0;
uS[0] = NO_ECHO;
while (i < it) {
last = ping();           // Send ping.
if (last == NO_ECHO) {   // Out of range ping.
it--;                // Skip, don't include as part of median.
last = _maxEchoTime; // Adjust "last" variable so delay is correct length.
} else {                       // Ping in range, include as part of median.
if (i > 0)                 // Don't start sort till second ping.
for (j = i; j > 0 && uS[j - 1] < last; j--) // Insertion sort loop.
uS[j] = uS[j - 1]; // Shift ping array to correct position for sort insertion.
else j = 0;                // First ping is starting point for sort.
uS[j] = last;              // Add last ping to array in sorted position.
i++;                       // Move to next ping.
}
if (i < it -1) delay(PING_MEDIAN_DELAY - (last >> 10)); // Millisecond delay between pings.
}
return (uS[it >> 1]); // Return the ping distance median.
}


This saves 112 bytes of complied code size so it's worth considering.  I could add both a ping_median() and ping_mode() but I feel that's a little excessive.  Any statistic types out there may want to chime in on if a pure median calculation is good enough in removing digital noise.  Or, if the addition of the truncated mean with removed +/-2cm outliners is worth the 112 byte loss.  Median and truncated mean yield different cm results about 10% of the time, but which one is better or more correct?  When they return two different values there's not one value that's clearly more accurate more consistently as far as I can tell.

I'm leaning towards the above ping_median method as a digital filter.  It's 112 bytes smaller and seemingly just as effective (albeit sometimes different).

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 16, 2012, 12:19 am
NewPing v1.5 released, here's what's new:

Added ping_median() method which does a user specified number of pings (default=5) and returns the median ping in microseconds (out of range pings ignored). This is a very effective digital filter. Optimized for smaller compiled size (even smaller than sketches that don't use a library).

Download NewPing v1.5 (http://code.google.com/p/arduino-new-ping/downloads/list)

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 16, 2012, 12:29 am
By the way, I went with just the median method for digital filtering.  It's fast, the overhead is much smaller, and the results were just as effective as finding the mean of a centered sample.  Using ping_median() is just as simple as using ping() too.  There's nothing to figure out, just change ping() to ping_median() in your sketch and it will automatically do 5 pings and return the median ping.  To specify a different number of samples, just specify the number of iterations you want like this: ping_median(9).  Here's a sample sketch that uses ping_median:

Code: [Select]
#include <NewPing.h>

#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 sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

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

void loop() {
 delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
 Serial.print(sonar.ping_median(3) / US_ROUNDTRIP_CM); // Send 3 pins and return the median ping converted to centimeters.
 Serial.println("cm");
}


Enjoy!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: codlink on Aug 18, 2012, 06:38 pm
Wanted to say thanks for the hard work.  Really appreciate this library!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: fairorgan on Aug 21, 2012, 02:41 am
Fantastic job with this new library!

I am especially liking the median feature of v1.5 to eliminate rogue results, but how can this be integrated into the 15 sensor example sketch which does not use ping() but sonar.ping_timer(function) instead?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 21, 2012, 03:32 pm

Fantastic job with this new library!

I am especially liking the median feature of v1.5 to eliminate rogue results, but how can this be integrated into the 15 sensor example sketch which does not use ping() but sonar.ping_timer(function) instead?


To actually combine the two would be simple.  However, in the process it would lose the interrupt aspect of the ping_timer() method.  I've been toying with the idea, and considering new ways of doing it.  One thing I've considered is a mass ping of all sensors at the same time followed by interrupt waiting for the ping echo.  With 15 sensors there could be crazy cross-talk.  But with 4 sensors it would probably work.

Also consider that with 15 sensors, if it were to poll each sensor 3 times it would take 3 times as long.  Not sure how much processing time you have left after pinging 15 sensors.  But, multiply the time it takes by 3 or 5 and you may no longer have time to do anything else, or the pings are just too slow to sense something in time if your robot is moving at a high enough speed.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: fairorgan on Aug 21, 2012, 04:23 pm
Hi Tim,

I was actually only thinking of using two SR-04 sensors (at most three), but like your use of the array in the 15 sensor example for holding the data. Would I be better just duplicating the new ping_median once per sensor and not use an array nor interrupt method?

My project: I am controlling a robot's head position via servos, which currently have either remote control (via joystick) or automatic random positioning of x and y axis. I would like to add the ability for close object tracking of the x axis, so thought the best way would be two ultrasonic sensors pointing slightly apart concealed on the head itself, and in the event of an object coming within say a couple of metres range, the head will stop random movements and track the object in x axis by moving the servo to keep the signal from both ultrasonic sensors the same, until either the object goes out of range or the robot gets bored.

Nick
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Bi0H4z4rD on Aug 21, 2012, 09:31 pm
First of all, thanks for the great job you are doing!

Now, i wanted to comment two issues i am having.

First one is the "0" thing. I still get it too often, but i have found some "logic" sequence on it.

Here are some results:
Code: [Select]
210 210
211 211
210 210
211 211
0 211
0 211 211
0 0
210 211
210 210
211 210
210 210
210 210
0 210
0 210 210
0 0
210 0
210 0 210
210 210
210 210
210 211
0 211
0 211 211
0 0
209 0
209 0 209
209 209
210 211
210 210
210 210
0 210
0 210 210
0 0
210 211
210 210
210 0
210 0 210
211 210
0 211
0 211 211
0 0
210 213
210 210
211 210
210 210
211 211
0 210
0 210 210
188 0
188 0 188
210 0
210 0 210
210 210
210 210
210 209
209 210
0 210
0 210 210
0 0
210 0
210 0 210
210 209
210 210
210 211
0 210
0 210 210
0 0
209 211
210 210
210 210
210 210
210 211
0 210
0 210 210
0 0


First and second colums are read values, and third is just the difference between first and second, so can be ignored. There seems to be an issue that affects after X cycles and makes it return value "0".

Here is the code that i am running:

Code: [Select]
#include <NewPing.h>

NewPing sonar1(2, 3, 400); // Sensor 1: trigger pin, echo pin, maximum distance in cm


#define pingSpeed 35 // Ping frequency (in milliseconds), fastest we should ping is about 35ms per sensor, 100ms is default


void setup() {
 Serial.begin(115200);

}

void loop() {

  unsigned int current_distance1 = sonar1.convert_cm(sonar1.ping());
  delay(100);
  unsigned int current_distance2 = sonar1.convert_cm(sonar1.ping());
        Serial.print(current_distance1);
     Serial.print(" ");
     Serial.println(current_distance2);

  if (current_distance1 > current_distance2) {
   unsigned int result = (current_distance1 - current_distance2);
   if (result > 10){
     Serial.print(current_distance1);
     Serial.print(" ");
     Serial.print(current_distance2);
     Serial.print(" ");
     Serial.println(result);

}
  }
  if (current_distance1 < current_distance2) {
   unsigned int result = (current_distance2 - current_distance1);
   if (result > 10){
     Serial.print(current_distance1);
     Serial.print(" ");
     Serial.print(current_distance2);
     Serial.print(" ");
     Serial.println(result);

}
  }
  delay(29);
}


Maybe it helps you solve this issue.

Second thing, is that after a determined number of cycles, the board stops working. I mean, it just freezes. It might take something like 4 minutes or so. Im not too sure about what the reason is, but just wanted to comment it.

This code is being run on an UNO with an SRF05.

BR

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Bi0H4z4rD on Aug 21, 2012, 10:03 pm
I have some very good news for ppl with so many "0".

The issue is not the library (NewPing). The issue are the connections between the sensor and the board. I just found out that, if i hold tight the connections in the sensor with my hand, i get these results:

Code: [Select]
38 54
38 54 16
34 196
34 196 162
199 198
177 197
177 197 20
172 195
172 195 23
171 171
195 170
195 170 25
109 59
109 59 50
96 46
96 46 50
58 75
58 75 17
55 195
55 195 140
196 83
196 83 113
176 0
176 0 176
171 175
169 195
169 195 26
195 169
195 169 26
194 61
194 61 133
90 137
90 137 47
196 57
196 57 139
111 61
111 61 50


With same code as posted in post above this one, moving the sensor all around my room.

So, hope this helps!

BR
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 22, 2012, 12:53 am
Your code works fine for me.  I guess a loose connection could the the source of the problem.  But, it could also be that you're trying to get a ping that's just too far away.  These sensors really don't work all the way out to 400 or 500cm.  They seem to work okay to about 200cm for most, but I have some sensors that won't read anything consistently beyond around 75cm.  This is the fault of the sensors, not the library as the same thing happens with other libraries or with no library at all.  Try putting something 50cm away from the sensor and see what happens then.  It's just suspicious that it stops working around 200cm and then in your next test all the results are within 200cm.  Maybe it would work without you holding the sensor if all the readings were <50cm?  But, if it is a lose connection, that could also be why it's crashing after a few minutes, it's simply shorting out.  BTW, I've *never* got a zero reading that wasn't for a logical reason and I've *never* had any of my Arduino or Teensy 2.0 crash while using the NewPing library.  And, I've sometimes ran them for several hours or even overnight without a single issue.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Bi0H4z4rD on Aug 22, 2012, 01:17 am

Your code works fine for me.  I guess a loose connection could the the source of the problem.  But, it could also be that you're trying to get a ping that's just too far away.  These sensors really don't work all the way out to 400 or 500cm.  They seem to work okay to about 200cm for most, but I have some sensors that won't read anything consistently beyond around 75cm.  This is the fault of the sensors, not the library as the same thing happens with other libraries or with no library at all.  Try putting something 50cm away from the sensor and see what happens then.  It's just suspicious that it stops working around 200cm and then in your next test all the results are within 200cm.  Maybe it would work without you holding the sensor if all the readings were <50cm?  But, if it is a lose connection, that could also be why it's crashing after a few minutes, it's simply shorting out.  BTW, I've *never* got a zero reading that wasn't for a logical reason and I've *never* had any of my Arduino or Teensy 2.0 crash while using the NewPing library.  And, I've sometimes ran them for several hours or even overnight without a single issue.

Tim


Yeah, as i say, it was all due to loose connections. I just got everything soldered, and now i get 0 only when its out of range. Both tests you see above where done in the same room, where i should get no zeros at all since its pretty small.

I guess the "arduino stops working" would be due to some data generated by the loose connection that would cause an overflow.

Everything working pretty much perfect right now!

BR
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 23, 2012, 12:08 am

I was actually only thinking of using two SR-04 sensors (at most three), but like your use of the array in the 15 sensor example for holding the data. Would I be better just duplicating the new ping_median once per sensor and not use an array nor interrupt method?

My project: I am controlling a robot's head position via servos, which currently have either remote control (via joystick) or automatic random positioning of x and y axis. I would like to add the ability for close object tracking of the x axis, so thought the best way would be two ultrasonic sensors pointing slightly apart concealed on the head itself, and in the event of an object coming within say a couple of metres range, the head will stop random movements and track the object in x axis by moving the servo to keep the signal from both ultrasonic sensors the same, until either the object goes out of range or the robot gets bored.


If you just wanted to use an array to store the ping results, you could easily modify the 15 sensor sketch to work with ping_median instead of ping_timer.  The problem is that the sketch would no longer be interrupt driven, and would be waiting for ping echos instead of doing anything else (like positioning the servo on the robot or doing probably much of anything else).  For example, if you had 3 sensors and each sensor would take 5 samples to find the median that would be a total of 15 pings with at least a 29ms delay between each or a total of around 435ms (about 1/2 second) every ping cycle where your robot can do nothing but read the sensors.  Not at all interrupt driven like the 15 sensor sketch where very little time is wasted monitoring the pings and you're free to do other things what seems like the same time.

A better solution is to continue to use the 15 sensor sketch as a base, but use oversampling to read the sensors multiple times, then average the results.  Here's an example sketch:

Code: [Select]
#include <NewPing.h>

#define SENSORS        3 // Number or sensors.
#define ITERATIONS     5 // Iterations for each sensor.
#define PING_NUM ITERATIONS * SENSORS // Calculates the number of pings.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 29 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[PING_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[PING_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 0;         // Keeps track of which sensor is active.

NewPing sonar[PING_NUM] = {      // Sensor object array (Each sensor's trigger pin, echo pin, and max distance to ping).
 NewPing(12, 11, MAX_DISTANCE), // Sensor 0, sample 1
 NewPing(2, 3, MAX_DISTANCE),   // Sensor 1, sample 1
 NewPing(4, 5, MAX_DISTANCE),   // Sensor 2, sample 1
 NewPing(12, 11, MAX_DISTANCE), // Sensor 0, sample 2
 NewPing(2, 3, MAX_DISTANCE),   // Sensor 1, sample 2
 NewPing(4, 5, MAX_DISTANCE),   // Sensor 2, sample 2
 NewPing(12, 11, MAX_DISTANCE), // Sensor 0, sample 3
 NewPing(2, 3, MAX_DISTANCE),   // Sensor 1, sample 3
 NewPing(4, 5, MAX_DISTANCE),   // Sensor 2, sample 3
 NewPing(12, 11, MAX_DISTANCE), // Sensor 0, sample 4
 NewPing(2, 3, MAX_DISTANCE),   // Sensor 1, sample 4
 NewPing(4, 5, MAX_DISTANCE),   // Sensor 2, sample 4
 NewPing(12, 11, MAX_DISTANCE), // Sensor 0, sample 5
 NewPing(2, 3, MAX_DISTANCE),   // Sensor 1, sample 5
 NewPing(4, 5, MAX_DISTANCE)    // Sensor 2, sample 5
};

void setup() {
 Serial.begin(115200);
 pingTimer[0] = millis() + 75;          // First ping starts at 75ms, gives time for the Arduino to chill before starting.
 for (uint8_t i = 1; i < PING_NUM; i++) // Set the starting time for each sensor.
   pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void loop() {
 for (uint8_t i = 0; i < PING_NUM; i++) { // Loop through all the sensors.
   if (millis() >= pingTimer[i]) {        // Is it this sensor's time to ping?
     pingTimer[i] += PING_INTERVAL * PING_NUM;   // Set next time this sensor will be pinged.
     if (i == 0 && currentSensor == PING_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
     sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
     currentSensor = i;                          // Sensor being accessed.
     cm[currentSensor] = NO_ECHO;                // Make distance NO_ECHO in case there's no ping echo for this sensor.
     sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
   }
 }
 // The rest of your code would go here.
}

void echoCheck() { // If ping received, set the sensor distance to array.
 if (sonar[currentSensor].check_timer())
   cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
 unsigned int uS[ITERATIONS], last;
 uint8_t i, j, x, it, ii;
 for (x = 0; x < SENSORS; x++) {
   uS[0] = NO_ECHO;
   it = ITERATIONS;
   ii = 0;
   for (i = 0; i < ITERATIONS; i++) {
     last = cm[x + (i * SENSORS)];
     if (last != NO_ECHO) {   // Ping in range, include as part of median.
       if (i > 0) {           // Don't start sort till second ping.
         for (j = ii; j > 0 && uS[j - 1] < last; j--) // Insertion sort loop.
           uS[j] = uS[j - 1]; // Shift ping array to correct position for sort insertion.
       } else j = 0;          // First ping is starting point for sort.
       uS[j] = last;          // Add last ping to array in sorted position.
       ii++;                  // Next ping in insertion sort array.
     } else it--;             // Ping out of range, skip and don't include as part of median.
   }
   Serial.print(x);
   Serial.print("=");
   Serial.print(uS[it >> 1]);
   Serial.print("cm ");
 }
 Serial.println();
}


The above sketch is 3 sensors with 5 times oversampling.  Instead of just printing the results in the oneSensorCycle function, it does the same insertion sort/median calculation as NewPing does with the ping_median method.  It pings each sensor (0,1,2) then repeats 5 times.  For example, the ping order is: 0,1,2,0,1,2,0,1,2,0,1,2,0,1,2.  This sketch will also accommodate different oversampling (iterations).  Just change the ITERATIONS define and sonar array to match.

The advantage is that this sketch is totally interrupt driven.  So, the ATmega has all kinds of time to do other things.  While pinging, every 24uS it checks for a ping echo, but the rest of the time your sketch can do other things (like rotate a servo, move, etc).  Once a full 3 sensor, 5 oversample pass is made, it goes to the oneSensorCycle function where the median values for the 3 sensors are calculated, which is very quick and only takes about 30uS.  Basically, the ATmega is free to do other things at the same time it's pinging.  Just be sure to not use any delay statements in your sketches!

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 23, 2012, 09:40 pm
fairorgan got me to thinking about exactly how much processing time is spent using the ping_timer method.  Which also helps to understand what else your sketch could be doing in the remaining time.  So, I wrote a sketch to tests this.  The sketch runs for 30 seconds and logs how much time is spent both initiating the ping and checking for the return echo.  It's not perfect, as there's some overhead in doing these calculations making these estimates a little on the high side.  Anyway, here's the results with pings happening every 29ms.

5cm pings = <1% load
20cm pings = 2% load
70cm pings = 7% load
125cm pings = 12% load
200cm pings = 19% load
500cm pings = 45% load

When reducing the maximum sensor distance value when calling the NewPing constructor, you can greatly reduce the maximum ping_timer load.  For example, if you leave it at the default of 500cm, using ping_timer every 29ms will use up to 45% processor load.  However, lowering the max distance to 200cm means the maximum load can be only 19%, or lowering it to 50cm makes the max load only 5%.  So, setting a maximum distance to the longest distance you need will greatly free up the ATmega to do other parts of your sketch.

The ping frequency also effects the processor load.  The above numbers were all done at a 29ms ping rate.  However, if the ping rate is every 100ms, the load is drastically reduced to only 5.5% (down from 19%).  200cm maximum distance and pinging every 50ms uses a maximum of 11% processor load.

So, when creating an interrupt driven sketch and using NewPing, setting the maximum sensor distance and ping rate to what you really need for your project will greatly effect how much processing time you have available to do other parts of your sketch.  Doing a maximum ping rate of 29ms and leaving the default maximum distance at 500cm will use almost half of the ATmega processing time (45%).  If your project really only needs to sense out to 200cm and pinging once every 100ms is all the faster you really need, you've lowered the processing time down to only 5.5% (almost 1/10th the load).

Keep in mind that these are maximum load amounts.  If the a ping echo is sensed at a shorter distance, the load can be greatly reduced.  For example, the 45% load for a max distance of 500cm at a 29ms ping rate is only if there's a NO_ECHO (zero value).  If under the same settings there's a constant ping echo at 10cm, the load is only 1%.  So, these are truly worse case numbers.  But, to avoid your sketch to be sluggish at times, you should consider the worst case scenario.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: sbright33 on Aug 25, 2012, 12:40 am
Thinking...  Instead of measuring the time of a reflection returned from an object.  What if we had 2 devices synchronized by GPS or an accurate clock.  One sending the ping, the other receiving it.  If we can measure the delay within 1-2us that would be accurate.  Roughly 0.01".  Obviously that is not possible because of the physics of a sound wave. 

What is the theoretical limit using the frequency of the ultrasonic sensors in this configuration? 
It's the same as the normal method.
Let's use 100khz as an example.  Each cycle is 10us.  So 1/10"?  Certainly <1/2".  Averaging multiple readings.

Wouldn't this greatly increase the range compared to using only 1 device?

You could send a ping every 2ms once you know the rough distance. 
Then you'd have 500 measurements to average in only 1 sec, regardless of the distance.

Obviously the limitation would not be the accuracy of the PPS clock, since GPS is +-10ns.
10ns is about 10ft at the speed of LIGHT!
We'll leave that for another LightPing Library...

How can I use this method with the receiver in a Quadcopter?
The problem is the sound from the motors and blades.
The obvious answer is to put the transmitter in the air,
the receiver on the ground where you want to land, then Xbee to send the data.
This works much better, with a huge increase in range, compared to reflecting from the ground when it's grass.

Thoughts?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 26, 2012, 08:03 am

Thinking...  Instead of measuring the time of a reflection returned from an object.  What if we had 2 devices synchronized by GPS or an accurate clock.  One sending the ping, the other receiving it.  If we can measure the delay within 1-2us that would be accurate.  Roughly 0.01".  Obviously that is not possible because of the physics of a sound wave. 

What is the theoretical limit using the frequency of the ultrasonic sensors in this configuration? 
It's the same as the normal method.
Let's use 100khz as an example.  Each cycle is 10us.  So 1/10"?  Certainly <1/2".  Averaging multiple readings.

Wouldn't this greatly increase the range compared to using only 1 device?

You could send a ping every 2ms once you know the rough distance. 
Then you'd have 500 measurements to average in only 1 sec, regardless of the distance.

Obviously the limitation would not be the accuracy of the PPS clock, since GPS is +-10ns.
10ns is about 10ft at the speed of LIGHT!
We'll leave that for another LightPing Library...

How can I use this method with the receiver in a Quadcopter?
The problem is the sound from the motors and blades.
The obvious answer is to put the transmitter in the air,
the receiver on the ground where you want to land, then Xbee to send the data.
This works much better, with a huge increase in range, compared to reflecting from the ground when it's grass.

Thoughts?


The current ping sensors I've found can't ping that quickly.  I'm finding some ping sensors now that can't really ping faster than about 48-49ms, and none can faster than once every 29-32ms.  Basically, they initiate a ping, then you can't initiate another ping till some set time has passed.

Also, when you initiate a ping they take a little while before they actually start (around 450uS).  This varies greatly from device to device.  My library waits for the sensor to be ready so an accurate measurement is taken.

Finally, when sending a large number of pings, there's no way the receiving sensor would be able to know when the ping that arrived was sent.  The only way that would be possible is if the ping itself actually contained a timestamp.

Without some kind of time stamp on the ping itself, very accurately synchronized sensors, and custom built sensors that would ping on command, it's not really possible.  There are probably easier ways of doing it, albeit probably just as expensive.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: sbright33 on Aug 26, 2012, 05:18 pm
There must be a way to SEND a ping every 5ms.  Once you know the rough distance, there's no need to put a timestamp on each ping.  You already know the rough distance, hence how many integer ms it takes.  When you send them at 2-5ms intervals you're now trying to measure the 100us interval.  0.1ms which you add to the integer rough distance you already found.  0.1ms or 0.05ms can be obtained by averaging many samples.  Forget about all this for a minute, it's not my main point.  Let's just use your 50ms interval with no timestamps.

Wouldn't the distance or range increase greatly with 2 devices, sender and receiver in sync?


Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 27, 2012, 05:37 am

There must be a way to SEND a ping every 5ms.  Once you know the rough distance, there's no need to put a timestamp on each ping.  You already know the rough distance, hence how many integer ms it takes.  When you send them at 2-5ms intervals you're now trying to measure the 100us interval.  0.1ms which you add to the integer rough distance you already found.  0.1ms or 0.05ms can be obtained by averaging many samples.  Forget about all this for a minute, it's not my main point.  Let's just use your 50ms interval with no timestamps.

Wouldn't the distance or range increase greatly with 2 devices, sender and receiver in sync?


Around double the distance.  So maybe up to 10 meters for very inexpensive SR04 type sensors.  There are commercial sensors that have a range of up to 50 feet, so using two sensors that range could be as high as 100 feet.

In the case of an Quadcopter, you would need to have two synchronized timers.  I'm not sure if this is the environment you're really considering, but you wouldn't need synchronized timers if you could tie the send and receive sensors to the same Arduino.  There could be an issue with wire length, however.

I still think you'd need a time stamp, unless you're only trying to measure acceleration, which may be possible as the distance between the pings would vary due to acceleration.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: sbright33 on Aug 27, 2012, 03:56 pm
Interesting discussion Tim.  I disagree about timestamps.  Here's how to synchronize 2 Uno's to 2us.
As you can see they stay in sync even without GPS once initialized.
http://arduino.cc/forum/index.php/topic,120288.0.html
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 27, 2012, 05:27 pm

Interesting discussion Tim.  I disagree about timestamps.  Here's how to synchronize 2 Uno's to 2us.
As you can see they stay in sync even without GPS once initialized.
http://arduino.cc/forum/index.php/topic,120288.0.html


Synchronizing two are not the issue, it's knowing when the ping was sent so you know how long it took to get there.  How do you know WHICH ping you're getting?  Without knowing when the ping was sent, how can you possibly know how long it took to get there?

Let's say that you've synced two ATmega's to within 15 microseconds (that accuracy would be plenty).  One starts sending out pings every 2 millisecond which the other would receive.  Even though they're synced, how does the receiving unit know when that ping was sent to be able to calculate the time and therefore the distance?  Without the start time reference, I can't see how you would measure distance.  For the sake of argument, the receiving unit gets the ping, what values are you using to calculate for distance?  You have receive ping time, so what's the start time?  You need both start and end time to calculate the time it took to send the ping.  You know the pings are 2ms apart, but where do you get the start time?

You *could* measure acceleration/deceleration by measuring the time between the pings.  But, that wouldn't need the two units to be time synced anyway, and would do nothing to measure distance.  Only "hotter" or "colder" would be known.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: sbright33 on Aug 27, 2012, 08:31 pm
Let me simplify and round to make it easier to discuss.  We will use your method of only 1 unit.  First send out a single ping and wait up to 100ms.  Each 1ms is about 1ft, 2ms round trip.  Measure the integer number of msecs rounding down.  Let's assume the result is near the middle between 20-21 about 20.5.  We don't need to be more exact than that.  Now send out 100 pings exactly 1ms apart.  Measure the return values mod 1000us.  This gives us the part to the right of the decimal.  We already know 20ms.  Average them.  We might get 522us.  So the answer is 20.52ms.  The last 2 is not significant.  Convert to feet. 

You can see we don't need to identify which ping is which.  It doesn't matter since they're all sent at x.000 secs.  This could be relative to nothing, or GPS time.  But we could figure it out since we know the object is about 20.x ms away.  When a ping comes 20.51ms later we know it was sent 20+us ago, not 19 or 21.

This would not work if the object were exactly 20.01ms away, because we would hear the ping being sent each 1ms.  It would be much louder and block us from hearing the echo.  But it would work with 2 devices using an accurate clock!  Or you could just change the interval to 1.12ms instead of 1.0ms if your echo was being blocked.  More complicated math.

The advantage of my idea is that you get 100's of pings per second to average, even if the target is far away.  This will let you calculate an accurate distance much quicker than waiting 100ms between sending, if you want an answer in 0.3 secs.

If you like my idea you an have it!

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 27, 2012, 11:29 pm

Let me simplify and round to make it easier to discuss.  We will use your method of only 1 unit.  First send out a single ping and wait up to 100ms.  Each 1ms is about 1ft, 2ms round trip.  Measure the integer number of msecs rounding down.  Let's assume the result is near the middle between 20-21 about 20.5.  We don't need to be more exact than that.  Now send out 100 pings exactly 1ms apart.  Measure the return values mod 1000us.  This gives us the part to the right of the decimal.  We already know 20ms.  Average them.  We might get 522us.  So the answer is 20.52ms.  The last 2 is not significant.  Convert to feet. 

You can see we don't need to identify which ping is which.  It doesn't matter since they're all sent at x.000 secs.  This could be relative to nothing, or GPS time.  But we could figure it out since we know the object is about 20.x ms away.  When a ping comes 20.51ms later we know it was sent 20+us ago, not 19 or 21.

This would not work if the object were exactly 20.01ms away, because we would hear the ping being sent each 1ms.  It would be much louder and block us from hearing the echo.  But it would work with 2 devices using an accurate clock!  Or you could just change the interval to 1.12ms instead of 1.0ms if your echo was being blocked.  More complicated math.

The advantage of my idea is that you get 100's of pings per second to average, even if the target is far away.  This will let you calculate an accurate distance much quicker than waiting 100ms between sending, if you want an answer in 0.3 secs.

If you like my idea you an have it!


Sending pings out every 1ms would be too quick as it could take up to 29ms for that ping to arrive.   A ping every 1ms would only work if you were measuring distances of less than around 34cm.  Anything further than that would require a longer time between pings.  I was assuming you were wanting to measure up to 10m (the max sensor distance).  If so, you couldn't ping faster than once every 29ms.  If you only were going to measure within 34cm, then you could send a ping out every 1ms.

And that's just the start of the problem.  Conventional ping sensors would still have a problem for three reasons.  First, when you tell a ping sensor to send out a ping, it takes it's good old time doing it.  I haven't found one that takes less than 440 microseconds (7cm worth) of waiting around before it starts.  Some can take over 88ms!  Secondly, some sensors go inactive for a while after a ping is received, or even longer if a ping is not received (like 32ms!)  Finally, existing sensors don't listen for an echo till that same sensor sends out a ping first.  In other words, the receiving sensor isn't even listening when the sending sensor is sending out pings.

Maybe I don't understand what you're trying to accomplish.  Do you want to ping 100 times a second?  You can almost do that already with the NewPing library if your sensor allows it.  Or, are you trying to make an ultrasonic sensor work for further than 5m?  And if so there are sensors that work up to 50 feet away already.  But, the technique you're speaking of would not allow you to send 100 pings per second and measure the distance from 10m away.  Pinging every 29ms for 10m or pings every 1ms for distances within 34cm would be possible.  But only with custom designed ping sensors and receivers and accurately synced devices.

I guess I just don't see what you're trying to do, as you can already ping at very high speeds with the NewPing library with sensors that support it (not quite 1ms, but every 3ms works for distances of about 50cm).  It's also a bit of an issue outside the scope of the NewPing library as you would need custom hardware and special hardware to sync the two systems.  More of a specialty thing rather than a public library.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: sbright33 on Aug 27, 2012, 11:51 pm
I've got a working demo pinging every 1ms using 2 simple transducers.  The object is 10ft away.
To summarize: First you need to know how many integer feet away it is.

Sounds like I cannot use the same hardware you have with 2 units, sender and receiver.
My goal is to double my distance, as you said.

With a Quadcopter, this S/R method allows me to put the receiver on the ground away from the noisy motors and blades.
Again doubling the distance, that's >x4 compared to using a single sensor in the air.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 28, 2012, 01:12 am

I've got a working demo pinging every 1ms using 2 simple transducers.  The object is 10ft away.
To summarize: First you need to know how many integer feet away it is.

Sounds like I cannot use the same hardware you have with 2 units, sender and receiver.
My goal is to double my distance, as you said.

With a Quadcopter, this S/R method allows me to put the receiver on the ground away from the noisy motors and blades.
Again doubling the distance, that's >x4 compared to using a single sensor in the air.



Yes, you would need to know how many integer feet away it is.  It also wouldn't be able to detect how many integer feet away it was or if it moved position outside of a foot it wouldn't know it was at a different position.  But, what's the point of sensing the distance if you already know the integer feet and the distance couldn't vary that much?

If you simply want to double the distance, use an ultrasonic sensor that can sense up to 50 feet away.  No need to change anything else.  Or, use two sensors connected to the same Arduino with one having a 10 foot connection.  Disable the outbound ping speaker on the receiving unit and trigger both at the same time.

Not sure how it helps the Quadcopter, other than maybe to hover in place, and only when on top of the receiving sensor.  How do you know how many integer feet away it is?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: sbright33 on Aug 28, 2012, 01:39 am
You have to first send a long ping to get the integer part.  Then the next pings come 1ms later, so it can't have moved very far.  If it does move slowly you can track it's location with only 1ms pings.  You don't have to wait for the long ping to return to begin sending more, unless you are concerned about missing the first one and not knowing it.

There are 2 new independent ideas here.  One of them is sending pings closer together like 1ms.  The other is using a separate sender/receiver, with one of them attached to the object.  You can choose one or both methods.

Yes it would only help for landing at a particular spot.  This is better than nothing because it doesn't work otherwise past 3ft.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 28, 2012, 05:42 am

You have to first send a long ping to get the integer part.  Then the next pings come 1ms later, so it can't have moved very far.  If it does move slowly you can track it's location with only 1ms pings.  You don't have to wait for the long ping to return to begin sending more, unless you are concerned about missing the first one and not knowing it.

There are 2 new independent ideas here.  One of them is sending pings closer together like 1ms.  The other is using a separate sender/receiver, with one of them attached to the object.  You can choose one or both methods.

Yes it would only help for landing at a particular spot.  This is better than nothing because it doesn't work otherwise past 3ft.


I will have to bow to your better wisdom of using a quadcopter. I'm only in the research stage of building one at this point.  I had planned on possibly using an ultrasonic sensor as a type of automated landing assistance or possibly crash protection or autonomous usage.  Using an ultrasonic sensor was not paramount to my quadcopter plans (primary goal is for aerial photography/video).  But, I had not considered noise from the quadcopter interfering with the ultrasonic distancing.

Ping frequency didn't seem to be an issue as I figured the ATmega would have a lot to do with reading all the sensors/controls, calculating stabilization etc.  Also, I only had figured I'd ping to about 8 feet (250cm) where I could ping every 15ms (66/second).  With a quadcopter going 10mph (14.67 fps) that works out to about a ping every 2.5 inches.  I figured if it was moving any faster than 10mph, it would probably be moving too quickly at 8 feet to stop in time anyway.  Maybe in reality this is a naive plan, as prop noise was not considered and speed is unrealistic.  I had figured 8 feet @ 10mph would still give 2.5" of resolution.  Obviously, the quadcopter would be slowed at this point with a landing in the <3mph range which 15ms pings would mean it could only be moving about a cm per ping.  That naively seems like a realistic landing, but maybe not.

The other issue specific to a quadcopter is that the NewPing library is *NOT* currently suited to quadcopters!  While it's faster than other libraries, there's an inherent issue were even the fastest (trigger/echo) sensors will sit around waiting for about 440uS per ping.  That's just not acceptable in my opinion for a flight controller.  I have plans to make NewPing work in this situation, but currently it's not advised.  I would suggest for a quadcopter you use a I2C ping sensor that does all the calculation without waiting around for the ping to return.  Obviously, doing it your way where we just ping from the quadcopter we don't need to wait for the ping to initiate nor the ping echo to return we don't have to worry about CPU usage.  But still, NewPing is not suited for that purpose as it's a distancing library.

Your project sounds interesting, and I may very well look into this when my quadcopter is launched, but I don't think this usage will ever be integrated in the NewPing library.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: sbright33 on Aug 28, 2012, 04:57 pm
Your library is suitable if you want slow updates close to the ground before landing.  Sometimes that is all we need for a Quadcopter.

I have been flying for months.  I recommend beginning with a KK board.  It has gyros, it's simple, and it just works the first time.  KKv2.0 has accelerometers too, to keep it level.  It's hard enough to fly even with this, impossible without it the first time.

The next step is a pressure sensor to keep it steady at a particular altitude for example 10m above ground.

Then a compass to keep it pointed north, now it's easy to control the x,y position manually with only 1 stick on transmitter!
I've found a 2D compass works if you have a KK2.0 board first.

If you're still having fun add GPS.  Hobbyking has a frame and 4 motors for $30.  Let me know if you have any question!
Steve

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 29, 2012, 09:34 am

Your library is suitable if you want slow updates close to the ground before landing.  Sometimes that is all we need for a Quadcopter.

I have been flying for months.  I recommend beginning with a KK board.  It has gyros, it's simple, and it just works the first time.  KKv2.0 has accelerometers too, to keep it level.  It's hard enough to fly even with this, impossible without it the first time.

The next step is a pressure sensor to keep it steady at a particular altitude for example 10m above ground.

Then a compass to keep it pointed north, now it's easy to control the x,y position manually with only 1 stick on transmitter!
I've found a 2D compass works if you have a KK2.0 board first.

If you're still having fun add GPS.  Hobbyking has a frame and 4 motors for $30.  Let me know if you have any question!
Steve


I considered the KK due to the extreme low cost.  But, will probably go for the Crius AIO Pro (http://www.rctimer.com/index.php?gOo=goods_details.dwt&goodsid=765&productname=) because checks all the boxes and is only $63 for a ATmega2560, 10DOF (including the MPU6050), and GPS can be added for only $25.  The KK2.0 is interesting, but I want more control, not less.  Also, I decided a deal-breaker was any ATmega328p-based flight controller due to the lower bit PWM control.  The ATmega32u4 with its (6) 11-bit PWM's was considered (in the NanoWii and the Pro Micro).  But, the price is higher than the Crius AIO Pro once you add a magnetometer or flight controller to the Pro Micro.  I really like the NanoWii.  But, the price is already very close to the Crius AIO Pro and adding a magnetometer puts it over, before a altimeter is even considered.  The Crius AIO Pro is really hard to beat in price, and it's not missing anything either.

ESC's and motors are my issues now.  First I was considering the Turnigy Plush, but then I read about the SimonK firmware and found the RCTimer SimonK 30A (http://www.rctimer.com/index.php?gOo=goods_details.dwt&goodsid=779&productname=) ESC's.  But, I'm worried about the lack of an external resonator in it.  So, I'm considering a HobbyKing F-30A and flashing the SimonK firmware myself.  But, the F-30A isn't in stock, and typically hasn't been for years now ;-(

Then there's the motor issue.  Finding a quality motor that's not too expensive has been a challenge.  I read recommendations, only to read later that the model has changed or there's new quality problems.  Looking for something in the 2836/kv850 range that can drive a 1147 prop (I'm going to run Lipo 3S).  The Turnigy 2217/860kv (http://www.hobbyking.com/hobbyking/store/__5691__Turnigy_2217_20turn_860kv_22A_Outrunner.html) seems like a good motor, and I can get 4 for only $58.

I'd like to get everything from one place, but it's starting to look like I'm going to be making a few different orders.  Suggestions?

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: sbright33 on Aug 29, 2012, 05:03 pm
I like your choices will read about Crius.  I'm going low cost.  ESC for $6.  Motors for $7 for my first model.  Ebay or Amazon free shipping.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: sbright33 on Aug 30, 2012, 06:36 pm
I agree, Crius seems like the best choice.  It's new and complicated inside.  But not many people have tested it in the real world.  The code is new too.  A small bug might cause a crash if you're not an experienced Quad pilot.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 31, 2012, 06:09 am

I agree, Crius seems like the best choice.  It's new and complicated inside.  But not many people have tested it in the real world.  The code is new too.  A small bug might cause a crash if you're not an experienced Quad pilot.


The AIO had one hardware issue, which has since been resolved (weak USB connector).  Software-wise, it's just using MultiWii, and nothing special as it's all standard hardware with standard connections.  To MultiWii, it's just a ATmega 2560 with a 6050 and other sensors attached.  Not saying there couldn't be a problem, but those that have it have had success and it's been out for a few months now so there's a lot of them out there.  There's been a couple with problems, but problems with vibration and losing a radio connection can be found for every flight controller (as it's the fault of something else, like unbalanced motor or a cheap radio).

It's not Crius' first flight controller either.  So, they've had some experience.  Finally, nothing they're doing is revolutionary.  They just print up a board connecting very common chips together in common ways.  Really, all Crius did was make traces between very common and well documented processors/chips.  It's only $60, if it was $300 from some unknown I'd reconsider.  Heck, a branded Arduino Mega is almost $60 with 0DOF.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: stan001 on Sep 05, 2012, 09:10 pm
Does this library works with URM37 v3.2 ( http://www.dfrobot.com/wiki/index.php?title=URM37_V3.2_Ultrasonic_Sensor_(SKU:SEN0001) )

Mode 3: PWM passive control mode
Under this mode, a low pull on pin COMP/TRIG will trigger a sensor reading. The width of the pulse is proportional to the servo rotating degree. After a successful sensor reading, Pin PWM will output pulses, every 50us represents 1cm. If the reading is invalid, a 50000us pulse will be returned.

Can I use the NewPing library and change the NewPing.h to make it work for the URM37 v3.2 ?

Thanks
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 06, 2012, 04:14 pm

Does this library works with URM37 v3.2 ( http://www.dfrobot.com/wiki/index.php?title=URM37_V3.2_Ultrasonic_Sensor_(SKU:SEN0001) )

Mode 3: PWM passive control mode
Under this mode, a low pull on pin COMP/TRIG will trigger a sensor reading. The width of the pulse is proportional to the servo rotating degree. After a successful sensor reading, Pin PWM will output pulses, every 50us represents 1cm. If the reading is invalid, a 50000us pulse will be returned.

Can I use the NewPing library and change the NewPing.h to make it work for the URM37 v3.2 ?

Thanks


Reading the documentation, it appears that it will work with the NewPing library.  It does appear that you would need to change the US_ROUNDTRIP_CM to 50 and US_ROUNDTRIP_IN to 127 for the distance calculations to be correct.

With that said, if you don't already have the URM37 and there's not a good reason why you need to buy this specific one, I would suggest getting one that's known to work with NewPing.  As a bonus, they're also cheaper than the URM37.

Further, if it was me, and I already had this sensor or was required to use it for another purpose, I would use the serial interface instead of the trigger/PWM interface.  There's many benefits of using the serial interface, including setting up automated pings, not waiting for ping echos, getting temperature, etc.  They've also created a serial library for the sensor so you don't need too much effort to get it working in this way.

If you do get the sensor working with NewPing, let me know.  I'd like to hear your experience.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: crispy on Sep 09, 2012, 09:35 pm
This may have been answered before in the thread, but I didn't see it on a quick read-through.

I'm using the NewPing library (which is awesome) and the Arduino Motor Shield.  Unfortunately the shield uses pins 3 and 11 to do the motor PWM, which conflicts with Timer2 used in NewPing.

Is there a way to change what timer NewPing uses?  Or, is it just simpler to un-stack the shield and the Arduino and manually wire the PWM into different pins?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 10, 2012, 04:57 am

This may have been answered before in the thread, but I didn't see it on a quick read-through.

I'm using the NewPing library (which is awesome) and the Arduino Motor Shield.  Unfortunately the shield uses pins 3 and 11 to do the motor PWM, which conflicts with Timer2 used in NewPing.

Is there a way to change what timer NewPing uses?  Or, is it just simpler to un-stack the shield and the Arduino and manually wire the PWM into different pins?


First off, NewPing does not use Timer2 for the standard ping() and ping_median() methods.  It's only for the timer interrupt ping_timer() method where NewPing uses Timer2 on the Arduino Uno.  Also, the library uses Timer4 for the Teensy and Leonardo (ATmega32U4).  So, if you're just using ping() or ping_median(), you have no conflict with Timer2 (or Timer4 on the ATmega32U4).

However, if you're using the timer interrupt ping_timer() method, yes, it will use Timer2 and there isn't an option to use Timer1.  I had first written it to work with both Timer1 and Timer2 but decided to only implement Timer2 because the servo library uses Timer1, which is a common library.  However with motors, there's many different ways of doing it, most of which don't use any timers (I use serial motor controllers for example).

Also, because Timer2 is 8 bit and Timer1 is 16 bit, it's not as simple as changing all the 2's to 1's to make it work.  It wouldn't be too difficult for someone to modify the code to allow a switch for Timer2 or Timer1.  But, they would need a good deal of knowledge on how the timer interrupts work on the ATmega at a lower level.  I don't feel it's worth doing as I would think most people writing event-driven code that requires using the ping_timer() method also wouldn't be using the motor shield and instead using an outboard motor controller with better PWM control.  But, maybe I'm mistaken.  In any case, I'm probably not the one to add this support, someone else will if they feel it's required for their situation.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: crispy on Sep 10, 2012, 02:38 pm
Tim,

Thanks for your very thorough response.  The sketch I'm developing does use the interrupt_ping_timer() method, since the sketch needs to "multitask".  It sounds like changing the timer that NewPing uses is a non-starter, since I will also need to drive a servo (in addition to 2 motors).

It sounds like the best option for me is to unstack the shield and change which pins are used for PWM.

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 10, 2012, 05:59 pm

Tim,

Thanks for your very thorough response.  The sketch I'm developing does use the interrupt_ping_timer() method, since the sketch needs to "multitask".  It sounds like changing the timer that NewPing uses is a non-starter, since I will also need to drive a servo (in addition to 2 motors).

It sounds like the best option for me is to unstack the shield and change which pins are used for PWM.


The ATmega328 has limited timers (3, but Timer0 is used for millis and delay so you really only have 2 available).  When doing a project where motors and servos are involved, you're really cutting it close when using an ATmega328.  You can still do it, using a serial motor controller (http://www.pololu.com/catalog/product/1110) or I2C motor controller (http://www.seeedstudio.com/depot/grove-i2c-motor-driver-p-907.html?cPath=170_173) (which are cheap, small, use fewer pins and allow for control of many motors using multiple controllers).  Or, you can use a Teensy/Leonardo (ATmega32u4) or ATmega2560 based microcontroller systems that have additional timers/PWM pins.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: crispy on Sep 11, 2012, 03:03 pm

The ATmega328 has limited timers (3, but Timer0 is used for millis and delay so you really only have 2 available).  When doing a project where motors and servos are involved, you're really cutting it close when using an ATmega328.  You can still do it, using a serial motor controller (http://www.pololu.com/catalog/product/1110) or I2C motor controller (http://www.seeedstudio.com/depot/grove-i2c-motor-driver-p-907.html?cPath=170_173) (which are cheap, small, use fewer pins and allow for control of many motors using multiple controllers).  Or, you can use a Teensy/Leonardo (ATmega32u4) or ATmega2560 based microcontroller systems that have additional timers/PWM pins.


I looked into the motor controllers you linked, and frankly serial communication is something I'd rather avoid if possible on this project. I'm trying to keep the scope somewhat limited so I actually have a chance of getting the whole thing to work.

I've looked at my pinout list and I show 2 pins (5 and 6) will still have PWM available even if I use both the Servo and NewPing libraries.  I will also have enough pins free to drive a conventional motor shield.  So this is the route I would prefer to go.  However, I haven't found much in the way of discussion about using the "official" motor shield un-stacked from the Arduino.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 11, 2012, 07:06 pm


The ATmega328 has limited timers (3, but Timer0 is used for millis and delay so you really only have 2 available).  When doing a project where motors and servos are involved, you're really cutting it close when using an ATmega328.  You can still do it, using a serial motor controller (http://www.pololu.com/catalog/product/1110) or I2C motor controller (http://www.seeedstudio.com/depot/grove-i2c-motor-driver-p-907.html?cPath=170_173) (which are cheap, small, use fewer pins and allow for control of many motors using multiple controllers).  Or, you can use a Teensy/Leonardo (ATmega32u4) or ATmega2560 based microcontroller systems that have additional timers/PWM pins.


I looked into the motor controllers you linked, and frankly serial communication is something I'd rather avoid if possible on this project. I'm trying to keep the scope somewhat limited so I actually have a chance of getting the whole thing to work.

I've looked at my pinout list and I show 2 pins (5 and 6) will still have PWM available even if I use both the Servo and NewPing libraries.  I will also have enough pins free to drive a conventional motor shield.  So this is the route I would prefer to go.  However, I haven't found much in the way of discussion about using the "official" motor shield un-stacked from the Arduino.


The serial and I2C suggestions also solves the problem with needing more than 2 motors (you can daisy chain many of these controllers for control of many motors using only 2 Arduino pins in total).  When you want to control 4 motors as well as doing anything else, it's a real challenge with the limited pins of the ATmega328.  There's other advantages also, like ultrasonic PWM to avoid motor hum and whine.

If you only want motor control and want to use the Arduino PWM pins to control speed, you can use the TB6612FNG Dual Motor Driver Carrier (http://www.pololu.com/catalog/product/713) which uses the same TB6612FNG MOSFET-based H-bridge as the serial controller but without serial control (you control it directly with Arduino pins).  The TB6612FNG is a better H-bridge than the L298N used in the Arduino motor shield (it's also very cheap).  While the Arduino motor shield says it can take 2A, the L298N really can't deal with that well and gets very hot.  The TB6612FNG is rated for 1A with 3A max, but it can actually handle two motors going at 1A each at the same time as well as 3A spikes without causing a fire like the L298N will try to do.  If your motors are even close to a 1A rating, the TB6612FNG would be a better option than the L298N.

Or, you can hack up your motor shield to use pins 5 and 6.  I'd probably cut traces and wire new jumpers to keep the shield basically as-is.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: crispy on Sep 11, 2012, 07:42 pm
I agree that the official motor driver is not the most ideal for my application.  I already have one on-hand though, so I have an incentive to try to get it to work before buying additional components.  The motors I'm using are low-current low voltage motors that come with the Tamiya double gearbox so the current limit should not be an issue.

I like the look of the pololu driver you linked, I will keep it in mind if the shield does not work out.

Thanks again for your help.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 12, 2012, 04:06 pm

I agree that the official motor driver is not the most ideal for my application.  I already have one on-hand though, so I have an incentive to try to get it to work before buying additional components.  The motors I'm using are low-current low voltage motors that come with the Tamiya double gearbox so the current limit should not be an issue.

I like the look of the pololu driver you linked, I will keep it in mind if the shield does not work out.

Thanks again for your help.


Actually, those low voltage motors are typically worse.  Higher quality, higher voltage motors will typically be easier on an H-bridge and keep things cooler.  Just keep your fingers and flammable material away from the L298N ;-)  And if you do decide to get another motor controller, consider the serial interface version.  It's far easier to connect and use, control using just two wires no matter how many motors you have, and simple library commands.  I have a half-written updated library for it that simplifies things even more.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: stan001 on Sep 18, 2012, 11:09 am

Reading the documentation, it appears that it will work with the NewPing library.  It does appear that you would need to change the US_ROUNDTRIP_CM to 50 and US_ROUNDTRIP_IN to 127 for the distance calculations to be correct.

With that said, if you don't already have the URM37 and there's not a good reason why you need to buy this specific one, I would suggest getting one that's known to work with NewPing.  As a bonus, they're also cheaper than the URM37.

Further, if it was me, and I already had this sensor or was required to use it for another purpose, I would use the serial interface instead of the trigger/PWM interface.  There's many benefits of using the serial interface, including setting up automated pings, not waiting for ping echos, getting temperature, etc.  They've also created a serial library for the sensor so you don't need too much effort to get it working in this way.

If you do get the sensor working with NewPing, let me know.  I'd like to hear your experience.

Tim


Thanks for the reply...

I could not get it to work with the NewPing libraries after making the changes to the header file...  :~

Instead I use the serial library for the URM37 but still have some issues on using two sensors at once....

I'm using this as a people counter sensor to be mounted at the ceiling of retail store...

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 19, 2012, 05:18 pm


Reading the documentation, it appears that it will work with the NewPing library.  It does appear that you would need to change the US_ROUNDTRIP_CM to 50 and US_ROUNDTRIP_IN to 127 for the distance calculations to be correct.

With that said, if you don't already have the URM37 and there's not a good reason why you need to buy this specific one, I would suggest getting one that's known to work with NewPing.  As a bonus, they're also cheaper than the URM37.

Further, if it was me, and I already had this sensor or was required to use it for another purpose, I would use the serial interface instead of the trigger/PWM interface.  There's many benefits of using the serial interface, including setting up automated pings, not waiting for ping echos, getting temperature, etc.  They've also created a serial library for the sensor so you don't need too much effort to get it working in this way.

If you do get the sensor working with NewPing, let me know.  I'd like to hear your experience.

Tim


Thanks for the reply...

I could not get it to work with the NewPing libraries after making the changes to the header file...  :~

Instead I use the serial library for the URM37 but still have some issues on using two sensors at once....

I'm using this as a people counter sensor to be mounted at the ceiling of retail store...



Did you wire it to use PWM passive control mode instead of the serial?  Also, it's possible it needs a longer MAX_SENSOR_DELAY or trigger length.  Anyway, if you can't get it to work correctly with 2 sensors using the serial method, you could send it to me and I'll try to get the PWM mode working with NewPing and then send you the sensor back.  It seems as though with a little tweaking it would work.  And if so, when you got the sensor back you could implement both sensors.  I'd like to add support for this sensor so it's worth my time to try to get it working for you.

Let me know.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: stan001 on Sep 19, 2012, 06:40 pm


Did you wire it to use PWM passive control mode instead of the serial?  Also, it's possible it needs a longer MAX_SENSOR_DELAY or trigger length.  Anyway, if you can't get it to work correctly with 2 sensors using the serial method, you could send it to me and I'll try to get the PWM mode working with NewPing and then send you the sensor back.  It seems as though with a little tweaking it would work.  And if so, when you got the sensor back you could implement both sensors.  I'd like to add support for this sensor so it's worth my time to try to get it working for you.

Tim


Tim,

I double check and wire the pins are correctly... now pin 4 = PWM, pin 5 = trigger

I tried the NewPing library again and this time I put it on a oscilloscope to "see" what's going on....

The URM37/echo pin seems to be working correctly as the pulse width decreases when range is near and pulse width increases when range is far away...

The serial monitor is still showing 0cm ....

I measured the width from the scope and here is what I got :-

1cm =    0.5ms ( 500us )
20cm = 1ms
30cm = 1.5ms
40cm = 2ms
100cm = 5.16ms
185cm = 8.00ms ( my ceiling height )

The period is 68ms for every distance measurement....

The codes is as per the NewPingExample and I only made changes to the defines below

#define US_ROUNDTRIP_CM 50
#define US_ROUNDTRIP_IN 127
#define TRIGGER_PIN  5  
#define ECHO_PIN     4  
#define MAX_DISTANCE 500

Please suggest what else should I try...
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 19, 2012, 08:55 pm



Did you wire it to use PWM passive control mode instead of the serial?  Also, it's possible it needs a longer MAX_SENSOR_DELAY or trigger length.  Anyway, if you can't get it to work correctly with 2 sensors using the serial method, you could send it to me and I'll try to get the PWM mode working with NewPing and then send you the sensor back.  It seems as though with a little tweaking it would work.  And if so, when you got the sensor back you could implement both sensors.  I'd like to add support for this sensor so it's worth my time to try to get it working for you.

Tim


Tim,

I double check and wire the pins are correctly... now pin 4 = PWM, pin 5 = trigger

I tried the NewPing library again and this time I put it on a oscilloscope to "see" what's going on....

The URM37/echo pin seems to be working correctly as the pulse width decreases when range is near and pulse width increases when range is far away...

The serial monitor is still showing 0cm ....

I measured the width from the scope and here is what I got :-

1cm =    0.5ms ( 500us )
20cm = 1ms
30cm = 1.5ms
40cm = 2ms
100cm = 5.16ms
185cm = 8.00ms ( my ceiling height )

The period is 68ms for every distance measurement....

The codes is as per the NewPingExample and I only made changes to the defines below

#define US_ROUNDTRIP_CM 50
#define US_ROUNDTRIP_IN 127
#define TRIGGER_PIN  5  
#define ECHO_PIN     4  
#define MAX_DISTANCE 500

Please suggest what else should I try...



It appears the ping trigger process is working if you're getting activity on the echo pin.  Does it look like a nice square wave?  Is the pulse width measured high, low, or are both the same?  NewPing waits up to MAX_SENSOR_DELAY for the echo pin to go high and then measures the time it's high.  If the distance measurement is on the low state instead of high, it would obviously be wrong.  Also, if you modify the sketch to trigger just one ping, how long will the echo pin give the PWM distance?

I'd try set the MAX_SENSOR_DELAY to a very large number, maybe a million.  Also, set the ping rate to be very slow, like once every 5 seconds.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: stan001 on Sep 19, 2012, 09:25 pm


It appears the ping trigger process is working if you're getting activity on the echo pin.  Does it look like a nice square wave?  Is the pulse width measured high, low, or are both the same?  NewPing waits up to MAX_SENSOR_DELAY for the echo pin to go high and then measures the time it's high.  If the distance measurement is on the low state instead of high, it would obviously be wrong.  Also, if you modify the sketch to trigger just one ping, how long will the echo pin give the PWM distance?

I'd try set the MAX_SENSOR_DELAY to a very large number, maybe a million.  Also, set the ping rate to be very slow, like once every 5 seconds.

Tim


Yes nice square wave as per the snapshot I sent to your e-mail..

From the scope, the URM37 PWM pin is ALWAYS HIGH (5V) and when it is activated, it goes low instead... that is where I got my above measurements....

Codes from the URM37 using PWM passive mode :-

unsigned long DistanceMeasured=pulseIn(URPWM,LOW);

Mode 3: PWM passive control mode
Under this mode, a low pull on pin COMP/TRIG will trigger a sensor reading. The width of the pulse is proportional to the servo rotating degree. After a successful sensor reading, Pin PWM will output pulses, every 50us represents 1cm. If the reading is invalid, a 50000us pulse will be returned.


Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: stan001 on Sep 21, 2012, 03:11 pm
Dear Tim,

Are you able to add the option to have the distance measurement/pulse width based on LOW signal instead of HIGH signal ? With this, the URM37 passive PWM mode should work with the NewPing library...

Thanks



Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 21, 2012, 04:43 pm



It appears the ping trigger process is working if you're getting activity on the echo pin.  Does it look like a nice square wave?  Is the pulse width measured high, low, or are both the same?  NewPing waits up to MAX_SENSOR_DELAY for the echo pin to go high and then measures the time it's high.  If the distance measurement is on the low state instead of high, it would obviously be wrong.  Also, if you modify the sketch to trigger just one ping, how long will the echo pin give the PWM distance?

I'd try set the MAX_SENSOR_DELAY to a very large number, maybe a million.  Also, set the ping rate to be very slow, like once every 5 seconds.

Tim


Yes nice square wave as per the snapshot I sent to your e-mail..

From the scope, the URM37 PWM pin is ALWAYS HIGH (5V) and when it is activated, it goes low instead... that is where I got my above measurements....

Codes from the URM37 using PWM passive mode :-

unsigned long DistanceMeasured=pulseIn(URPWM,LOW);

Mode 3: PWM passive control mode
Under this mode, a low pull on pin COMP/TRIG will trigger a sensor reading. The width of the pulse is proportional to the servo rotating degree. After a successful sensor reading, Pin PWM will output pulses, every 50us represents 1cm. If the reading is invalid, a 50000us pulse will be returned.



If it only goes low once that would be the problem, as NewPing is looking for a high signal, not a low signal.  I had figured it would put out a constant PWM with the same duration of high as low, as it says it puts out pulses, not pulse.  I'd really need to see the rise and fall timings to see if there's a way of doing this without switching it to sensing a low signal rather than a high signal.  Also, the number of pulses it outputs (or is it just a single pulse).

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 21, 2012, 04:44 pm

Dear Tim,

Are you able to add the option to have the distance measurement/pulse width based on LOW signal instead of HIGH signal ? With this, the URM37 passive PWM mode should work with the NewPing library...

Thanks


It would be possible.  But would be like shooting in the dark without an actual sensor to test with.  There could be a host of other problems.  From your testing, is it sending out a single low pulse or is it pulses as the documentation states?

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: stan001 on Sep 21, 2012, 08:41 pm


Dear Tim,

Are you able to add the option to have the distance measurement/pulse width based on LOW signal instead of HIGH signal ? With this, the URM37 passive PWM mode should work with the NewPing library...

Thanks


It would be possible.  But would be like shooting in the dark without an actual sensor to test with.  There could be a host of other problems.  From your testing, is it sending out a single low pulse or is it pulses as the documentation states?

Tim


From my observation on the scope, it is sending multiple pulses based on the returned ping timing/distance..

I'm not sure what the NewPing does on the trigger pins but it surely trigger the PWM pins to send a LOW pulse per trigger on a constant basis...

I thought if the library read a high pulse whereas the URM37 reads a low pulse, a "simple"  #if define URM37 would change the codes whereas all the other codes and timing would remain the same...


*** I could be wrong or it just sounded too simplified...

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 22, 2012, 04:03 am

I thought if the library read a high pulse whereas the URM37 reads a low pulse, a "simple"  #if define URM37 would change the codes whereas all the other codes and timing would remain the same...


*** I could be wrong or it just sounded too simplified...


You're right, that would be all that's required to read a LOW pulse instead of a HIGH pulse.  It's a little more complicated as it waits and makes sure the signal is LOW before it times the HIGH pulse.  But, it's still shooting in the dark without the sensor in front of me.

You can try the following changes to NewPing.cpp, which just changes the pulse measurement from HIGH to LOW:

Code: (Line 38) [Select]

while (!(*_echoInput & _echoBit))                   // Wait for the ping echo.


Code: (Lines 97 and 98) [Select]

while (!(*_echoInput & _echoBit) && micros() <= _max_time) {} // Wait for echo pin to clear.
while (*_echoInput & _echoBit)                                // Wait for ping to start.


Code: (Line 122) [Select]

if (*_echoInput & _echoBit) {    // Ping echo received.


Give it a go.  Keep in mind that this is just a guess, and we're still assuming a lot.  But, it's a simple thing to try.  There's other issues as well, like this could give a reading, but it may not be consistent or accurate due to timing issues.

Let me know what happens.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: stan001 on Sep 22, 2012, 04:37 am


You're right, that would be all that's required to read a LOW pulse instead of a HIGH pulse.  It's a little more complicated as it waits and makes sure the signal is LOW before it times the HIGH pulse.  But, it's still shooting in the dark without the sensor in front of me.

You can try the following changes to NewPing.cpp, which just changes the pulse measurement from HIGH to LOW:

Code: (Line 38) [Select]

while (!(*_echoInput & _echoBit))                   // Wait for the ping echo.


Code: (Lines 97 and 98) [Select]

while (!(*_echoInput & _echoBit) && micros() <= _max_time) {} // Wait for echo pin to clear.
while (*_echoInput & _echoBit)                                // Wait for ping to start.


Code: (Line 122) [Select]

if (*_echoInput & _echoBit) {    // Ping echo received.


Tim


Dear Tim,

I made the changes to the suggested codes and it WORKS on the URM37 using the Examples codes...

I'm using Pin4 for PWM & Pin5 for Trigger...

I also tried with TWO sensors and it is still working without any delays between reading the sensors...

Let me capture a scope output and post it here later...

Thanks a lot!!!

Stanley

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 22, 2012, 05:34 am

I made the changes to the suggested codes and it WORKS on the URM37 using the Examples codes...

I'm using Pin4 for PWM & Pin5 for Trigger...

I also tried with TWO sensors and it is still working without any delays between reading the sensors...

Let me capture a scope output and post it here later...

Thanks a lot!!!

Stanley


We got lucky for sure.  Is it reading accurate distances?  3 distances are a good test (10cm, 50cm and 200cm) something like that.  It probably won't be prefect, but within about 1cm is about the best you can hope for with ultrasonic sensors.  As it is now, we're assuming 50uS is really 1cm.  Also, you should probably try to test the ping_in() method to make sure the inches are also correct.

I've implemented changes to the NewPing Library to a allow support for the URM37 sensor in PWM mode.  v1.6 will include this support.  There's a URM37_ENABLED define you set to "true" to enable support (which measures the low signal length instead of the high and adjusts the length so each 50uS is 1cm).

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: stan001 on Sep 22, 2012, 03:01 pm

We got lucky for sure.  Is it reading accurate distances?  3 distances are a good test (10cm, 50cm and 200cm) something like that.  It probably won't be prefect, but within about 1cm is about the best you can hope for with ultrasonic sensors.  As it is now, we're assuming 50uS is really 1cm.  Also, you should probably try to test the ping_in() method to make sure the inches are also correct.

I've implemented changes to the NewPing Library to a allow support for the URM37 sensor in PWM mode.  v1.6 will include this support.  There's a URM37_ENABLED define you set to "true" to enable support (which measures the low signal length instead of the high and adjusts the length so each 50uS is 1cm).

Tim


I did some measurements, the distance of the following looks good :-

10cm - ok
50cm - ok
100cm - ok
150cm - ok
200cm - ok

With +/- 1 to 2cm variance for distance above 100cm...

I have a strange issues, one of the URM37 sensors, after operating for 7-9 hours, it just stop working... ( I think this is related to the sensors and nothing to do with the NewPing lib ), even after I do multiple reset, it is still not responding and gives a 50,000us ( means reading is invalid )... 

I'll report this issue back to DFRobot for this...
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Neonz on Sep 26, 2012, 08:03 pm
Hello, I have a big problem and I need help. I'm trying to use the Ultrasonic Sensor HC-SR04 to make a project, I have this sensor connected to the arduino via USB and the problem is that i get multiple values of 0cm. For example i mesure 3cm, 4cm, 4cm, 5cm, 0cm,0cm,0cm,0cm, 6cm, 0cm,0cm,0cm, 8cm. I tried with the Newping library and with another library called Ultrasonic but it was the same. Something awkward is that when i use the Ultrasonic Library with the example code, it works great. But when i upload my example the problem starts.

This is my code:

--------------------------------------------

#include <Ultrasonic.h>
const int alarmPin = 7;
const int alarm2Pin = 6;
Ultrasonic ultrasonic(9,8,5000); // (Trig PIN,Echo PIN, Max.TimeOut in µsec )


void setup() {
  Serial.begin(9600);
  pinMode(alarmPin, OUTPUT);
  pinMode(alarm2Pin, OUTPUT);
}

void loop()
{
  if (ultrasonic.Ranging(CM) >= 10)
  {
    digitalWrite(alarmPin, HIGH);
  }
  else
  {
    digitalWrite(alarmPin, LOW);
  }
  if (ultrasonic.Ranging(CM) < 10 && ultrasonic.Ranging(CM) > 5)
  {
    digitalWrite(alarm2Pin, HIGH);
  }
  else
  {
    digitalWrite(alarm2Pin, LOW);
  }
  Serial.print(ultrasonic.Ranging(CM));
  Serial.println(" cm" );
  delay(100);


Thanks for your help, and sry for my grammar.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 28, 2012, 10:18 pm

Hello, I have a big problem and I need help. I'm trying to use the Ultrasonic Sensor HC-SR04 to make a project, I have this sensor connected to the arduino via USB and the problem is that i get multiple values of 0cm. For example i mesure 3cm, 4cm, 4cm, 5cm, 0cm,0cm,0cm,0cm, 6cm, 0cm,0cm,0cm, 8cm. I tried with the Newping library and with another library called Ultrasonic but it was the same. Something awkward is that when i use the Ultrasonic Library with the example code, it works great. But when i upload my example the problem starts.


I can't really help with someone else's library, but I do see why it's not working for you.  Use the following script with my NewPing library and then if there's still a problem I can diagnose it for you:

Code: [Select]

#include <NewPing.h>

#define alarmPin 7
#define alarm2Pin 6

#define TRIGGER_PIN   9  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN      8  // 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 sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

void setup() {
 Serial.begin(9600);
 pinMode(alarmPin, OUTPUT);
 pinMode(alarm2Pin, OUTPUT);
}

void loop() {
 unsigned int cm = sonar.ping_cm(); // Send ping, get ping distance in cm.
  Serial.print(cm);
  Serial.println(" cm");
 if (cm >= 10) {
   digitalWrite(alarmPin, HIGH);
 } else {
   digitalWrite(alarmPin, LOW);
 }
 if (cm < 10 && cm > 5)  {
   digitalWrite(alarm2Pin, HIGH);
 } else {
   digitalWrite(alarm2Pin, LOW);
 }
 delay(100);
}


That script should be a drop-in replacement using NewPing for your defective script.  Let me know what happens.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: basile-laderchi on Oct 11, 2012, 08:45 am
Unfortunately for me, I am using the tone library and wanted to use the NewPing library too.
Do you know any way around the conflict?
It can be also a new tone library (or a modified one) or another way of playing a tone without the usage of the Timer2

TIA,
basile
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Oct 16, 2012, 05:28 pm

Unfortunately for me, I am using the tone library and wanted to use the NewPing library too.
Do you know any way around the conflict?
It can be also a new tone library (or a modified one) or another way of playing a tone without the usage of the Timer2

TIA,
basile


NewPing only uses a timer interrupt when using the  event-driven ping method "ping_timer".  The standard "ping" method as in the example sketch that starts this thread doesn't use any timer interrupts at all.

Do you need to use the event-driven ping method?  Or, do you somehow believe that NewPing always uses a timer interrupt?  If you believe NewPing always uses a timer interrupt, maybe you could explain why you believed this so I can make this more clear to other users.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: basile-laderchi on Oct 17, 2012, 09:18 am
This is part of the sketch I am using:
Code: [Select]
#include <NewPing.h>

NewPing sonar = NewPing(A4, A4, 300);

void setup() {
}

void loop() {
  tone(12, 2999, 3000);
}


When I try to verify the sketch I always get this error:
Code: [Select]
core.a(Tone.cpp.o): In function `__vector_7':
C:\...\arduino-1.0\hardware\arduino\cores\arduino/Tone.cpp:523: multiple definition of `__vector_7'
NewPing\NewPing.cpp.o:C:\...\Documents\Arduino\libraries\NewPing/NewPing.cpp:214: first defined here


Even when I comment out or delete the 3rd line ("NewPing sonar = ...") I still get the same error.

basile

P.S.: I am using a Parallax PING))) sensor on an Arduino UNO board and I think (I am not sure because the test has been performed by a friend) that when it is connected to A4 (as in the example) it doesn't work. Unfortunately right now there are no digital ports available.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: AWOL on Oct 17, 2012, 10:13 am
Quote
This is part of the sketch I am using:

This is part of an answer I am giving: tone.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: basile-laderchi on Oct 17, 2012, 10:27 am

This is part of the sketch I am using:

This is part of an answer I am giving: tone.


That's exactly why I replaced the tone function with this function:
Code: [Select]
void toneWorkaround(byte tonePin, int frequency, int duration) {
  int period = 1000000L / frequency;
  int pulse = period / 2;
  for (long i = 0; i < duration * 1000L; i += period) {
    digitalWrite(tonePin, HIGH);
    delayMicroseconds(pulse);
    digitalWrite(tonePin, LOW);
    delayMicroseconds(pulse);
  }
}


Even after this modification to my code though the Parallax PING))) refuses to work when using the NewPing library.

Right now the Parallax PING))) is working and returning correct values with this code:
Code: [Select]

long ping(byte pingPin) {
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  pinMode(pingPin, INPUT);
  long duration = pulseIn(pingPin, HIGH);
  return duration;
}


basile

P.S.: robot's full code as is right now: http://pastebin.com/jc2sgQ4t
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Oct 17, 2012, 08:01 pm

This is part of the sketch I am using:
Code: [Select]
#include <NewPing.h>

NewPing sonar = NewPing(A4, A4, 300);

void setup() {
}

void loop() {
  tone(12, 2999, 3000);
}


When I try to verify the sketch I always get this error:
Code: [Select]
core.a(Tone.cpp.o): In function `__vector_7':
C:\...\arduino-1.0\hardware\arduino\cores\arduino/Tone.cpp:523: multiple definition of `__vector_7'
NewPing\NewPing.cpp.o:C:\...\Documents\Arduino\libraries\NewPing/NewPing.cpp:214: first defined here


Even when I comment out or delete the 3rd line ("NewPing sonar = ...") I still get the same error.

basile

P.S.: I am using a Parallax PING))) sensor on an Arduino UNO board and I think (I am not sure because the test has been performed by a friend) that when it is connected to A4 (as in the example) it doesn't work. Unfortunately right now there are no digital ports available.


Just comment out line 214, 216, and 217 in NewPing.cpp if you're not using the interrupt method of NewPing.  Commenting out the "NewPing sonar=" line won't help as the library files are loaded via the #include <NewPing.h>

Not sure what can be done to fix this without manually commenting out the lines.  If anyone has any suggestions I'd appreciate it.  At least the solution is very straight-forward and simple.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: caseyd on Oct 23, 2012, 11:17 pm
For this line in the example:
Serial.print(uS / US_ROUNDTRIP_IN); // Convert ping time to distance in cm and print result (0 = outside set distance range)

Is there a way to have "outside distance range" read the MAX_DISTANCE value instead of 0?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Oct 23, 2012, 11:59 pm

For this line in the example:
Serial.print(uS / US_ROUNDTRIP_IN); // Convert ping time to distance in cm and print result (0 = outside set distance range)

Is there a way to have "outside distance range" read the MAX_DISTANCE value instead of 0?


First, that would probably be a bad idea because a value of MAX_DISTANCE would indicate there was something there.  In other words, you wouldn't know if there was actually something exactly at 200cm away or if there was no ping echo if MAX_DISTANCE was set to 200.

With that said, you can easily do what you want.  See the following code snippet:

Code: [Select]

  long uS = sonar.ping();
  if (uS == NO_ECHO) uS = MAX_DISTANCE;
  Serial.print(uS);


Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bassmagnetic on Oct 25, 2012, 04:21 pm
Hi Tim,

I want to use 12 sensors, which is obviously achievable with your code, I have got 6 working really well so far so thank you.... however there are only 12 pins on the arduino uno, so I can only use 6 sensors (obviously 2pins per sensor). I see you can buy a Mux shield to add more inputs. Would this shield work with your code? (I'm very new to code). Would I need to change the code much to make it work? or is there a better / easier option?

Thanks again
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: cyclegadget on Oct 26, 2012, 01:39 am
@ bassmagnetic

Some time in the earlier pages, Tim made it possible to run each sensor from one digital pin, +5, and GND. So, the result is that 12 sensors require 12 digital pins.

Check the examples with his library.


EDIT: his discovery of the one pin method was reported on page 7 of this thread. I am not sure what page the addition was made to the examples.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Oct 26, 2012, 06:54 am

Hi Tim,

I want to use 12 sensors, which is obviously achievable with your code, I have got 6 working really well so far so thank you.... however there are only 12 pins on the arduino uno, so I can only use 6 sensors (obviously 2pins per sensor). I see you can buy a Mux shield to add more inputs. Would this shield work with your code? (I'm very new to code). Would I need to change the code much to make it work? or is there a better / easier option?

Thanks again


cyclegadget is quite right, I've written the NewPing library to work using only one one pin for both trigger and echo.  So, with even the Uno you can connect 12 ping sensors using the NewPing library.  Basically, the library sets the pin to output, initiates the ping, quickly switches the same pin to input, and waits for the ping echo.  The syntax is just to specify the same pin for both trigger and echo.  Below is an example sketch as well as a schematic of how you connect the sensor.  You simply tie the pin to trigger and then jumper trigger to echo.

http://code.google.com/p/arduino-new-ping/wiki/NewPing_Single_Pin_Sketch

Before you rip your project apart and use the one pin method I would suggest doing just one sensor first.  The reason is that for some sensors this one pin technique doesn't work.  If you're using the HC-SR04, you should be good to go.  Others may need a little capacitor instead of the jumper.  I believe I docucmented in the release notes in NewPing.h exactly which sensors worked without the cap and those that needed the cap.  Check the release notes in NewPing.h for details.

Also, I'm always interested to see what multi ping sensor projects people are using with NewPing.  Once you get things working, post a pic.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bassmagnetic on Oct 26, 2012, 01:05 pm
Brilliant, thanks Tim, just tried that and it works fine with 1 sensor, I am using HC-SR04's.... much better than buying more bits!!

Now I just need to figure out how to combine this code with the NewPing15sensor code to make it work with more sensors, any ideas, is it easy to do?

I am needing to increase the number of sensors as I want to make sure that proximately to the speakers does not trigger sounds (so no one goes deaf!)

I am making an installation as part of a final piece for an MA, i'd be happy to send details and photos when its all up and running...

thanks again

andre
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Oct 26, 2012, 05:45 pm

Brilliant, thanks Tim, just tried that and it works fine with 1 sensor, I am using HC-SR04's.... much better than buying more bits!!

Now I just need to figure out how to combine this code with the NewPing15sensor code to make it work with more sensors, any ideas, is it easy to do?

I am needing to increase the number of sensors as I want to make sure that proximately to the speakers does not trigger sounds (so no one goes deaf!)

I am making an installation as part of a final piece for an MA, i'd be happy to send details and photos when its all up and running...

thanks again

andre


Just take the 15 sensor sketch and for each sensor use the same trigger and echo pin.  For example, the first part of your sketch would look something like this:

Code: [Select]

#include <NewPing.h>

#define SONAR_NUM     12 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 0;          // Keeps track of which sensor is active.

NewPing sonar[SONAR_NUM] = {   // Sensor object array.
  NewPing(2, 2, MAX_DISTANCE), // Using same pin for trigger and echo.
  NewPing(3, 3, MAX_DISTANCE),
  NewPing(4, 4, MAX_DISTANCE),
  NewPing(5, 5, MAX_DISTANCE),
  NewPing(6, 6, MAX_DISTANCE),
  NewPing(7, 7, MAX_DISTANCE),
  NewPing(8, 8, MAX_DISTANCE),
  NewPing(9, 9, MAX_DISTANCE),
  NewPing(10, 10, MAX_DISTANCE),
  NewPing(11, 11, MAX_DISTANCE),
  NewPing(12, 12, MAX_DISTANCE),
  NewPing(13, 13, MAX_DISTANCE)
};


Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: basile-laderchi on Oct 30, 2012, 07:43 am
After the substitution of the tone function with the toneWorkaround one and the change of the power supply of the PING))) (attached to A4) to getting it's power from the Arduino everything is working juuuust fine!!!
I am now using the ping_median for the pings just in case there is some interference.

Thanks again for the great library.

basile
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Nov 02, 2012, 02:00 pm

After the substitution of the tone function with the toneWorkaround one and the change of the power supply of the PING))) (attached to A4) to getting it's power from the Arduino everything is working juuuust fine!!!
I am now using the ping_median for the pings just in case there is some interference.

Thanks again for the great library.

basile


Another solution would be to comment out line 214, 216, and 217 in NewPing.cpp if you're not using the interrupt method of NewPing.  You can then use the tone library without conflict.  In my development version, I've created a switch to do this if you're not using the timer interrupt method of NewPing.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Nov 08, 2012, 08:27 pm
I'm getting close to releasing a new version of the NewPing library.  Is anyone having any problems with it or want to suggest something new to add?  It's getting quite mature now so the updates probably won't happen as frequently.

I'm going to test it with the new 32-bit ARM Teensy 3.0 (http://www.pjrc.com/store/teensy3.html) that I got last week.  If someone has the Arduino Due and would like to test NewPing with it, that would be appreciated.  Note, that the timer interrupt methods probably won't work with the new crop of 32-bit Arduinos.  So, all I really care about testing and supporting at this time is the standard ping() method.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: jackryan on Nov 12, 2012, 09:23 am
I've downloaded the v1.5 and tried it in arduino 1.0 but it wont compile. im using a cloned arduino board with atmega8. does it support older boards?

http://www.elab.ph/forum/index.php?topic=6698.0

this is the board im using.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Nov 12, 2012, 11:56 pm

I've downloaded the v1.5 and tried it in arduino 1.0 but it wont compile. im using a cloned arduino board with atmega8. does it support older boards?

http://www.elab.ph/forum/index.php?topic=6698.0

this is the board im using.


I know the timer interrupt methods won't work correctly with the ATmega8 due to the clock rate.  Never had anyone try a ATmega8 to know if it worked or not.  Be sure to start with the basics and try the sample sketch (using the standard ping() method).  If you're still getting compile errors, including them with your reply would be helpful to detect if it's a simple thing or something more complex.  As it stands, without the errors I can't even guess as v1.5 works just fine with Arduino 0023, 1.0, 1.0.1, and 1.0.2.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: amatbrewer on Nov 19, 2012, 04:46 am
First, thanks for the lib! I love it.
Second I will apologize in advance if this has already been asked, but I can't seem to search just this topic so I may have missed it, if it was.

Has any one else experienced an error when attempting to use tone() along with this lib? When I attempt to include tone [e.g. tone(11,1000,20)] I get an error:
core.a(Tone.cpp.o): In function `__vector_7':
C:\Users\Dave\arduino-1.0.1-windows\arduino-1.0.1\hardware\arduino\cores\arduino/Tone.cpp:523: multiple definition of `__vector_7'
NewPing\NewPing.cpp.o:C:\Users\Dave\arduino-1.0.1-windows\arduino-1.0.1\libraries\NewPing/NewPing.cpp:214: first defined here


Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: basile-laderchi on Nov 19, 2012, 08:04 am
Dear amatbrewer,

First, thanks for the lib! I love it.

It is a great lib indeed!


Second I will apologize in advance if this has already been asked, but I can't seem to search just this topic so I may have missed it, if it was.

you did miss it indeed! It's just on the previous page: http://arduino.cc/forum/index.php/topic,106043.msg959928.html#msg959928


Has any one else experienced an error when attempting to use tone() along with this lib?

I had stumbled upon this error just a while ago, and after searching around I found the toneWorkaround function in a book (Arduino Cookbook, page 307). You can find the function I used here: http://arduino.cc/forum/index.php/topic,106043.msg959970.html#msg959970

basile
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: CyklKent on Nov 20, 2012, 01:58 am
I have a HC-SR04 sensor,  a 3.3v capable bluetooth module, and an Arduino Uno r3 (that is it besides spares of all three). I am using 10" jumper wires from the Arduino for power and pins 12 and 13. I am running newping with median(5). I have the HC-SR04 in a fixed position holder aiming at a 3 square inch surface that only moves in one direction directly away from the sensor (from 1" to 78"). This smooth/flat surface is accurately controlled to be square to the sensor for good signal return. With one sensor holder (this one is steel, fairly open air, and lightly holds the sensor around the two barrels) the readings are either perfect or up to 3% bad values (even after median(5) and the stationary object not very far away 15"). The other sensor holder (which is machined plastic, holds the barrels tightly, and encloses the sensor board) might work just as well or might give far more bad values. The erroneous distance values don't seem to be random. They are very similar numbers on a given day (a lot of 9" ±.3 one day, it might be around 3" another day).  The "test bed" is very controlled so I don't have items causing pings one day and not the next.  I bored out the tight fitting holder and hung the sensor in it with spacers to the sensor board 2 mounting holes and I didn't notice any change. I want to use this sensor and I know that this type of distance sensing isn't perfect, but I can't live with the "bad" days of the output. I can't enlarge the surface of the object being measured. I have tried changing all of the hardware with no change. I have tried USB 5v, 9vdc wall warts, and 4 x AA battery packs.  I have slowed the ping rate some. I have been trying to think through the possible problems (I will list some below):
Power pulsing (put a 1uF capacitor across the HC-SR04 Vcc and ground, and possibly across on the Arduino as well?).
Different sensor mounting (I don't know how much direct mechanical vibration problems there are at the receive barrel from the trigger).
Don't use pin13 due to the led.
The Arduino and bluetooth module need to be farther away from the sensor.
Use shielded cable instead of jumper wires.
Interference from something in the room.
Somehow pull the sensor farther back so I am not measuring the first 7" or so.
Maybe change to the HY SRF05 (I kind of doubt this will help).

Do you have any suggestions or do you think these sensors are just "flaky"?
Thank you.




Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Nov 20, 2012, 06:25 pm

Has any one else experienced an error when attempting to use tone() along with this lib? When I attempt to include tone [e.g. tone(11,1000,20)] I get an error:
core.a(Tone.cpp.o): In function `__vector_7':
C:\Users\Dave\arduino-1.0.1-windows\arduino-1.0.1\hardware\arduino\cores\arduino/Tone.cpp:523: multiple definition of `__vector_7'
NewPing\NewPing.cpp.o:C:\Users\Dave\arduino-1.0.1-windows\arduino-1.0.1\libraries\NewPing/NewPing.cpp:214: first defined here



If you're using the ping_timer() method with NewPing, you won't be able to use both the Tone library and NewPing as they both use Timer2.  If, however, you're using just the ping() method in NewPing, you'll be able to use the Tone library.  You'll just need to comment out a few lines in NewPing.cpp to avoid the conflict.  See this message for more details:

http://arduino.cc/forum/index.php/topic,106043.msg960630.html#msg960630

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Nov 20, 2012, 06:40 pm

I have a HC-SR04 sensor,  a 3.3v capable bluetooth module, and an Arduino Uno r3 (that is it besides spares of all three). I am using 10" jumper wires from the Arduino for power and pins 12 and 13. I am running newping with median(5). I have the HC-SR04 in a fixed position holder aiming at a 3 square inch surface that only moves in one direction directly away from the sensor (from 1" to 78"). This smooth/flat surface is accurately controlled to be square to the sensor for good signal return. With one sensor holder (this one is steel, fairly open air, and lightly holds the sensor around the two barrels) the readings are either perfect or up to 3% bad values (even after median(5) and the stationary object not very far away 15"). The other sensor holder (which is machined plastic, holds the barrels tightly, and encloses the sensor board) might work just as well or might give far more bad values. The erroneous distance values don't seem to be random. They are very similar numbers on a given day (a lot of 9" ±.3 one day, it might be around 3" another day).  The "test bed" is very controlled so I don't have items causing pings one day and not the next.  I bored out the tight fitting holder and hung the sensor in it with spacers to the sensor board 2 mounting holes and I didn't notice any change. I want to use this sensor and I know that this type of distance sensing isn't perfect, but I can't live with the "bad" days of the output. I can't enlarge the surface of the object being measured. I have tried changing all of the hardware with no change. I have tried USB 5v, 9vdc wall warts, and 4 x AA battery packs.  I have slowed the ping rate some. I have been trying to think through the possible problems (I will list some below):
Power pulsing (put a 1uF capacitor across the HC-SR04 Vcc and ground, and possibly across on the Arduino as well?).
Different sensor mounting (I don't know how much direct mechanical vibration problems there are at the receive barrel from the trigger).
Don't use pin13 due to the led.
The Arduino and bluetooth module need to be farther away from the sensor.
Use shielded cable instead of jumper wires.
Interference from something in the room.
Somehow pull the sensor farther back so I am not measuring the first 7" or so.
Maybe change to the HY SRF05 (I kind of doubt this will help).

Do you have any suggestions or do you think these sensors are just "flaky"?
Thank you.


Your full sketch and picture of your test jig may shed some light on things.  I have a bunch of sensors, and none have ever had a bad day.  My guess is that there's either a problem in your sketch, you're getting some type of environment noise, or there's something causing an echo reading.  The sketch and picture should lead us in the right direction.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: CyklKent on Nov 20, 2012, 09:36 pm
Thank you for the reply. I will post the code this evening. Here is a picture of the hardware. I am sorry but I can't show the actual set up or the 3in2 object being measured. The red and black wires hanging out from one sensor was temporary to watch on a scope.

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: CyklKent on Nov 21, 2012, 05:32 am
Here is the code that I normally use:
Code: [Select]
#include <NewPing.h>

#define TRIGGER_PIN  12
#define ECHO_PIN     13
#define MAX_DISTANCE 200  // In Centimeters (200cm = 78.7") It will not keep waiting for a return if past this value

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

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

void loop() {
  float uS = sonar.ping_median(5);
  Serial.print(uS / US_ROUNDTRIP_IN);
  Serial.print("a");
}

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Nov 21, 2012, 07:24 pm

Here is the code that I normally use:
Code: [Select]
#include <NewPing.h>

#define TRIGGER_PIN  12
#define ECHO_PIN     13
#define MAX_DISTANCE 200  // In Centimeters (200cm = 78.7") It will not keep waiting for a return if past this value

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

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

void loop() {
  float uS = sonar.ping_median(5);
  Serial.print(uS / US_ROUNDTRIP_IN);
  Serial.print("a");
}




I was hoping to get the picture of your testing jig in the test environment to look for possible echo sources.

But, looking at just your sketch I can see a problem.  Your sketch is sending a ping on top of an old ping, with no pause between.  This won't give reliable results.  What you'll get is possible echos.  You *MUST* wait *AT LEAST* 29ms between pings.  The reason you shouldn't go faster has to do with the sensor hardware and the speed of sound.  The sensors can sense up to around 500cm away (1000cm round-trip).  Speed of sound is around 29uS per cm.  That works out to 29ms.  If you don't wait *AT LEAST* 29ms, you could get an ping echo from a previous ping giving you all kinds of strange results.

While the ping_median() method adds a delay between each ping, it doesn't add a delay before or at the end.  So, the first ping is basically on top of the last ping.  It doesn't add a delay at the end of the ping_median() on purpose, so you can add whatever delay you want, or none at all if it's a one-time only ping.

So, after the sonar.ping_median(5), you need to add a line with something like "delay(29);"

Also, you shouldn't use pin 13 if you're using an Arduino as there's an LED on that pin.  Change that to any other pin to avoid possible conflict.  I stopped using pin 13 in my sample sketches due to a couple users having problems with an LED conflict.  Best to avoid that.

If you still have a problem, I would lengthen the delay between pings to something much larger, say 100ms.  You need to change the delay(29) to delay(100) as well as edit the NewPing.h file and change the PING_MEDIAN_DELAY from 29000 to 100000.  While a ping delay of 29ms should be long enough, if the sensor is too sensitive (say it can sense up to 600cm away, it would need at least a 600*2*29=34800uS [35ms] delay between pings).

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: CyklKent on Nov 21, 2012, 10:27 pm
I thank you for the reply and advice. I did not realize that there was no delay between the last median ping and the next first median ping. I will update like the below (actually, I will probably go with 35 delay in the library and below):
Code: [Select]
#include <NewPing.h>

#define TRIGGER_PIN  12
#define ECHO_PIN     11
#define MAX_DISTANCE 200  // In Centimeters (200cm = 78.7") It will not keep waiting for a return if past this value

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

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

void loop() {
 float uS = sonar.ping_median(5);
 delay(29);
 Serial.print(uS / US_ROUNDTRIP_IN);
 Serial.print("a");
}

I did run with no median and a 200 delay, and I still got some stray distance returns (that are oddly similar in value for a certain test period or day or two). I can live with a certain amount of stray distance returns, but some times it gets real bad. I will run on pin 11. I have gone through fixes that seem to fix the problem, and then I find out days later that the problem is back. Your library gave perfect results for a good while (earlier sketches with and without libraries did give stray values). I found that 3 different 9vdc wall warts gave stray returns, and then laptop or wall plug 5v usb had perfect returns....a month later I couldn't tell the difference between the power inputs. I do see some 60 hz at the sensor with the  9vdc wall warts. I have been wondering if I need a separate power supply for the ultrasonic sensor ( I don't know if there is a ground problem doing that). I think I will solder a 10uF capacitor across the sensor Vcc and ground. There seems to be two 47uF caps on the Arduino for its regulation (the new Arduino Due only has one I just noticed). I am going to do more testing, but I have to admit that I may have to change to a different type of sensor set up. My setup possibly does have echo problems. I may try with single pings every 2 seconds just to try to rule out echos as problems (I have tried with 500 delay before). I also am going to try completely unplugging the bluetooth module and watching the serial printer on the laptop (I usually watch distance values on my tablet via bluetooth).
Thank you again.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: CyklKent on Nov 23, 2012, 05:54 am
Wow, I am full. I want to eat more though XD
The below is what I use when I am wanting to see every ping result for testing (yes, I know that delays are to be avoided (even though Tim just told me I needed to add a delay between medians)).
Code: [Select]
#include <NewPing.h>

#define TRIGGER_PIN  12
#define ECHO_PIN     13
#define MAX_DISTANCE 200

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

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

void loop() {
  float uS = sonar.ping();
  Serial.print(uS / US_ROUNDTRIP_IN);
  Serial.print("a");
  delay(500);
}

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: murphy on Nov 24, 2012, 03:42 pm
Hello.

I have a project with 8 HC-SR04.

My problem is that when I trigger a sensor, the sensor closest are also triggered. I'm not yet used this new library. Can anyone give me an idea how can I do that with this new library?

The project summary is:
8 sensors HC-SR04 each sensor being fired one at a time.

The distance that the sensor is triggered should be between 5 and 15 cm.

Best regards.

murphy

[[|]]'s
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: E40racer on Nov 24, 2012, 05:22 pm

Hello.

I have a project with 8 HC-SR04 sharp sensors.

My problem is that when I trigger a sensor, the sensor closest are also triggered. I'm not yet used this new library. Can anyone give me an idea how can I do that with this new library?

The project summary is:
8 sensors sharp HC-SR04 each sensor being fired one at a time.

The distance that the sensor is triggered should be between 5 and 15 cm.

Best regards.

murphy

[[|]]'s


Sharp sensors? Those are completely different sensor to the HC-SR04.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: murphy on Nov 24, 2012, 07:31 pm
Sorry, is only HC-SR04. I thought they were maded by sharp
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: xvjeko on Nov 24, 2012, 08:12 pm
is it ok to use this:

HC-SR04 -------> > > > >             blank space          < < < < < - ------HC-SR04 sensor 2

is it ok if i limit the max reading range of both sensors to like 50 cm (and i need to read 50 cm), and i place sensors like 200 cm away from each other..
Would this work if each sensor had an independent microcontroller ???
Code: [Select]

delay(STEP_TIME);
  unsigned int uS1 = SONAR_L.ping();
  per_l = uS1 / US_ROUNDTRIP_CM;


Is the blank space enough, or should i use a "sponge" to prevent interference between 2 of the sensors ?????
THX :smiley-mr-green:
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Nov 25, 2012, 05:55 pm

I have a project with 8 HC-SR04.

My problem is that when I trigger a sensor, the sensor closest are also triggered. I'm not yet used this new library. Can anyone give me an idea how can I do that with this new library?

The project summary is:
8 sensors HC-SR04 each sensor being fired one at a time.

The distance that the sensor is triggered should be between 5 and 15 cm.


I have an example sketch that pings 15 sensors that's designed to be scaled to any number of sensors.

http://code.google.com/p/arduino-new-ping/wiki/15_Sensors_Example

Just set SONAR_NUM to 8 and modify the sonar object array to 8 sensors and to the pins tied to each.  This sketch works using the timer method so there's no delays and it will therefore work in many complicated sketches (just do everything triggered from events with no delays).  Also, as NewPing will work using the same pin for both trigger and echo, you only need to use 8 pins to work with all 8 sensors.  So, it's possible that your project would fit on a Uno or Teensy 2.0.  Which is a huge bonus for both price and size.

You shouldn't have any problem getting this example sketch working with your 8 sensors.  And it shouldn't be much of a challenge getting it integrated with your overall project sketch.

I'm going to make another post with tips on using the 15 sensor example sketch as some are having problems understanding how to use an event-driven sketch like this.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Nov 25, 2012, 06:35 pm

is it ok to use this:

HC-SR04 -------> > > > >             blank space          < < < < < - ------HC-SR04 sensor 2

is it ok if i limit the max reading range of both sensors to like 50 cm (and i need to read 50 cm), and i place sensors like 200 cm away from each other..
Would this work if each sensor had an independent microcontroller ???
Code: [Select]

delay(STEP_TIME);
  unsigned int uS1 = SONAR_L.ping();
  per_l = uS1 / US_ROUNDTRIP_CM;


Is the blank space enough, or should i use a "sponge" to prevent interference between 2 of the sensors ?????
THX :smiley-mr-green:


The thing to remember is that setting the maximum distance doesn't change how strong the trigger ping is nor how far the sensor will actually sense a ping.  All it does is just make anything beyond the set distance register as "clear" and the Arduino to stop monitoring that sensor.  The strength of the ping and the ability for a sensor to read a ping up to 500cm away is still there.

There's still a benefit in setting this distance as short as possible for your project.  Especially when using the standard ping() method.  But, don't think of it as changing the way the actual sensor works.

What you always need to consider is that when a sensor does a ping, that ping can echo from around 29 to 35ms.  It doesn't matter what you set the maximum distance to, this is how long a ping could be read by another sensor as a stray echo.

So in your example, it really depends on what the time is between pings.  If the ping to ping time is 100ms, there would be no issue.  If, however, you want to ping both sensors at the exact same time, you could have a problem.

Hope this helps.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: xvjeko on Nov 25, 2012, 06:41 pm


is it ok to use this:

HC-SR04 -------> > > > >             blank space          < < < < < - ------HC-SR04 sensor 2

is it ok if i limit the max reading range of both sensors to like 50 cm (and i need to read 50 cm), and i place sensors like 200 cm away from each other..
Would this work if each sensor had an independent microcontroller ???
Code: [Select]

delay(STEP_TIME);
  unsigned int uS1 = SONAR_L.ping();
  per_l = uS1 / US_ROUNDTRIP_CM;


Is the blank space enough, or should i use a "sponge" to prevent interference between 2 of the sensors ?????
THX :smiley-mr-green:


The thing to remember is that setting the maximum distance doesn't change how strong the trigger ping is nor how far the sensor will actually sense a ping.  All it does is just make anything beyond the set distance register as "clear" and the Arduino to stop monitoring that sensor.  The strength of the ping and the ability for a sensor to read a ping up to 500cm away is still there.

There's still a benefit in setting this distance as short as possible for your project.  Especially when using the standard ping() method.  But, don't think of it as changing the way the actual sensor works.

What you always need to consider is that when a sensor does a ping, that ping can echo from around 29 to 35ms.  It doesn't matter what you set the maximum distance to, this is how long a ping could be read by another sensor as a stray echo.

So in your example, it really depends on what the time is between pings.  If the ping to ping time is 100ms, there would be no issue.  If, however, you want to ping both sensors at the exact same time, you could have a problem.

Hope this helps.

Tim

Thanks for the anwser...
I will solve the problem by syncing them (only one sensor will work at a time, then a short delay, then the second will work etc...)
Title: 15 Sensors Example Sketch Help
Post by: teckel on Nov 25, 2012, 07:46 pm
There's been some confusion about how to use the 15 Sensors Example Sketch (http://code.google.com/p/arduino-new-ping/wiki/15_Sensors_Example).  I've changed some of the comments in the online code to help.  But, I think a post explaining this further would be beneficial.

The 15 Sensors Example Sketch uses the ping_timer() method which is designed for event-driven sketches that don't use delays.  If you're only used to Arduino sketches that are linear and have delays in the code, this concept will be quite foreign to you.  However, it's a good idea to try and embrace an event-driven paradigm.  Simple example "hello world" sketches work fine using delays.  But, once you try to do a complex project, using delays will often result in a project that just doesn't do what you want.  Consider controlling a motorized robot with remote control that balances and using ping sensors to avoid collisions.  Any delay at all, probably even 1 ms, would cause the balancing to fail and therefore your project would never work.  In other words, it's a good idea to start not using delays at all, or you're going to have a really hard time getting your project off the ground (literally with the balancing robot example).

So, it's good to first note that the 15 sensor example doesn't use any delays and is event driven.  You can think of it as multitasking.  The for() loop in void() polls each sensor array waiting for when it's that sensor's time to ping.  If it's time to ping, it triggers a ping_timer() to run in the background.  After the for() loop in void() where the comment is, you could add other code here that doesn't have anything to do with ping sensors.  For example: monitoring other sensors, controlling status lights, or whatever.  But, it's VERY important that these other things are also designed in an event-driven way with no delays.  If you add delays, it will miss ping times and skip them, resulting in what appears to be an error.

echoCheck() is where the background ping is polled every 24uS to see if a ping was received. If a ping is received, it sets the ping distance in CM in the cm[] array.  You shouldn't add anything to echoCheck() to use this sketch in its designed way.  This function always needs to be very lean as it's called every 24uS during a ping.

oneSensorCycle() is called once all of your sensors have been polled.  Lets say you have 8 sensors.  Every time all 8 sensors are pinged, this function is called and you can do something with the results.  For example, determine the surroundings of your robot and maybe make a motor direction change.  It doesn't have to output the results over a serial connection, this is just here for testing.  In a real-world sketch, you would remove or comment out everything in the oneSensorCycle() function and replace it with your code that does something with the sensor data in the cm[] array.

Also note, the 15 Sensors Example Sketch is designed to ping all the sensors and then do something with the results once all the sensors have been polled.  Some want to ping each sensor and then do something right away maybe between any two pings.  To do that, we no longer need the oneSensorCycle() function nor the if() statement in loop() that calls oneSensorCycle().  The following sketch calls the pingResult() function every time there's a ping within range.  Because this sketch still keeps the cm[] array, you can look at neighboring ping results in the cm[] array to do whatever calculations you need to do.

Code: [Select]
#include <NewPing.h>

#define SONAR_NUM      3 // Number of sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 0;          // Keeps track of which sensor is active.

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

void setup() {
 Serial.begin(115200);
 pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
 for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
   pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void loop() {
 for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
   if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
     pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
     sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
     currentSensor = i;                          // Sensor being accessed.
     cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
     sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
   }
 }
 // Other code that *DOESN'T* analyze ping results can go here.
}

void echoCheck() { // If ping received, set the sensor distance to array.
 if (sonar[currentSensor].check_timer()) {
   cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
   pingResult(currentSensor);
 }
}

void pingResult(uint8_t sensor) { // Sensor got a ping, do something with the result.
 // The following code would be replaced with your code that does something with the ping result.
 Serial.print(sensor);
 Serial.print(" ");
 Serial.print(cm[sensor]);
 Serial.println("cm");
}


If, however, you don't really care about comparing neighboring ping results and just want to ping multiple sensors and anytime there's something within range you want to trigger something, you can totally get rid of the cm[] array.  The following code is probably the easiest to understand, as it simply pings each sensor and when there's a ping within range, the pingResult() function is called.  You get the sensor number and the cm distance which you can do something with.  It will only call pingResult() when one of the sensors "hears" something within range.

Code: [Select]
#include <NewPing.h>

#define SONAR_NUM      3
#define MAX_DISTANCE 200
#define PING_INTERVAL 33

unsigned long pingTimer[SONAR_NUM];
uint8_t currentSensor = 0;

NewPing sonar[SONAR_NUM] = {
 NewPing(4, 5, MAX_DISTANCE),
 NewPing(6, 7, MAX_DISTANCE),
 NewPing(8, 9, MAX_DISTANCE)
};

void setup() {
 Serial.begin(115200);
 pingTimer[0] = millis() + 75;
 for (uint8_t i = 1; i < SONAR_NUM; i++)
   pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void loop() {
 for (uint8_t i = 0; i < SONAR_NUM; i++) {
   if (millis() >= pingTimer[i]) {
     pingTimer[i] += 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");
}


Remember, to analyze the ping results, you do that in the pingResults() function in the above sketches or in the oneSensorCycle() function in the 15 Sensors Example Sketch.  Also, none of these will properly work if you do any delay statements at any point in your sketch.  

If you ever want to stop the pings in your sketch, for example to do something that requires delays or takes longer than 33ms to process, do the following:
Code: [Select]

for (uint8_t i = 0; i < SONAR_NUM; i++) pingTimer[i] = -1;


To start the pings again, do the following:
Code: [Select]

pingTimer[0] = millis();
for (uint8_t i = 1; i < SONAR_NUM; i++) pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;


Hope this helps!  Future questions about using the 15 Sensors Example Sketch will be directed to this post first in the hope this will explain things better.  I can see some additions/corrections in the future to further clarify.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bulut on Dec 06, 2012, 02:38 am
I've bought a chinese "reverse gear obstacle detector for cars" ultrasonic sensor and the board , i checked the board and find the trigger and echo pins for sensor like SR04 , but this sensor has a different specifications from SR04 , i want to use this new ping library for measuring the distance  with arduino and this sensor, i am not sure witch parts of the code i have to change to work with my sensor , here is the specification of the sensor i got:

center frequency : 40KHZ  (i checked the input pulse on the board with osciloscope it is 16 bursts)
Ringing : 1.2ms max
maximum input voltage : 120 Vp-p
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 06, 2012, 04:21 pm

I've bought a chinese "reverse gear obstacle detector for cars" ultrasonic sensor and the board , i checked the board and find the trigger and echo pins for sensor like SR04 , but this sensor has a different specifications from SR04 , i want to use this new ping library for measuring the distance  with arduino and this sensor, i am not sure witch parts of the code i have to change to work with my sensor , here is the specification of the sensor i got:

center frequency : 40KHZ  (i checked the input pulse on the board with osciloscope it is 16 bursts)
Ringing : 1.2ms max
maximum input voltage : 120 Vp-p



Have you tried connecting it and using the sample NewPing sketch?  By the pin labels, it sounds like it could work as-is.  The 120V is a little confusing, but the specs seems a little thin to begin with.  Got a picture or more information?

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bulut on Dec 07, 2012, 03:02 am


Have you tried connecting it and using the sample NewPing sketch?  By the pin labels, it sounds like it could work as-is.  The 120V is a little confusing, but the specs seems a little thin to begin with.  Got a picture or more information?

Tim
[/quote]

i tried simple new ping sketch but it just reads up to 40cm and not so much accurate , in you sketch the ping pulse is 1 pulse with 10us width i think if we manipulate the code to 2 or 3 pulses with 16us width it will solve my problem,and i think we have to increase the frequency too.how should we change the code?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bulut on Dec 07, 2012, 10:53 am
i think we have to change this part of code
Code: [Select]
*_triggerOutput &= ~_triggerBit; // Set the trigger pin low, should already be low, but this will make sure it is.
delayMicroseconds(4);            // Wait for pin to go low, testing shows it needs 4uS to work every time.
*_triggerOutput |= _triggerBit;  // Set trigger pin high, this tells the sensor to send out a ping.
delayMicroseconds(10);           // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS.
*_triggerOutput &= ~_triggerBit; // Set trigger pin back to low.


i need 16 bursts with period of 21us  and frequency of 40KHZ for my trigger , how should i change the code?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 08, 2012, 12:41 am

i tried simple new ping sketch but it just reads up to 40cm and not so much accurate , in you sketch the ping pulse is 1 pulse with 10us width i think if we manipulate the code to 2 or 3 pulses with 16us width it will solve my problem,and i think we have to increase the frequency too.how should we change the code?


The 1 pulse / 10uS width is just to trigger the sensor.  The sensor detects this and then sends out it's own multiple pulses.  In other words, the sensor doesn't just send out one 10uS pulse, we just trigger it.  I have not seen a sensor that doesn't automatically send out multiple pulses from a trigger.  Are you sure it's not ready doing this?  The fact that it reads distances appears that it's working.  Do you even know the maximum sensor distance?  Maybe it's only 40cm.  Also, you may need to change the uS to CM conversion if your sensor puts out different values.  The URM37 sensor is a good example of this.   For the URM37 you set US_ROUNDTRIP_CM to 50, as that's how it converts and outputs the distance values.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: CyklKent on Dec 08, 2012, 01:28 am
Do your sensors look like these?:

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bulut on Dec 08, 2012, 12:55 pm

Quote
The 1 pulse / 10uS width is just to trigger the sensor.  The sensor detects this and then sends out it's own multiple pulses.  In other words, the sensor doesn't just send out one 10uS pulse, we just trigger it.  I have not seen a sensor that doesn't automatically send out multiple pulses from a trigger.

i know it how the sensor works but this sensor dosnt operate with 1 pulse / 10 us it works with 16 pulses with period of 21us  and frequency of 40KHZ if i can apply this to my sensor it will work, now i just want to know how should i produce this 16 pulses(40KHZ)

Quote
Do you even know the maximum sensor distance?  Maybe it's only 40cm


the maximum is 5 meter , it reads 40cm but not accurate it has 13cm error.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bulut on Dec 08, 2012, 12:57 pm

Do your sensors look like these?:



exactly the same
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 10, 2012, 04:16 pm


Do your sensors look like these?:



exactly the same


So, you're trying to use just the sensor without the control board?  Many people have tried doing this and I have yet to hear of anyone who was successful.  The same is true with the typical HC-SR04 type sensors.  You can't just use the sensors without the control board.

Basically, if you want to use these sensors, you're going to need to interface with the control board, not the sensors directly.  It's not something that can be fixed with software.  You need hardware to amplify the signals, issue the pings, etc.  You can't just connect them to an Arduino, they won't work that way.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bulut on Dec 11, 2012, 07:33 am

Quote
So, you're trying to use just the sensor without the control board?


no i am not trying to use the sensor without the board , in my first post i noted that i am using the sensor board . i know if i connect the sensor directly to the arduino it wont work.

Quote
It's not something that can be fixed with software

believe me if we apply the 16 pulses with 21us period with 40KHZ frequency i will be work i am sure, so please tell me how to change the code to produce this pulses .

Quote
You need hardware to amplify the signals

the sensor board has the amplifyer inside.

check the pictures

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 11, 2012, 06:20 pm

believe me if we apply the 16 pulses with 21us period with 40KHZ frequency i will be work i am sure, so please tell me how to change the code to produce this pulses .


The NewPing library doesn't do the ultrasonic pulses.  It only triggers the control board which does the pulses.  It's very odd that this control board doesn't do these pulses (that's one of the duties of the control board). I've never heard of a control board that doesn't do the required pulses that the control board's decoder requires.  It only makes sense that the control board would issue the correct pulses that it needs on the decode side.  It could be how you're doing the ping trigger.  Maybe you're not doing the trigger, but actually just a single fire?  In other words, maybe you're connecting to the wrong place on the control board.

In any case, doing these pulses is outside the scope of the NewPing library as it would drastically change things and be specific to one individual control board.

What you'll need to do is create your own control function or library.  In order to do the pulses with accuracy, you'll need to look into PWM.  I don't think the standard Arduino PWM will work as you need to set a frequency of around 47 kHz (21uS) while the maximum Arduino PWM is 1 kHz.  Using timers you can get as high as 64 kHz, but I believe the next step would be 32 kHz so you could still have a problem.

I'd really try to get the control board to do the correct pulses (that's its job anyway).  If you can't, try looking for PWM library that can do high frequency pulses.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: vsodhani on Dec 28, 2012, 12:23 am
I am using the new Ping library with my code and have hit a dead end.  My code is running a SparkFun stepper motor in a loop where it slowly increments the RPM.  I eventually want to control the speed based on the distance measurement from my Ping((( sensor, but I've dumbed it down to find the error.  It's not the best code for my  motor, but for example sake it works.  The problem is that even though I use the ping_timer like in the example calling:

sonar.ping_timer(echoCheck);

stops the motor from moving.  once I comment that line out the motor starts working again.  below is the code.  any ideas?
Code: [Select]

#include <NewPing.h>
#include <AFMotor.h>


#define TRIGGER_PIN  7  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     7  // 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.

AF_Stepper motor(200, 1);
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
unsigned int pingSpeed = 1000; // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer;     // Holds the next ping time.
int rpm =10;

void setup(){
  Serial.begin(115200);
  pingTimer = millis(); // Start now.
 
  Serial.println("Stepper test!");
  motor.setSpeed(100);  // 100 rpm   
  motor.step(100, FORWARD, SINGLE);
  Serial.println("step done");
  motor.release();
  delay(1000);
 
}

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.
    sonar.ping_timer(echoCheck); // Send out the ping, calls "echoCheck" function every 24uS where you can check the ping status.
  }
 
 
  Serial.print("setting RMP = ");
  Serial.println(rpm);
  motor.setSpeed(rpm);
  Serial.println();
  Serial.println();
  motor.step(100, FORWARD, SINGLE);
  rpm = rpm +10;
  delay(1000);
}
  void echoCheck() { // Timer2 interrupt calls this function every 24uS where you can check the ping status.
  // Don't do anything here!
  if (sonar.check_timer()) { // This is how you check to see if the ping was received.
    // Here's where you can add code.
    Serial.print("Ping: ");
    Serial.print(sonar.ping_result / US_ROUNDTRIP_CM); // Ping returned, uS result in ping_result, convert to cm with US_ROUNDTRIP_CM.
    Serial.println("cm");
  }
 
 
}

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: cyclegadget on Dec 28, 2012, 01:17 am
I think this part of the code is incorrect. It will always check as true. That is all that I have found at the moment.

Code: [Select]
if (millis() >= pingTimer) {   // pingSpeed milliseconds since last ping, do another ping.
    pingTimer += pingSpeed;      // Set the next ping time.
    sonar.ping_timer(echoCheck); // Send out the ping, calls "echoCheck" function every 24uS where you can check the ping status.
  }


Take a look at the blink without delay example.
Code: [Select]
unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis; 
   
   
    // run function here
   
  }
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: vsodhani on Dec 28, 2012, 06:31 am
that code was taken straight from the NewPingEventTimer example code, and as far as I can tell should not always be true.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 28, 2012, 06:35 am

I am using the new Ping library with my code and have hit a dead end.  My code is running a SparkFun stepper motor in a loop where it slowly increments the RPM.  I eventually want to control the speed based on the distance measurement from my Ping((( sensor, but I've dumbed it down to find the error.  It's not the best code for my  motor, but for example sake it works.  The problem is that even though I use the ping_timer like in the example calling:

sonar.ping_timer(echoCheck);

stops the motor from moving.  once I comment that line out the motor starts working again.  below is the code.  any ideas?


I'd start debugging this by removing the Serial.print/Serial.println stuff inside the echoCheck subroutine.  This is only there for a test, you should eventually replace it with code that processes the ping result.  But for now you can simply delete it.  If it still doesn't work correctly, it could be that the AFMotor library is also using the same timer that NewPing is using to do the stepper motor control.

Also, cyclegadget is correct, you're not really using the pingTimer correctly.  Both ping_timer() and the pingTimer variable are designed to be used WITHOUT delays.  If you're using delays, it's going to not work correctly.

Basically, if you're going to use delays, you should not use any of the polling (pingTimer) stuff and shouldn't use the ping_timer() method.  You should just use the standard ping() method.  If you want to create a more event driven sketch, you need to be comfortable with not using delay commands.

I simplified your sketch and used the standard ping() method (well, ping_cm() which is ping that converts the result to centimeters).  This may make more sense and be a closer fit to what you're trying to do.

Code: [Select]
#include <NewPing.h>
#include <AFMotor.h>

AF_Stepper motor(200, 1);
NewPing sonar(7, 7, 200); // NewPing setup of pins and maximum distance.
int rpm = 10;

void setup(){
 Serial.begin(115200);
 Serial.println("Stepper test!");
 motor.setSpeed(100);  // 100 rpm  
 motor.step(100, FORWARD, SINGLE);
 Serial.println("step done");
 motor.release();
 delay(1000);
}

void loop(){
 int cm = sonar.ping_cm();
 Serial.print(cm);
 Serial.println(" cm");
 
 Serial.print("setting RMP = ");
 Serial.println(rpm);
 motor.setSpeed(rpm);
 Serial.println();
 Serial.println();
 motor.step(100, FORWARD, SINGLE);
 rpm += 10;
 delay(1000);
}
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 28, 2012, 06:39 am

that code was taken straight from the NewPingEventTimer example code, and as far as I can tell should not always be true.


It is always true, because you're adding delays and telling it to start right away, yet then adding a full second delay.  Basically, you need to either create an event driven/polling type sketch, or one with delays.  Combining the two could give you problems.

It doesn't seem you're comfortable with an event driven/polling type sketch.  So, you shouldn't really try to use any example NewPing sketch that uses the ping_timer() method.  Stick with ping(), ping_cm(), ping_in(), and ping_median() till you're comfortable with not using the delay() command in your sketch.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: vsodhani on Dec 29, 2012, 03:00 am
hi teckel & cyclegadget,

thank you for your response.  i am new to events.  so i tried taking out all the delays and also tried calling the ping function directly but i had the same results.  i'm going to look into the adafruit motor library to see if it is using the timer as the new ping library.

thanks again!  i'll report back.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: cyclegadget on Dec 29, 2012, 04:52 am

@hbaxton

Take a look at this sketch. I reworked your sketch and put the motor running part into a function then, made it work with blink without delay style. It is untested but, I think it will work.

Code: [Select]
#include <NewPing.h>
#include <AFMotor.h>


#define TRIGGER_PIN  7  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     7  // 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.

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

unsigned int pingSpeed = 1000;  // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer;        // Holds the next ping time.
unsigned long motorTimer;       // Holds the place for motor speed adjusts
unsigned int adjustTime = 1000; // how often to adjust the speed of the motor
int rpm =10;

void setup(){
  Serial.begin(115200);
  pingTimer = millis(); // Start now.

  Serial.println("Stepper test!");
  motor.setSpeed(100);  // 100 rpm   
  motor.step(100, FORWARD, SINGLE);
  Serial.println("step done");
  motor.release();
  delay(1000);
}

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 = millis() + pingSpeed;      // Set the next ping time.
    sonar.ping_timer(echoCheck); // Send out the ping, calls "echoCheck" function every 24uS where you can check the ping status.
  }

////////////////////////////////////////Here is the new part that will run your motor on a timer
  if (millis() >= motorTimer)
  {
    motorrun();
    motorTimer = millis() + adjustTime;
  }
}

void motorrun()
{ // this is the function that will run your motor when called
  Serial.print("setting RMP = ");
  Serial.println(rpm);
  motor.setSpeed(rpm);
  Serial.println();
  Serial.println();
  motor.step(100, FORWARD, SINGLE);
  rpm = rpm +10;
}


void echoCheck() { // Timer2 interrupt calls this function every 24uS where you can check the ping status.
  // Don't do anything here!
  if (sonar.check_timer()) { // This is how you check to see if the ping was received.
    // Here's where you can add code.
    Serial.print("Ping: ");
    Serial.print(sonar.ping_result / US_ROUNDTRIP_CM); // Ping returned, uS result in ping_result, convert to cm with US_ROUNDTRIP_CM.
    Serial.println("cm");
  } 
}
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 29, 2012, 07:23 am

hi teckel & cyclegadget,

thank you for your response.  i am new to events.  so i tried taking out all the delays and also tried calling the ping function directly but i had the same results.  i'm going to look into the adafruit motor library to see if it is using the timer as the new ping library.

thanks again!  i'll report back.


You can't just remove the delays and expect it to work as then you'll have other problems.  Instead, try using the replacement sketch I provided in a previous post that includes delays, but does so correctly.  Your sketch was a hybrid, but used bad logic.  To simplify things for you, my sketch does it the standard way, with the ping() method and delays.  This is how you should use NewPing unless you know what you're doing and know how to write event-driven sketches.  I do highly suggest that you learn this programming paradigm as you'll have a hard time graduating beyond "hello world" tests otherwise.  But, maybe try something simple at first.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: xvjeko on Jan 02, 2013, 07:26 pm
Hello.. i wrote a code that uses this library, and isn't 100% reliable when debugging...
I'd be grateful if you comment it.
Code: [Select]

#include <NewPing.h>

#define BAUD 9600
#define MIN_DISTANCE 6      //Minimum distance to ping (cm)
#define MAX_DISTANCE 60     //Maximum distance to ping (cm)
#define THRESHOLD 10        //Treshold (cm)
#define HOLD_TIME 15        //Delay between each step (ms)
#define STEP_TIME 33        //Delay between ultrasonic's

//Creating ultrasonic objects
NewPing SONAR_L(TRIG_PIN_L, ECHO_PIN_L, 2000);
NewPing SONAR_R(TRIG_PIN_R, ECHO_PIN_R, 2000);

//Creating debugg function
void debugg(int val_l, int val_r)
{
 Serial.print(val_l);
 Serial.print(" ");
 Serial.print(val_r);
 Serial.println();
}

//Creating setup function
void setup()
{
 Serial.begin(BAUD);
 
 pinMode(ECHO_PIN_L, INPUT);
 pinMode(ECHO_PIN_R, INPUT);
 pinMode(TRIG_PIN_L, OUTPUT);
 pinMode(TRIG_PIN_R, OUTPUT);
}

//Program
void loop()
{
 //Declaring local static variables
 static bool hold = false;
 static int val_l, val_r;
 static int per_l, per_r;
 static int prev_per_l = MIN_DISTANCE, prev_per_r = MIN_DISTANCE;

 //Reading ultrasonic values
 delay(STEP_TIME);
 unsigned int uS1 = SONAR_L.ping();
 per_l = uS1 / US_ROUNDTRIP_CM;
 
 delay(STEP_TIME);
 unsigned int uS2 = SONAR_R.ping();
 per_r = uS2 / US_ROUNDTRIP_CM;
 
 //Limiting the effective range of ultrasonics
 per_l = constrain(per_l, MIN_DISTANCE, MAX_DISTANCE);
 per_r = constrain(per_r, MIN_DISTANCE, MAX_DISTANCE);
 
 //This part of code is used to save the distance of ultrasonic sensors
 //when the hand is moved away from the beam ) ) ) of the sensor
 if( (per_l - prev_per_l) > THRESHOLD )
 {
   per_l = prev_per_l;
   hold=false;
 }

 if( (per_r - prev_per_r) > THRESHOLD )
 {
   per_r = prev_per_r;
   hold=false;
 }
 
 prev_per_l = per_l;
 prev_per_r = per_r;

 //Modifying the data using linear math (used for servo motors)
 per_l = map(per_l, MIN_DISTANCE, MAX_DISTANCE, 100, 0);

 val_l = map(per_r, MIN_DISTANCE, MAX_DISTANCE, 90, 0);
 val_r = map(per_r, MIN_DISTANCE, MAX_DISTANCE, 0, 90);
 
 val_l = val_l * (per_l / 100.0);
 val_r = val_r * (per_l / 100.0);

 //Writing final data to servo motors
 servo_l.write(val_l);
 servo_r.write(val_r);
 
 //Debugging the final data
 debugg(val_l, val_r);

 //Applying the final delay (due to servo speed characteristics)
 hold=true;
 if(hold==true) delay(HOLD_TIME);
}
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 02, 2013, 08:19 pm

Hello.. i wrote a code that uses this library, and isn't 100% reliable when debugging...
I'd be grateful if you comment it.


1) TRIG_PIN_L, TRIG_PIN_R, ECHO_PIN_L and ECHO_PIN_R are never defined.
2) No reason to set the pin modes, NewPing does that for you.
3) You shouldn't set the maximum distance to 2000cm on the "NewPing SONAR" lines.  The sensor won't work beyond 500cm and setting it to 2000 could make the time between pings from 33ms to 115ms or just cause problems in general.  Just remove the ,2000 and it will default to the sensor's maximum distance, which is 500cm and will allow for 33ms between pings as you have it set.
4) The "constrain" commands will give you problems as out of range results (which are zero) would change to 6.  Out of range would typically be beyond 500cm, making it 6cm will probably not give what you're looking for.  Instead, do something like "if (per_l > 0) per_l = constrain(per_l, MIN_DISTANCE, MAX_DISTANCE);" so there can still be a zero result (out of range).
5) The rest of your code then needs to accommodate what to do with out of range results.  It doesn't appear that you have considered that.  If anything, a zero result should be changed to MAX_DISTANCE + 1, as that's what it means.  Without considering a zero result (out of range), your sketch will probably never work.

That should give you a good start to diagnose what's going on.  1, 3, 4 & 5 are real problems that will seriously cause problems for your sketch.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: xvjeko on Jan 02, 2013, 08:40 pm


Hello.. i wrote a code that uses this library, and isn't 100% reliable when debugging...
I'd be grateful if you comment it.


1) TRIG_PIN_L, TRIG_PIN_R, ECHO_PIN_L and ECHO_PIN_R are never defined.
2) No reason to set the pin modes, NewPing does that for you.
3) You shouldn't set the maximum distance to 2000cm on the "NewPing SONAR" lines.  The sensor won't work beyond 500cm and setting it to 2000 could make the time between pings from 33ms to 115ms or just cause problems in general.  Just remove the ,2000 and it will default to the sensor's maximum distance, which is 500cm and will allow for 33ms between pings as you have it set.
4) The "constrain" commands will give you problems as out of range results (which are zero) would change to 6.  Out of range would typically be beyond 500cm, making it 6cm will probably not give you want you're looking for.  Instead, do something like "if (per_l > 0) per_l = constrain(per_l, MIN_DISTANCE, MAX_DISTANCE);" so there can still be a zero result (out of range).
5) The rest of your code then needs to accommodate what to do with out of range results.  It doesn't appear that you have considered that.  If anything, a zero result should be changed to MAX_DISTANCE + 1, as that's what it means.  Without considering a zero result (out of range), your sketch will probably never work.

That should give you a good start to diagnose what's going on.  1, 3, 4 & 5 are real problems that will seriously cause problems for your sketch.

Tim


thank you sir

EDIT: I got everything to work now... I hope it will run flawlessly in the real life... Thanks again
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 04, 2013, 05:51 am

thank you sir

EDIT: I got everything to work now... I hope it will run flawlessly in the real life... Thanks again


Glad to help!  Always satisfying when a project starts to come together.  Pictures of your final project are always appreciated by the community.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: matt121187 on Jan 04, 2013, 07:22 pm
hello..im using ultrasonic parallax ping))) sensor.can someone share to me coding for velocity (speed) sensor?  km/h

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 04, 2013, 09:56 pm

hello..im using ultrasonic parallax ping))) sensor.can someone share to me coding for velocity (speed) sensor?  km/h


What's the size and speed of the object you're trying to track the speed of?  Will the object always be heading straight for the sensor or at an angle?  If at an angle, is the angle consistent and known?

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: matt121187 on Jan 05, 2013, 05:26 am


hello..im using ultrasonic parallax ping))) sensor.can someone share to me coding for velocity (speed) sensor?  km/h


What's the size and speed of the object you're trying to track the speed of?  Will the object always be heading straight for the sensor or at an angle?  If at an angle, is the angle consistent and known?

Tim


between two cars..im doing the fyp project..doing the car blind spot detection..this sensor put at the side of the car..then this sensor will measure the distance and speed between  my car and side car. actually, for the speed, im not measure the speed of the side car but im measure the different speed between my car and side car..(i think this very simple compare to  measure the speed of the side car)
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: matt121187 on Jan 05, 2013, 01:44 pm
can someone help me... =(
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: cyclegadget on Jan 05, 2013, 06:22 pm

can someone help me... =(


First step, make Arduino work with basic code for NewPing.

After you understand how the sketch works you can use variables to calculate speed.

Quoted from this link http://www.unitarium.com/speed-calculator

Quote
Assume, V - stands for average speed (velocity), T - stands for traveling time and D - stands for traveled distance.

Average Speed can be calculated by using the formula: V = D/T
Traveled distance can be calculated as: D = V*T
Traveling time can be calculated using: T = D/V

Using the formulas remember about the units. For example, if the distance is given in meters and the time is given in seconds, calculated average speed is given in meters per second.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: matt121187 on Jan 05, 2013, 06:48 pm


can someone help me... =(


First step, make Arduino work with basic code for NewPing.

After you understand how the sketch works you can use variables to calculate speed.

Quoted from this link http://www.unitarium.com/speed-calculator

Quote
Assume, V - stands for average speed (velocity), T - stands for traveling time and D - stands for traveled distance.

Average Speed can be calculated by using the formula: V = D/T
Traveled distance can be calculated as: D = V*T
Traveling time can be calculated using: T = D/V

Using the formulas remember about the units. For example, if the distance is given in meters and the time is given in seconds, calculated average speed is given in meters per second.



sorry, im new with arduino..what do u mean by " First step, make Arduino work with basic code for NewPing."? from the ping sensor coding, i can get the distance, but how to get the value of times?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: cyclegadget on Jan 05, 2013, 08:22 pm
Quote
Assume, V - stands for average speed (velocity), T - stands for traveling time and D - stands for traveled distance.

Average Speed can be calculated by using the formula: V = D/T
Traveled distance can be calculated as: D = V*T
Traveling time can be calculated using: T = D/V


You may want to start a thread in the programming questions area for your project. Below, is some help to get you started.
You have a sensor that can provide distance information. This is your "D" variable.

You can use millis() or micros() to measure your time between distance checks. This is your "T" variable. FirstMillis() - SecondMillis() = time between distance checks.

V = D/T......."V" velocity, = "D" distance / "T" time.

Before you ask more questions, you need to read this thread so that you will get the best help possible. http://arduino.cc/forum/index.php/topic,97455.0.html

Good luck, your project is easily possible but, you need to put in some time to make it happen.

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 07, 2013, 12:08 am
sorry, im new with arduino..what do u mean by " First step, make Arduino work with basic code for NewPing."? from the ping sensor coding, i can get the distance, but how to get the value of times?


You create a time stamp for each ping.  Then, looking at multiple ping times, and the comparison to the ping time stamp, you can easily calculate the speed (also if it's getting closer or further away).  For example, you have two pings like the following:

Ping 1: Timestamp 50,000uS - Ping time 8,000uS
Ping 2: Timestamp 100,000uS - Ping time 7,000uS

So, two pings that are 50ms apart, the first distance is 8000uS (140cm), sencond ping is 7,000uS (123cm).  So, in 50ms, it got 17cm closer (140-123).  17cm/50ms = .17/0.05 m/s or 3.4 m/s or 7.6 miles/hour.

Only the previous and current ping timestamp and distance are needed.  If you use scheduled polling so you always know exactly how far apart each ping is (for example, exactly 50,000uS) then you don't even need to know the timestamp, just the current and previous ping distance.  Just don't use delay(50) to make them 50ms apart, that won't be accurate.  You'll need to either use an interrupt timer or polling to keep things accurate.  Interrupt timer would be ideal but more complicated unless you used a timer library would would greatly simplify things.

I've written a little sketch for you that uses the NewPing and TimerOne library that outputs the speed via serial and uses the timer interrupt to make the ping timing very accurate.  I added lots of comments so you should be able to follow along.  Speed values are in meters per second, with positive values coming at you and negative moving away.  Anyway, here's the sketch:

Code: [Select]
#include <TimerOne.h>
#include <NewPing.h>

#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.

NewPing sonar(TRIGGER_PIN, ECHO_PIN); // NewPing setup of pins.

volatile int previous = 0, current = 0; // Must be volatile because these change inside the interrupt code.
volatile float mps = 0.0;
volatile boolean newping = false;

void setup() {
 delay(1000);                        // Wait a second before we start.
 Timer1.initialize(50000);           // 50000uS = 50ms.
 Timer1.attachInterrupt(pingSensor); // pingSensor to run every 50ms.
 Serial.begin(115200);               // Open serial monitor at 115200 baud to see ping results.
}

void loop() {
 if (newping) { // There a new ping, print speed.
   /* START - This section would be replaced with code that would do something with the result other than just output to serial. */
   if (mps) {   // Non-zero speed, show result.
     Serial.print(mps);
     Serial.println(" m/s");
   } else Serial.println("-"); // Can't determine speed, output "-" instead of speed.
   /* END */
   newping = false; // Set to false till next ping.
 }
}

void pingSensor() {
 previous = current;
 current = sonar.ping_cm(); // Send out a ping and get the results in CM.
 if (previous && current) { // If either are zero, we had a no-ping result or on the first ping.
   mps = (float) (previous - current) * 0.2; // Calculate speed in m/s (positive values are coming at you, negative moving away).
 } else mps = 0; // Can't calculate speed.
 newping = true; // Flag that there's a new ping.
}


Hope this helps!

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: dbustillo on Jan 07, 2013, 04:40 am
Hi,

First of all THANK YOU TIM for this library!!!!!!!!!!!!!!!!!!!!
And thank you to all the enthusiasts who have been posting here!

I have been running into a slight problem that I have not been able to fix, despite dowloading the lib again, googling it a million times, etc. I am trying to get readings from a PING))) sensor and from a maxbotic MAX SONAR (which can be PWM, An or BW, I have it as PWM) and arduino throws the same error:
'NewPing' does not name a type

sketch_jan06a:3: error: 'NewPing' does not name a type
sketch_jan06a:4: error: 'NewPing' does not name a type
sketch_jan06a.cpp: In function 'void loop()':
sketch_jan06a:19: error: 'sonar1' was not declared in this scope
sketch_jan06a:23: error: 'sonar2' was not declared in this scope

The code I used is the modified sample one provided:
Code: [Select]
#include <NewPing.h>
//barely modified sketch from Tim Eckel's original sketch

NewPing sonar1(11, 12, 200); // Sensor 1: trigger pin, echo pin, maximum distance in cm
NewPing sonar2(9, 10, 200); // Sensor 2: same stuff

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

void setup() {
  Serial.begin(9600);
  // Do other stuff here
  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
  }
  // Do other stuff here, notice how there's no delays in this sketch, so you have processing cycles to do other things :)
}


Any suggestions would be greatly greatly appreciated..... Thank you!!!!!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: matt121187 on Jan 07, 2013, 08:35 am

sorry, im new with arduino..what do u mean by " First step, make Arduino work with basic code for NewPing."? from the ping sensor coding, i can get the distance, but how to get the value of times?


You create a time stamp for each ping.  Then, looking at multiple ping times, and the comparison to the ping time stamp, you can easily calculate the speed (also if it's getting closer or further away).  For example, you have two pings like the following:

Ping 1: Timestamp 50,000uS - Ping time 8,000uS
Ping 2: Timestamp 100,000uS - Ping time 7,000uS

So, two pings that are 50ms apart, the first distance is 8000uS (140cm), sencond ping is 7,000uS (123cm).  So, in 50ms, it got 17cm closer (140-123).  17cm/50ms = .17/0.05 m/s or 3.4 m/s or 7.6 miles/hour.

Only the previous and current ping timestamp and distance are needed.  If you use scheduled polling so you always know exactly how far apart each ping is (for example, exactly 50,000uS) then you don't even need to know the timestamp, just the current and previous ping distance.  Just don't use delay(50) to make them 50ms apart, that won't be accurate.  You'll need to either use an interrupt timer or polling to keep things accurate.  Interrupt timer would be ideal but more complicated unless you used a timer library would would greatly simplify things.

I've written a little sketch for you that uses the NewPing and TimerOne library that outputs the speed via serial and uses the timer interrupt to make the ping timing very accurate.  I added lots of comments so you should be able to follow along.  Speed values are in meters per second, with positive values coming at you and negative moving away.  Anyway, here's the sketch:

Code: [Select]
#include <TimerOne.h>
#include <NewPing.h>

#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.

NewPing sonar(TRIGGER_PIN, ECHO_PIN); // NewPing setup of pins.

volatile int previous = 0, current = 0; // Must be volatile because these change inside the interrupt code.
volatile float mps = 0.0;
volatile boolean newping = false;

void setup() {
 delay(1000);                        // Wait a second before we start.
 Timer1.initialize(50000);           // 50000uS = 50ms.
 Timer1.attachInterrupt(pingSensor); // pingSensor to run every 50ms.
 Serial.begin(115200);               // Open serial monitor at 115200 baud to see ping results.
}

void loop() {
 if (newping) { // There a new ping, print speed.
   /* START - This section would be replaced with code that would do something with the result other than just output to serial. */
   if (mps) {   // Non-zero speed, show result.
     Serial.print(mps);
     Serial.println(" m/s");
   } else Serial.println("-"); // Can't determine speed, output "-" instead of speed.
   /* END */
   newping = false; // Set to false till next ping.
 }
}

void pingSensor() {
 previous = current;
 current = sonar.ping_cm(); // Send out a ping and get the results in CM.
 if (previous && current) { // If either are zero, we had a no-ping result or on the first ping.
   mps = (float) (previous - current) * 0.2; // Calculate speed in m/s (positive values are coming at you, negative moving away).
 } else mps = 0; // Can't calculate speed.
 newping = true; // Flag that there's a new ping.
}


Hope this helps!

Tim


tq so much eckel!!its work for me..i using parallax ping ultrasonic sensor and add some more coding..later i post here what ive done..tq so much!!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 08, 2013, 03:09 am

Hi,

First of all THANK YOU TIM for this library!!!!!!!!!!!!!!!!!!!!
And thank you to all the enthusiasts who have been posting here!

I have been running into a slight problem that I have not been able to fix, despite dowloading the lib again, googling it a million times, etc. I am trying to get readings from a PING))) sensor and from a maxbotic MAX SONAR (which can be PWM, An or BW, I have it as PWM) and arduino throws the same error:
'NewPing' does not name a type

sketch_jan06a:3: error: 'NewPing' does not name a type
sketch_jan06a:4: error: 'NewPing' does not name a type
sketch_jan06a.cpp: In function 'void loop()':
sketch_jan06a:19: error: 'sonar1' was not declared in this scope
sketch_jan06a:23: error: 'sonar2' was not declared in this scope

Any suggestions would be greatly greatly appreciated..... Thank you!!!!!


Your exact sketch compiled fine here.  But, I can get it to fail and give the above errors by removing the #include <NewPing.h> line.  This means that while you're telling it to load NewPing.h, it can't find it.  Most of the time, this means that you didn't install NewPing properly to the correct directory.  Libraries are installed inside your "Arduino" library in a subdirectory named "libraries".  Inside "libraries" you would create a new directory named "NewPing" with the files in the NewPing zip file in the NewPing directory.  See the other directories inside "libraries" for examples of how it should look.  The only instructions I have for installing a library with Arduino is:

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


If you can't figure out how to correctly install a library, do a web search for how to install an Arduino library, maybe someone else has a better way of describing it.

Tim
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent
Post by: Mr-What on Jan 08, 2013, 03:10 pm

Very good job, man!!!!
Two questions:
- is it possible to use multiple ultrasonic sensors? i.e 4 sensors?
- with multiple sensors and a distance between 10 and 20 cm how fast can be the readings?
Thanks

For my HC-SR04 app, I use a common trigger signal (to all 8 sensors), then pin-change interrupts to read pulse time.
I went outside the libraries to do this.  Haven't tried to see how fast I can ping, but they all share the same
timeout, currently at .030 sec (30ish Hz max).  They don't seem to work for distances longer than about
.020 ping time, so I'd think that a max rate of around 40 Hz should be achievable... for full 2+m range.

I don't know how much faster you could go at max 20cm, since subsequent pulses might
give false readings from objects around 2-2.5m away.

See http://arduino.cc/forum/index.php/topic,141363.0.html (http://arduino.cc/forum/index.php/topic,141363.0.html) for my test code.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent
Post by: Mr-What on Jan 08, 2013, 03:13 pm

I'm writing a library for these: http://goo.gl/FWMjI  and I'd love to try some cool mapping ideas with your code...


I'm writing my own too.  My test code is posted at http://arduino.cc/forum/index.php/topic,141363.0.html (http://arduino.cc/forum/index.php/topic,141363.0.html).
The big difference for my code is that an array of HC-SR04's all share the same trigger, then read pulse
time using pin-change interrupts (on mega).

It is kind of hard for me to generalize pin-change interrupts, so it is somewhat hard-coded.
more of an example than a good general-purpose library.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent
Post by: teckel on Jan 09, 2013, 09:50 am


I'm writing a library for these: http://goo.gl/FWMjI  and I'd love to try some cool mapping ideas with your code...


I'm writing my own too.  My test code is posted at http://arduino.cc/forum/index.php/topic,141363.0.html (http://arduino.cc/forum/index.php/topic,141363.0.html).
The big difference for my code is that an array of HC-SR04's all share the same trigger, then read pulse
time using pin-change interrupts (on mega).

It is kind of hard for me to generalize pin-change interrupts, so it is somewhat hard-coded.
more of an example than a good general-purpose library.


The problem with pin-change interrupts is that it's not even tested on the Uno, only Mega.  It's a little ridged for a general-purpose library.  The next release of NewPing *should* have a pin interrupt-based method. I've expanded my required compatibility to include the Uno, Teensy 2.0, and Teensy 3.0.  So, it's a little more challenging at times.

I do have a question for you.  How do you deal with pings that don't return?  Waiting for the interrupt doesn't work as sometimes there isn't a ping return.  I'm building an ultra-low-powered system currently and because I can't rely on getting a ping result, I can't do what I wanted, which is to put the ATmega to sleep while waiting for the pin interrupt.  Still got it down to using only 1.27mA, but even lower would be better.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Mr-What on Jan 09, 2013, 03:55 pm
I have run the pin-change interrupts on UNO...  the official pin-change interrupt libraries are tested for UNO, NOT mega.

Either way, you will see that this is kind of hard-coded to my app.
It gets very tricky when you want to use specific pins so they share the same interrupt vector.
So tricky that I gave up on "proper" programming, and kind of hard-coded pin assignments and interrupts.

My application runs on a constant poll, and will call .timeout() when more than about 20000us have passed.
That is not shown...  since I just posted my original test script demonstrating use of pin-change interrupts for a sonar array.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 09, 2013, 04:44 pm

I have run the pin-change interrupts on UNO...  the official pin-change interrupt libraries are tested for UNO, NOT mega.

Either way, you will see that this is kind of hard-coded to my app.
It gets very tricky when you want to use specific pins so they share the same interrupt vector.
So tricky that I gave up on "proper" programming, and kind of hard-coded pin assignments and interrupts.

My application runs on a constant poll, and will call .timeout() when more than about 20000us have passed.
That is not shown...  since I just posted my original test script demonstrating use of pin-change interrupts for a sonar array.


My bad, pinchangeint supports Uno with partial Mega compatibility.

Don't you have to wait at least 29 to 35ms?  The sensors work at up to 500cm, which means the pings are still bouncing around for up to 28,500uS.

Also, when I've tried to fire multiple sensors simultaneously, it really only worked well in wide-open spaces.  In more closed environments, I'd get cross-sensor echos at times making it unreliable.

With this said, using the Teensy 3.0 is really nice as every pin can be an interrupt.  You may want to consider this as it would make things a lot easier.  Not to mention the extra horsepower the microcontroller will give you.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Mr-What on Jan 10, 2013, 03:50 pm
You are right.  I need to revisit that.  I might need to extend that timeout.  I have seen these specific sensors work over 2m (to a flat wall).

Haven't seen cross-talk in my testing yet, but I haven't done anything too stressing.  This is for a large robot, so the sensors will be about 20-50 cm apart, more or less radially pointing outward.

For collision avoidance I am hoping that a false positive from a simultaneous ping would not necessarily be a bad thing.  If I receive my neighbor's ping from a tilted surface nearby (which I still need to avoid), that is better than not seeing anything.  I hope that the first echo sensed causes the pin to go low, and I get the "conservative" estimate of distance to a nearby obstacle.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: jmXCA on Jan 27, 2013, 10:46 am
Teckel, I've received a Due and downloaded NewPing (you asked earlier in the thread).  The immediate issues are that it includes "avr/io.h" and "avr/interrupt.h", neither of which seem to have obvious counterparts for the ARM due.

With those headers missing, the following lines become issues:
Code: [Select]

C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In constructor 'NewPing::NewPing(uint8_t, uint8_t, int)':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:19: error: cannot convert 'volatile RwReg*' to 'volatile uint8_t*' in assignment
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:20: error: cannot convert 'volatile RoReg*' to 'volatile uint8_t*' in assignment
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:22: error: 'portModeRegister' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_us(unsigned int, void (*)())':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:151: error: 'OCR2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:152: error: 'TIMSK2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:152: error: 'OCIE2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_ms(long unsigned int, void (*)())':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:167: error: 'OCR2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:168: error: 'TIMSK2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:168: error: 'OCIE2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_stop()':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:177: error: 'TIMSK2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:177: error: 'OCIE2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_setup()':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:195: error: 'ASSR' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:195: error: 'AS2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:196: error: 'TCCR2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:196: error: 'WGM21' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:197: error: 'TCCR2B' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:197: error: 'CS22' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:198: error: 'TCNT2' was not declared in this scope
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: jmXCA on Jan 27, 2013, 11:28 am

Teckel, I've received a Due and downloaded NewPing (you asked earlier in the thread).  The immediate issues are that it includes "avr/io.h" and "avr/interrupt.h", neither of which seem to have obvious counterparts for the ARM due.

With those headers missing, the following lines become issues:
Code: [Select]

C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In constructor 'NewPing::NewPing(uint8_t, uint8_t, int)':
SNIP



Ok, so in a pinch I quickly hacked this to work on the DUE (NO TIMERS YET).  I'm new to Arduino so these changes probably have some side effect I'm not aware of (ie, I'm not sure why digitalWrite and pinMode functions weren't used in the first place - maybe just to avoid function calls?)
1) In NewPing.h:
-if'defd the AVR includes
#ifndef __arm__
#include <avr/io.h>
#include <avr/interrupt.h>
#ifndef __arm__

-added 2 members to NewPing class
uint8_t _triggerPin;
uint8_t _echoPin;

2) In NewPing.cpp:
-Added these 2 lines in the constructor
   _triggerPin = trigger_pin;
   _echoPin = echo_pin;

-Commented out the portModeRegister line

-Change any lines like  "*_triggerMode |= _triggerBit; // Set trigger pin to output."
to: pinMode(_triggerPin,OUTPUT);


-And finally a new ping_trigger()
#ifdef __arm__
boolean NewPing::ping_trigger() {
#if DISABLE_ONE_PIN != true
   pinMode(_triggerPin, OUTPUT);
#endif
   digitalWrite(_triggerPin, LOW);
   delayMicroseconds(4);            // Wait for pin to go low, testing shows it needs 4uS to work every time.
   digitalWrite(_triggerPin, HIGH);
   delayMicroseconds(10);           // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS.
   digitalWrite(_triggerPin, LOW);

#if DISABLE_ONE_PIN != true
   pinMode(_triggerPin, INPUT);
#endif

   _max_time =  micros() + MAX_SENSOR_DELAY;                  // Set a timeout for the ping to trigger.
   while ((digitalRead(_echoPin) == HIGH) && (micros() <= _max_time)) {}
   while (!(digitalRead(_echoPin) == HIGH))                          // Wait for ping to start.
      if (micros() > _max_time) return false;                // Something went wrong, abort.

   _max_time = micros() + _maxEchoTime; // Ping started, set the timeout.
   return true;                         // Ping started successfully.
}
#else
//old ping_trigger() goes here
#endif
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 28, 2013, 05:15 am

Teckel, I've received a Due and downloaded NewPing (you asked earlier in the thread).  The immediate issues are that it includes "avr/io.h" and "avr/interrupt.h", neither of which seem to have obvious counterparts for the ARM due.

With those headers missing, the following lines become issues:
Code: [Select]

C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In constructor 'NewPing::NewPing(uint8_t, uint8_t, int)':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:19: error: cannot convert 'volatile RwReg*' to 'volatile uint8_t*' in assignment
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:20: error: cannot convert 'volatile RoReg*' to 'volatile uint8_t*' in assignment
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:22: error: 'portModeRegister' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_us(unsigned int, void (*)())':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:151: error: 'OCR2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:152: error: 'TIMSK2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:152: error: 'OCIE2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_ms(long unsigned int, void (*)())':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:167: error: 'OCR2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:168: error: 'TIMSK2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:168: error: 'OCIE2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_stop()':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:177: error: 'TIMSK2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:177: error: 'OCIE2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_setup()':
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:195: error: 'ASSR' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:195: error: 'AS2' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:196: error: 'TCCR2A' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:196: error: 'WGM21' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:197: error: 'TCCR2B' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:197: error: 'CS22' was not declared in this scope
C:\arduino-1.5.1r2\hardware\arduino\sam\libraries\NewPing\NewPing.cpp:198: error: 'TCNT2' was not declared in this scope



The Due will not currently work with the NewPing library.  NewPing uses all low-level port register calls which are specific to the 8 bit ATmega processors.  I've been working on a new version that will work with the Teensy 3.0 (http://www.pjrc.com/store/teensy3.html) that's similar to the Due as they both use 32 bit microcontrollers.  I don't plan on getting a Due as the Teensy 3.0 (http://www.pjrc.com/store/teensy3.html) offers similar capability but in a MUCH smaller size and only costs $19.  But, this update should also work with the Due in the basic non-timer interrupt methods.

The code you listed in your following post is similar to my development library for the non-8-bit ATmega microcontrollers.  Instead of timer interrupt methods, pin interrupt should be the method of choice for the Due.  I know for the Teensy 3.0 every pin can be an external pin interrupt, which makes it ULTRA convenient .  I think the Due isn't quite as advanced in this area, which makes it a little more of an issue to implement, or will be somewhat limited.

You'll soon find that most advanced libraries won't work with the Due.  Only simple libraries that don't do any lower-level commands will work.  For size and speed, many libraries have adopted very specific 8 bit ATmega compatibility.  So, expect to find many libraries that won't work with the Due.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: gandalf50 on Jan 29, 2013, 09:53 pm
Hi Tim.

Thanks for a great library!

I have a problem though that you might have some ideas on what I've done wrong.
When using your lib (v1.5) together with an Ethernet shield, I can't get 3 sensors to work properly.

E.g:
- If I use 3 HC-SR04 sensors and a Mega 2560 with your example code with an sonar array, they all work fine, but if I just add an Ethernet shield to the Mega, 2 of the sensors give bad readings (like 4 cm instead of 90-150cm). The same wiring is used and no code is changed, just added the Ethernet shield (i.e. not messed with Timer2 and don't use the tone lib)

- The Ethernet shield works, e.g. can just load other code (e.g. web server code, NTP client etc) without even removing the connected sensors and it works fine, i.e. it's not the Ethernet shield itself (have also tried with another Ethernet shield with same result)

- I've stayed away from the 50-53 pins (used by Ethernet shield+HW ss pin) and the PWM pins. Currently using pin 30-35 (it's the middle HC-SR04 that gives OK readings when Ethernet shield is connected)

- Tried with stuff like disabling SD SPI interface, pin 4, and setting pin 53 to output without any luck.

- Using Arduino 1.0.2 IDE

Any ideas?

Thanks in advance!!
  /Magnus
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 30, 2013, 04:30 am

Hi Tim.

Thanks for a great library!

I have a problem though that you might have some ideas on what I've done wrong.
When using your lib (v1.5) together with an Ethernet shield, I can't get 3 sensors to work properly.

E.g:
- If I use 3 HC-SR04 sensors and a Mega 2560 with your example code with an sonar array, they all work fine, but if I just add an Ethernet shield to the Mega, 2 of the sensors give bad readings (like 4 cm instead of 90-150cm). The same wiring is used and no code is changed, just added the Ethernet shield (i.e. not messed with Timer2 and don't use the tone lib)

- The Ethernet shield works, e.g. can just load other code (e.g. web server code, NTP client etc) without even removing the connected sensors and it works fine, i.e. it's not the Ethernet shield itself (have also tried with another Ethernet shield with same result)

- I've stayed away from the 50-53 pins (used by Ethernet shield+HW ss pin) and the PWM pins. Currently using pin 30-35 (it's the middle HC-SR04 that gives OK readings when Ethernet shield is connected)

- Tried with stuff like disabling SD SPI interface, pin 4, and setting pin 53 to output without any luck.

- Using Arduino 1.0.2 IDE

Any ideas?

Thanks in advance!!
  /Magnus



First, try using different pins for the sensors that are not working.  It sounds like a conflict.  If that doesn't work, you're going to need to provide some code so I know exactly how you're using NewPing.  Not even sure what method of NewPing you're using, timer interrupt method or standard?  At least part of the code would be helpful (maybe all of it).

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: gandalf50 on Jan 30, 2013, 08:09 pm
Sounds good, I'll try some more with other pin configs.

I didn't provide the code since I have this problem with e.g. your example code with the sonar array and 3 sensors. I.e. your code with "This example code was used to successfully communicate with 15 ultrasonic sensors". Let me know if you still want the code (only updated the SONAR_NUM and objects in the sonar array).

Do you know if someone got multiple sensor working together with an Ethernet shield on the Mega 2560?

Brg,
  /Magnus
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 31, 2013, 12:01 am

Sounds good, I'll try some more with other pin configs.

I didn't provide the code since I have this problem with e.g. your example code with the sonar array and 3 sensors. I.e. your code with "This example code was used to successfully communicate with 15 ultrasonic sensors". Let me know if you still want the code (only updated the SONAR_NUM and objects in the sonar array).

Do you know if someone got multiple sensor working together with an Ethernet shield on the Mega 2560?

Brg,
  /Magnus


The code is always helpful, even if it's basically the same as the sample.  I've seen several times that a little change was made and that was causing the problem.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: gandalf50 on Jan 31, 2013, 08:42 am
Sure, here it is:
// ---------------------------------------------------------------------------
// This example code was used to successfully communicate with 15 ultrasonic sensors. You can adjust
// the number of sensors in your project by changing SONAR_NUM and the number of NewPing objects in the
// "sonar" array. You also need to change the pins for each sensor for the NewPing objects. Each sensor
// is pinged at 33ms intervals. So, one cycle of all sensors takes 495ms (33 * 15 = 495ms). The results
// are sent to the "oneSensorCycle" function which currently just displays the distance data. Your project
// would normally process the sensor results in this function (for example, decide if a robot needs to
// turn and call the turn function). Keep in mind this example is event-driven. Your complete sketch needs
// to be written so there's no "delay" commands and the loop() cycles at faster than a 33ms rate. If other
// processes take longer than 33ms, you'll need to increase PING_INTERVAL so it doesn't get behind.
// ---------------------------------------------------------------------------
#include <NewPing.h>

#define SONAR_NUM     3 // Number of sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 0;          // Keeps track of which sensor is active.

NewPing sonar[SONAR_NUM] = {     // Sensor object array.
  NewPing(22, 23, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping. // OK
  NewPing(24, 25, MAX_DISTANCE), // NOK
  NewPing(34, 35, MAX_DISTANCE)  // OK
};

  void setup() {
    Serial.begin(115200);
    pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
    for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
      pingTimer = pingTimer[i - 1] + PING_INTERVAL;
  }

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    if (millis() >= pingTimer) {         // Is it this sensor's time to ping?
      pingTimer += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }
  }
  // Other code that *DOESN'T* analyze ping results can go here.
}

void echoCheck() { // If ping received, set the sensor distance to array.
  if (sonar[currentSensor].check_timer())
    cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
  // The following code would be replaced with your code that does something with the ping results.
  for (uint8_t i = 0; i < SONAR_NUM; i++) {
    Serial.print(i);
    Serial.print("=");
    Serial.print(cm);
    Serial.print("cm ");
  }
  Serial.println();
}


Now two of the sensors work fine with the ethernet shield, using the pins above. Without the ethernet shield all 3 works.
I've looked at the 2560 pinout, but it didn't help figuring this out. Also tried several pin configs. I've also tried initializing the Ethernet shield (i.e. setting IP addr etc), but no luck (and tried with the 1.0 IDE as well).

Only the 3 sensors are wired to the Mega (power via USB).

I'll try with an UNO with an Ethernet shield and an Arduino Ethernet.

  /Magnus
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 31, 2013, 10:16 pm

Now two of the sensors work fine with the ethernet shield, using the pins above. Without the ethernet shield all 3 works.
I've looked at the 2560 pinout, but it didn't help figuring this out. Also tried several pin configs. I've also tried initializing the Ethernet shield (i.e. setting IP addr etc), but no luck (and tried with the 1.0 IDE as well).

Only the 3 sensors are wired to the Mega (power via USB).

I'll try with an UNO with an Ethernet shield and an Arduino Ethernet.

 /Magnus


I don't see any Ethernet code in that sketch.  Does it fail just as is?  What exactly happens?

The first thing you should ALWAYS try is to use different pins.  Also, switch the sensors to see if the problem follows the sensors or the pins.  My guess is that there's a conflict with the pins you are using.  Using different pins is so simple that you should always try this first.

Try totally different pins and see if anything changes.  If so, the conflict is with the Ethernet or SD library.

I'd also try to slow down the pings, change PING_INTERVAL 33  to PING_INTERVAL 250 and see if that does anything.

Finally, I'd try to not use a timer interrupt method of pinging as it could be just a simple timing issue with multiple libraries competing for CPU cycles.  So instead of using ping_timer() just do a convention ping of each sensor.  Here's a sketch that does just that to your 3 sensors:

Code: [Select]
#include <NewPing.h>

#define SONAR_NUM       3 // Number of sensors.
#define MAX_DISTANCE  200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 250 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

NewPing sonar[SONAR_NUM] = {     // Sensor object array.
  NewPing(22, 23, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(24, 25, MAX_DISTANCE),
  NewPing(34, 35, MAX_DISTANCE)
};

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

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    unsigned int cm = sonar[i].ping_cm();
    Serial.print(i);
    Serial.print("=");
    Serial.print(cm);
    Serial.print("cm ");
  }
  Serial.println();
  delay(PING_INTERVAL);
}


Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: gandalf50 on Feb 02, 2013, 11:51 am
I solved it!

External power is needed to the Arduino, i.e. just powering via USB is not enough to get good results when multiple ping sensors and an Ethernet shield are used.
This is regardless if an Mega or an Uno are used, or if the PC have 1 or 2 PSUs.

  //Magnus
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: oigres666 on Feb 04, 2013, 04:39 pm
Hi everyone! I have a question... if I use 4 ultrasonic sensors and I want to send the data to Processing for transforming the data to OSC, can I use the 15 sensors sketch but with 4?? I don't know how can i do it...
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: cyclegadget on Feb 04, 2013, 06:58 pm

Hi everyone! I have a question... if I use 4 ultrasonic sensors and I want to send the data to Processing for transforming the data to OSC, can I use the 15 sensors sketch but with 4?? I don't know how can i do it...


Code: [Select]
#define SONAR_NUM       4 // Number of sensors.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Feb 04, 2013, 10:23 pm

I solved it!

External power is needed to the Arduino, i.e. just powering via USB is not enough to get good results when multiple ping sensors and an Ethernet shield are used.
This is regardless if an Mega or an Uno are used, or if the PC have 1 or 2 PSUs.

  //Magnus



Interesting!  My ultrasonic sensors only use a couple mA each, while the Arduino Uno uses 60 mA (I'd guess the Mega uses more).  I wouldn't think that just the sensors would put your USB or the voltage regulator over the top.  Have you measured what kind of current it's using?  It just seems very unlikely that it's within a couple mA of going over the top and the sensors draw enough current to do it.  I guess it's possible, just doesn't seem likely.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: oigres666 on Feb 05, 2013, 05:50 pm


Hi everyone! I have a question... if I use 4 ultrasonic sensors and I want to send the data to Processing for transforming the data to OSC, can I use the 15 sensors sketch but with 4?? I don't know how can i do it...


Code: [Select]
#define SONAR_NUM       4 // Number of sensors.

yeah, I know that, but i want to know how to send to processing, How can processing read this data???.... coz from processing i can transform the data to OSC...or am I wrong?? :smiley-roll-sweat:
Thank u!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Feb 05, 2013, 06:35 pm



Hi everyone! I have a question... if I use 4 ultrasonic sensors and I want to send the data to Processing for transforming the data to OSC, can I use the 15 sensors sketch but with 4?? I don't know how can i do it...


Code: [Select]
#define SONAR_NUM       4 // Number of sensors.

yeah, I know that, but i want to know how to send to processing, How can processing read this data???.... coz from processing i can transform the data to OSC...or am I wrong?? :smiley-roll-sweat:
Thank u!


What do you mean by "i want to know how to send to processing"?  What is "processing"?  What is "OSC"?

The sketch pings the sensors and stores the values in the cm[] array.  In the pingResult() function the contents of the cm[] array are output via serial.  If you want to send that data to something else, whatever "processing" and "OSC" is, you would simply replace the contents of the pingResults() function with whatever you wanted to do with the results.  We have no idea what you want to do with the results, but the data is there for you to do whatever you want with it.  The pingResults() function is where you should do your magic with the results.

I have a post with help and alternative code for the 15 sensor sketch (http://arduino.cc/forum/index.php/topic,106043.msg1009294.html#msg1009294).

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: rainierez on Feb 05, 2013, 06:56 pm
Just used this on a project I was building against my digispark. I removed the timer stuff since I didn't need them and it wouldn't compile against it. But anyway. worked great and was better than me trying to futz with timing all day long. Thanks!!

DigiStump's forum post for the project: http://digistump.com/board/index.php/topic,299.0.html (http://digistump.com/board/index.php/topic,299.0.html)

Youtube of it running: http://www.youtube.com/watch?v=QNZyMQC3maQ (http://www.youtube.com/watch?v=QNZyMQC3maQ)
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Feb 05, 2013, 07:56 pm

Just used this on a project I was building against my digispark. I removed the timer stuff since I didn't need them and it wouldn't compile against it. But anyway. worked great and was better than me trying to futz with timing all day long. Thanks!!


I think the digispark uses the ATtiny85, that would make sense that it wouldn't work with the timer stuff.  I believe I've modified my development code to detect the ATtiny processors and not use the timer interrupt stuff.  The standard ping(), ping_cm(), ping_in(), ping_median() methods should still work just fine on the ATtiny.

If program space is also a problem with the limited memory on the ATtiny, you could reduce the compiled size by optimizing your sketch a little.  Here's a suggestion:

Code: [Select]
#include <NewPing.h>

#define TRIGGER_PIN 3
#define ECHO_PIN 5
#define RED_PIN 0
#define GREEN_PIN 1
#define BLUE_PIN 4
#define MAX_DISTANCE 60

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

void setup() {
 pinMode(RED_PIN, OUTPUT);
 pinMode(GREEN_PIN, OUTPUT);
 pinMode(BLUE_PIN, OUTPUT);
}

void loop() {
 uint8_t distance = sonar.ping_cm();
 
 if (distance) {
   uint8_t greenValue = map(distance, 1, MAX_DISTANCE, 0, 255);  //Map the distance range to a range of 0 to 255 to the pwm value for the Green LED
   uint8_t redValue = 255 - greenValue;
   analogWrite(GREEN_PIN, greenValue);
   analogWrite(RED_PIN, redValue);
   digitalWrite(BLUE_PIN, LOW);
 } else {
   //Out of range, turn the LED blue
   digitalWrite(GREEN_PIN, LOW);
   digitalWrite(RED_PIN, LOW);    
   digitalWrite(BLUE_PIN, HIGH);
 }
 delay(50);
}


This would use quite a bit less sketch size and reduce the memory usage as well by using defines and right-sized variables.

On a side note, the digispark is under-powered and overpriced. For a couple dollars more you can get a Teensy 2.0 which is practically the same size and a full ATmega microcontroller so you have a ton of available pins (actually, it has more pins than an Arduino Uno).  For just $3 more you can also get the Teensy 3.0 which is a 96 MHz 32-bit microcontroller, but still works with Arduino IDE.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: oigres666 on Feb 06, 2013, 01:14 pm




Hi everyone! I have a question... if I use 4 ultrasonic sensors and I want to send the data to Processing for transforming the data to OSC, can I use the 15 sensors sketch but with 4?? I don't know how can i do it...


Code: [Select]
#define SONAR_NUM       4 // Number of sensors.

yeah, I know that, but i want to know how to send to processing, How can processing read this data???.... coz from processing i can transform the data to OSC...or am I wrong?? :smiley-roll-sweat:
Thank u!


What do you mean by "i want to know how to send to processing"?  What is "processing"?  What is "OSC"?

The sketch pings the sensors and stores the values in the cm[] array.  In the pingResult() function the contents of the cm[] array are output via serial.  If you want to send that data to something else, whatever "processing" and "OSC" is, you would simply replace the contents of the pingResults() function with whatever you wanted to do with the results.  We have no idea what you want to do with the results, but the data is there for you to do whatever you want with it.  The pingResults() function is where you should do your magic with the results.

I have a post with help and alternative code for the 15 sensor sketch (http://arduino.cc/forum/index.php/topic,106043.msg1009294.html#msg1009294).

Tim

First of all, thank you for answering Tim! Processing is a language like, java, C++, etc... and OSC it's a protocol like MIDI for controlling a virtual instrument or whatever in your computer... My project is with 4 ultrasonic sensors to get the results and transform them into OSC so you can control eg. Ableton Live or whatever, moving your hands you can change a synth's parameters in real time.... Your code works perfectly for my 4 sensors! Now with your advice I'm going to try "play" with the data... Maybe I could obviate "Processing" and finding a library for Arduino which I can handle OSC... hahahaha sorry I'm rambling...
Anyway Thanks for ur code again!!!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: rainierez on Feb 07, 2013, 10:48 pm
Quote
I think the digispark uses the ATtiny85, that would make sense that it wouldn't work with the timer stuff.  I believe I've modified my development code to detect the ATtiny processors and not use the timer interrupt stuff.  The standard ping(), ping_cm(), ping_in(), ping_median() methods should still work just fine on the ATtiny.

If program space is also a problem with the limited memory on the ATtiny, you could reduce the compiled size by optimizing your sketch a little.  Here's a suggestion:

Code: [Select]
#include <NewPing.h>

#define TRIGGER_PIN 3
#define ECHO_PIN 5
#define RED_PIN 0
#define GREEN_PIN 1
#define BLUE_PIN 4
#define MAX_DISTANCE 60

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

void setup() {
 pinMode(RED_PIN, OUTPUT);
 pinMode(GREEN_PIN, OUTPUT);
 pinMode(BLUE_PIN, OUTPUT);
}

void loop() {
 uint8_t distance = sonar.ping_cm();
 
 if (distance) {
   uint8_t greenValue = map(distance, 1, MAX_DISTANCE, 0, 255);  //Map the distance range to a range of 0 to 255 to the pwm value for the Green LED
   uint8_t redValue = 255 - greenValue;
   analogWrite(GREEN_PIN, greenValue);
   analogWrite(RED_PIN, redValue);
   digitalWrite(BLUE_PIN, LOW);
 } else {
   //Out of range, turn the LED blue
   digitalWrite(GREEN_PIN, LOW);
   digitalWrite(RED_PIN, LOW);    
   digitalWrite(BLUE_PIN, HIGH);
 }
 delay(50);
}


This would use quite a bit less sketch size and reduce the memory usage as well by using defines and right-sized variables.

On a side note, the digispark is under-powered and overpriced. For a couple dollars more you can get a Teensy 2.0 which is practically the same size and a full ATmega microcontroller so you have a ton of available pins (actually, it has more pins than an Arduino Uno).  For just $3 more you can also get the Teensy 3.0 which is a 96 MHz 32-bit microcontroller, but still works with Arduino IDE.

Tim


Great stuff, I'm a hardware junky that knows enough code to be stupid with it. so seeing someone that knows how to make it effecient is alway a bonus. Thanks for cleaning that up a ton. I will have a go with that and let you know.

Again Thanks!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: rainierez on Feb 07, 2013, 11:09 pm
The new code you updated works great but if I leave the timer functions in the cpp then it won't compile. :/ I get this in the IDE

Code: [Select]
...\Arduino\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_us(unsigned int, void (*)())':
...\Arduino\libraries\NewPing\NewPing.cpp:151: error: 'OCR2A' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:152: error: 'TIMSK2' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:152: error: 'OCIE2A' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_ms(long unsigned int, void (*)())':
...\Arduino\libraries\NewPing\NewPing.cpp:167: error: 'OCR2A' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:168: error: 'TIMSK2' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:168: error: 'OCIE2A' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_stop()':
...\Arduino\libraries\NewPing\NewPing.cpp:177: error: 'TIMSK2' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:177: error: 'OCIE2A' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp: In static member function 'static void NewPing::timer_setup()':
...\Arduino\libraries\NewPing\NewPing.cpp:195: error: 'ASSR' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:195: error: 'AS2' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:196: error: 'TCCR2A' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:196: error: 'WGM21' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:197: error: 'TCCR2B' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:197: error: 'CS22' was not declared in this scope
...\Arduino\libraries\NewPing\NewPing.cpp:198: error: 'TCNT2' was not declared in this scope
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Feb 08, 2013, 07:27 pm

The new code you updated works great but if I leave the timer functions in the cpp then it won't compile. :/ I get this in the IDE


Yes, v1.5 of NewPing that you're running is not designed for the ATtiny.  My development version now detects the ATtiny and automatically removes the timer stuff.  In other words, you'll need to comment out the timer stuff in the library till I release version 1.6 of NewPing.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: tasosstr on Feb 09, 2013, 08:42 pm
Hello,

I would like to ask if it is possibly to read the cm with decimal like 10.4 cm e.t.c.

Thank in advance.

Best regards,
Tasos
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Feb 11, 2013, 05:01 pm

Hello,

I would like to ask if it is possibly to read the cm with decimal like 10.4 cm e.t.c.

Thank in advance.

Best regards,
Tasos


Yes, simply use ping() which will return the milliseconds and then divide by whatever number you want to convert ms to cm (defaults to 57).  The library uses integers to save program space (saves about 1k by avoiding floating point).  Also, the accuracy isn't really better than a cm and there's other variables like temperature that will change the speed of sound and mess up your calculations.

However, keep in mind that doing any of this will really be of no good as the sensor is not accurate enough to actually give you a consistent reading of 10.4.  If you did use a floating point number for ms to cm conversion, the ping results would probably jump around from 10.9 to 10.1, with everything still.  So, I'm sure sure what use you'd really get from it.  All you'd really be doing is wasting 1k of program space and getting a bunch of different readings and not knowing which one was right.

Basically, I'd suggest leaving it as-is and accepting that the sensor is really only accurate to 1cm or 1in.  And, enjoy the extra speed and 1k of program space you saved by not using floating point calculations on things that are not accurate below an integer anyway.  NewPing is designed to be small, fast, and accurate.  Making it floating point would not help the accuracy and it would make it slower and larger.  So, it would hurt the library in every way.  But, you're free to use floating point if you wish by using the ping() method along with your own conversion (after also monitoring the temperature).

Let me know if you actually find this useful, I've yet to hear of it being at all useful or more accurate.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: michinyon on Feb 11, 2013, 06:35 pm
Well that's a good point,  but it is still likely to jump around between 10  and 11 cm.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: gandalf50 on Feb 11, 2013, 09:02 pm

Interesting!  My ultrasonic sensors only use a couple mA each, while the Arduino Uno uses 60 mA (I'd guess the Mega uses more).  I wouldn't think that just the sensors would put your USB or the voltage regulator over the top.  Have you measured what kind of current it's using?  It just seems very unlikely that it's within a couple mA of going over the top and the sensors draw enough current to do it.  I guess it's possible, just doesn't seem likely.

Tim


Well it did it for me at least. Hopefully it helps someone else as well.

The operating voltage for the HC-SR04 should apperently be 4.50 to 5.0V. But I did some quick measurements which shows that that's not the case for my sensors:

With Ethernet shield:
1. Power via USB port
1.1. With LCD screen connected as well, at 3 HC-SR04 ultrasonic sensors: 4.55 V
1.2. Without LCD Screen: 4.60 V

2. Power from power outlet
2.1. With LCD screen connected as well, at 3 HC-SR04 ultrasonic sensors: 4.98 V
2.2. Without LCD Screen: 4.98 V

Without Ethernet shield:
3. Power via USB port
3.1. With LCD screen connected as well, at 3 HC-SR04 ultrasonic sensors: 4.76 V
3.2. Without LCD Screen: 4.82 V

4. Power from power outlet
4.1. With LCD screen connected as well, at 3 HC-SR04 ultrasonic sensors: 4.98 V
4.2. Without LCD Screen: 4.98 V

i.e. since it doesn't work properly for me with just the sensors and the Ethernet shield connected (using just USB), over 4.60V seems to be needed.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Feb 11, 2013, 09:02 pm

Well that's a good point,  but it is still likely to jump around between 10  and 11 cm.


Not if you turn off rounding.  But, you are right, it can bounce between to different integers as well.  However, that's because the sensor is not accurate to a fraction of a cm.  It's not because the library doesn't do floating point.  Basically, it's not helpful to do floating point math.  But, feel free to do it.  Replace "ping_cm()" with "ping()/57.0" and you'll get a decimal result.  If you find this useful I'd really be amazed, but the library is designed so you can do it as shown.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Feb 11, 2013, 09:06 pm


Interesting!  My ultrasonic sensors only use a couple mA each, while the Arduino Uno uses 60 mA (I'd guess the Mega uses more).  I wouldn't think that just the sensors would put your USB or the voltage regulator over the top.  Have you measured what kind of current it's using?  It just seems very unlikely that it's within a couple mA of going over the top and the sensors draw enough current to do it.  I guess it's possible, just doesn't seem likely.

Tim


Well it did it for me at least. Hopefully it helps someone else as well.

The operating voltage for the HC-SR04 should apperently be 4.50 to 5.0V. But I did some quick measurements which shows that that's not the case for my sensors:

With Ethernet shield:
1. Power via USB port
1.1. With LCD screen connected as well, at 3 HC-SR04 ultrasonic sensors: 4.55 V
1.2. Without LCD Screen: 4.60 V

2. Power from power outlet
2.1. With LCD screen connected as well, at 3 HC-SR04 ultrasonic sensors: 4.98 V
2.2. Without LCD Screen: 4.98 V

Without Ethernet shield:
3. Power via USB port
3.1. With LCD screen connected as well, at 3 HC-SR04 ultrasonic sensors: 4.76 V
3.2. Without LCD Screen: 4.82 V

4. Power from power outlet
4.1. With LCD screen connected as well, at 3 HC-SR04 ultrasonic sensors: 4.98 V
4.2. Without LCD Screen: 4.98 V

i.e. since it doesn't work properly for me with just the sensors and the Ethernet shield connected (using just USB), over 4.60V seems to be needed.


I've ran ultrasonic sensors down to 3.3 volts and they still work.  I forgot I have an Internet shield, I'll see what kind of milliamps it uses.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: tasosstr on Feb 11, 2013, 09:15 pm


Hello,

I would like to ask if it is possibly to read the cm with decimal like 10.4 cm e.t.c.

Thank in advance.

Best regards,
Tasos



Yes, simply use ping() which will return the milliseconds and then divide by whatever number you want to convert ms to cm (defaults to 57).  The library uses integers to save program space (saves about 1k by avoiding floating point).  Also, the accuracy isn't really better than a cm and there's other variables like temperature that will change the speed of sound and mess up your calculations.

However, keep in mind that doing any of this will really be of no good as the sensor is not accurate enough to actually give you a consistent reading of 10.4.  If you did use a floating point number for ms to cm conversion, the ping results would probably jump around from 10.9 to 10.1, with everything still.  So, I'm sure sure what use you'd really get from it.  All you'd really be doing is wasting 1k of program space and getting a bunch of different readings and not knowing which one was right.

Basically, I'd suggest leaving it as-is and accepting that the sensor is really only accurate to 1cm or 1in.  And, enjoy the extra speed and 1k of program space you saved by not using floating point calculations on things that are not accurate below an integer anyway.  NewPing is designed to be small, fast, and accurate.  Making it floating point would not help the accuracy and it would make it slower and larger.  So, it would hurt the library in every way.  But, you're free to use floating point if you wish by using the ping() method along with your own conversion (after also monitoring the temperature).

Let me know if you actually find this useful, I've yet to hear of it being at all useful or more accurate.

Tim


Hello Dear Tim,

Thank you very much for the reply and for the help ! ! !

You have make amazing work well done ! ! !

I was try the bellow example:
Code: [Select]
#include <NewPing.h>

#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 500 // 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.

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

void loop() {
 delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
 float uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
 Serial.print("Ping: ");
 Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)
 Serial.println("cm");
}


and working perfect ! ! !

I need this because i want to get the height of a petrol tank, so now i can have more better results because of you :-)



Again Thank you Very Much ! ! !

Best Regards,
Tasos
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: warren631 on Feb 11, 2013, 10:28 pm
THANKS FOR THIS NEW SONIC LIBRARY!  GREAT WORK !!!!!!!!!!!!!!!!!!!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: ravenx99 on Feb 23, 2013, 12:12 am

I need this because i want to get the height of a petrol tank, so now i can have more better results because of you :-)


Tasos, just a word of caution before you get too far into your project:

Ultrasonic sensors don't work well with petrol/gasoline.  I seem to recall it was due to vapor in the tank giving false readings.

My wife used to work for ESI in Wichita, KS, which specialized in designing and installing liquid storage tank level sensors.  They provided a business-to-business link where their hardware would monitor tanks of, say, liquid chicken feed additive, and automatically call the tank-filling-company and schedule a delivery when the tank was low.

I recall my wife talking specifically about a big sale hanging on their ability to monitor fuel tank levels, and the lead engineer was under a lot of pressure to develop a sensor that worked, but a solution eluded him and it was causing a lot of friction at work.  This was many years ago, and it's now a solved problem, but the problem still stands for generic ultrasonic sensors.  (It may have been a solved problem then, and maybe the boss didn't want to use a third-party product.)

There are commercial sensors available for measuring petrol/gasoline, but I'm sure they're at least a magnitude more expensive than the hobby ultrasonic sensors.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: AWOL on Feb 23, 2013, 12:34 am
Quote
Ultrasonic sensors don't work well with petrol/gasoline.

Was the problem simply one of calibration, i.e. the speed of sound in vapour-laden air vs. speed of sound in air?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: ravenx99 on Feb 23, 2013, 12:39 am
I'm building a little robot with an HC-SR04 for obstacle avoidance, and I'm finding NewPing to be very nice.  Thanks for your hard work, Tim.

I'm using NewPing in timer-mode, but I don't really need to do anything inside my echoCheck() function... I just want a distance value to be available to other parts of the code.

Here's where I run into a problem... I'm not seeing a good way to directly determine the difference between "timed out without an echo" and "still waiting for an echo" conditions.  check_ping() returns false in both cases, and x.ping_result is only updated on receiving an echo.  So x.ping_result always indicates the distance of the last successful ping, but it will always be a positive value even when pings are timing out without an echo.

So inside my echoCheck(), I have to assign the value of ping_result to a global variable, and then when I read the global variable elsewhere in the code, I have to remember to set it to zero.  This is effectively doing the same job as ping_result, except it's happening in my code instead of inside NewPing.

Would it make sense for the timeout reset portion of check_ping() to set ping_result back to 0?  ping_result isn't used anywhere else in NewPing, so it wouldn't affect internal behavior.  I don't know how it might affect behavior of existing programs, but I suppose it could.

With this minor change, I could eliminate my global variable and just look at ping_result any time I want to know the status of the last ping.

On one level, I'd like the option for the timer-driven model to be even less involved.  I'd like to start the "ping engine" in setup() and have it ping every 50 usec "forever" without calling ping_timer() again, and be able to just check ping_result any time I like.  I can't call ping_timer(echoCheck) from within echoCheck(), because again, check_timer()'s return value doesn't differentiate between "timed out" and "still waiting".  (And despite being a career developer / system architect, I'll admit that I may be missing something here and that the problem is easily solved.)

If check_timer() returned an int... -1 for "still waiting", 0 for "timed out" and a positive value (distance) for an "echo received", it would be a lot more flexible.  And it would break existing code, since its' an API change.

I suppose I could peek at the timer value itself to see if it's still enabled, but having the library help with that would be ideal.  Maybe a function or variable I could call/look at to find out why check_timer() returned false?  Of course, an alternative function to ping_timer(), say, ping_forever(), that didn't (or optionally) require a echoCheck() and handled running the ping over and over on its own might be ideal.  (And I'll admit, this is what I expected when I first dug into the timer-driven mode.)

I may make some tweaks to the library and see which ideas pan out.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: ravenx99 on Feb 23, 2013, 05:22 am

Quote
Ultrasonic sensors don't work well with petrol/gasoline.

Was the problem simply one of calibration, i.e. the speed of sound in vapour-laden air vs. speed of sound in air?


A bit of searching suggests you may be on the right track, but it's apparently not as simple as a one-time calibration.  The speed of sound changes with the density of the fuel vapor, which varies with temperature.  If the only significant variable is temperature, knowing the temperature inside the tank would make compensation relatively simple.  But the temperature at the sensor  may not be representative of the rest of the tank, so may require a remote sensor.

It had an experienced sensor design engineer stumped, at least for awhile.

I asked my wife, and she said vapor was one issue, and another is that gasoline has a high thermal expansion ratio... to get an accurate volume measurement, you have to know the temperature of the fuel as well as its level.  But that wouldn't be an issue if you're only concerned with "the tank's getting low".    Apparently a float was a cheaper and more reliable method, at least at the time.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Feb 24, 2013, 07:42 pm

I'm building a little robot with an HC-SR04 for obstacle avoidance, and I'm finding NewPing to be very nice.  Thanks for your hard work, Tim.

I'm using NewPing in timer-mode, but I don't really need to do anything inside my echoCheck() function... I just want a distance value to be available to other parts of the code.

Here's where I run into a problem... I'm not seeing a good way to directly determine the difference between "timed out without an echo" and "still waiting for an echo" conditions.  check_ping() returns false in both cases, and x.ping_result is only updated on receiving an echo.  So x.ping_result always indicates the distance of the last successful ping, but it will always be a positive value even when pings are timing out without an echo.

So inside my echoCheck(), I have to assign the value of ping_result to a global variable, and then when I read the global variable elsewhere in the code, I have to remember to set it to zero.  This is effectively doing the same job as ping_result, except it's happening in my code instead of inside NewPing.

Would it make sense for the timeout reset portion of check_ping() to set ping_result back to 0?  ping_result isn't used anywhere else in NewPing, so it wouldn't affect internal behavior.  I don't know how it might affect behavior of existing programs, but I suppose it could.

With this minor change, I could eliminate my global variable and just look at ping_result any time I want to know the status of the last ping.

On one level, I'd like the option for the timer-driven model to be even less involved.  I'd like to start the "ping engine" in setup() and have it ping every 50 usec "forever" without calling ping_timer() again, and be able to just check ping_result any time I like.  I can't call ping_timer(echoCheck) from within echoCheck(), because again, check_timer()'s return value doesn't differentiate between "timed out" and "still waiting".  (And despite being a career developer / system architect, I'll admit that I may be missing something here and that the problem is easily solved.)

If check_timer() returned an int... -1 for "still waiting", 0 for "timed out" and a positive value (distance) for an "echo received", it would be a lot more flexible.  And it would break existing code, since its' an API change.

I suppose I could peek at the timer value itself to see if it's still enabled, but having the library help with that would be ideal.  Maybe a function or variable I could call/look at to find out why check_timer() returned false?  Of course, an alternative function to ping_timer(), say, ping_forever(), that didn't (or optionally) require a echoCheck() and handled running the ping over and over on its own might be ideal.  (And I'll admit, this is what I expected when I first dug into the timer-driven mode.)

I may make some tweaks to the library and see which ideas pan out.


There's no provision in NewPing to track when a ping is in process.  Once a ping is complete, you know if there was no ping or a ping and at what distance.  It's designed to be like an interrupt, where once the ping is complete your code then processes the result.  There's no requirement for the pingResult() function.  That's just there as a sample because most people want to process results as soon as a ping has been completed.  If you don't need it, simply delete it.

What you want to accomplish can be done without any modification to the library.  As your task is specific and different than most, it's best to have this code be in your sketch instead of the library.  This actually allows for more flexibility.  The process of pinging every 50 milliseconds can easily be done with the 15 sensor sketch example.  It doesn't matter if it's in your sketch or inside the NewPing library, it would be just as involved.  Having this inside your sketch allows for exact control as well.

ping_forever() would be a function in your sketch, basically like the 15 sensor sketch.  I've already done the work for you, you just need to impliment it in your sketch.  Having the library do too much would be outside the scope of the library.  It's designed to ping the sensor, not really manage all aspects of when a ping is sent or for how long.  The 15 sensor sketch is your ping_forever() function.  Just use that and add the rest of your code.  Also, be sure to read my post on more details about the 15 sensor sketch (http://arduino.cc/forum/index.php/topic,106043.msg1009294.html#msg1009294), and ways to tweak it for your needs.  I believe you'll find that I've already answered your questions there.

Here's a sample sketch that I whipped up for you that may assist:

Code: [Select]
#include <NewPing.h>

#define SONAR_NUM      3
#define MAX_DISTANCE 200
#define PING_INTERVAL 33

unsigned long pingTimer[SONAR_NUM];
unsigned int cm[SONAR_NUM];
uint8_t currentSensor = 0;
uint8_t pingStatus = 0;

NewPing sonar[SONAR_NUM] = {
  NewPing(4, 5, MAX_DISTANCE),
  NewPing(6, 7, MAX_DISTANCE),
  NewPing(8, 9, MAX_DISTANCE)
};

void setup() {
  Serial.begin(115200);
  pingForever();
}

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    if (millis() >= pingTimer[i]) {
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;
      sonar[currentSensor].timer_stop();
      currentSensor = i;
      cm[currentSensor] = 0;
      pingStatus = 1;
      sonar[currentSensor].ping_timer(echoCheck);
    }
  }
 
  /*
  At any time, you can get the value of pingStatus, currentSensor,
  or read the values of the last pings in the cm[] array.  It's
  up to you to figure out what you want to do with this data.
  */
}

void pingForever() {
  pingTimer[0] = millis();
  for (uint8_t i = 1; i < SONAR_NUM; i++) pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void pingStop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) pingTimer[i] = -1;
  pingStatus = 0;
}

void echoCheck() {
  if (sonar[currentSensor].check_timer()) {
    cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
    pingStatus = 0;
  }
}


Beyond this, and the 15 sensor sketch help post, you'll need to post your sketch for me to offer suggestions.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Feb 24, 2013, 07:46 pm

I asked my wife, and she said vapor was one issue, and another is that gasoline has a high thermal expansion ratio... to get an accurate volume measurement, you have to know the temperature of the fuel as well as its level.  But that wouldn't be an issue if you're only concerned with "the tank's getting low".    Apparently a float was a cheaper and more reliable method, at least at the time.


I would also suggest a float because then the electronics can be placed outside the tank with only the float on the inside.  Putting electronics inside fuel vapor doesn't sound like a good ideal.  Actually, it sounds like a very bad idea.  A short could result in a spark which results in a very bad day.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: oigres666 on Feb 28, 2013, 12:39 pm
Hi everyone, I would like to ask if it's possible to hold a value, I mean, if I remove my hand from the sensor, then the sensor measure out of range, I would like that the last value sent for serial (usb) was the measure from my hand to the sensor before remove... This is my sketch which I found in this post, BTW really useful!!!

Code: [Select]
#include <NewPing.h>

#define SONAR_NUM     4 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 0;          // Keeps track of which sensor is active.

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

void setup() {
  Serial.begin(115200);
  pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
  for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
    pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }
  }
  // The rest of your code would go here.
 
}

void echoCheck() { // If ping received, set the sensor distance to array.
  if (sonar[currentSensor].check_timer())
    cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
  for (uint8_t i = 0; i < SONAR_NUM; i++) {
      Serial.print(cm[i]);
}
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Feb 28, 2013, 04:44 pm

Hi everyone, I would like to ask if it's possible to hold a value, I mean, if I remove my hand from the sensor, then the sensor measure out of range, I would like that the last value sent for serial (usb) was the measure from my hand to the sensor before remove... This is my sketch which I found in this post, BTW really useful!!!


You would write your sketch to hold a value.  Once one cycle of pinging all the sensors is complete, it goes to the oneSensorCycle() function.  This is where you would analyze the results.  If you wanted to hold those results and stop pinging, this is where you would do it.  The 15 sensor sketch help post (http://arduino.cc/forum/index.php/topic,106043.msg1009294.html#msg1009294) shows how you would stop the ping process and resume.  If you only want to know when something is in the way of one of the sensors and then hold those results.  In the oneSensorCycle() function you would detect something was in the way, stop the pings, and do whatever you wanted with that information.  When you wanted to restart the pings, you would use the restart code.

That's about the best I can do shy of writing your script for you, and what fun would that be?

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: oigres666 on Feb 28, 2013, 04:51 pm


Hi everyone, I would like to ask if it's possible to hold a value, I mean, if I remove my hand from the sensor, then the sensor measure out of range, I would like that the last value sent for serial (usb) was the measure from my hand to the sensor before remove... This is my sketch which I found in this post, BTW really useful!!!


You would write your sketch to hold a value.  Once one cycle of pinging all the sensors is complete, it goes to the oneSensorCycle() function.  This is where you would analyze the results.  If you wanted to hold those results and stop pinging, this is where you would do it.  The 15 sensor sketch help post (http://arduino.cc/forum/index.php/topic,106043.msg1009294.html#msg1009294) shows how you would stop the ping process and resume.  If you only want to know when something is in the way of one of the sensors and then hold those results.  In the oneSensorCycle() function you would detect something was in the way, stop the pings, and do whatever you wanted with that information.  When you wanted to restart the pings, you would use the restart code.

That's about the best I can do shy of writing your script for you, and what fun would that be?

Tim

Thank you Tim!!! I'm going to work with these advices!!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bassmagnetic on Mar 21, 2013, 08:17 pm
Would NewPing work with a SRF08?

I've been using a HC-SR04 but I've looking for something more accurate at longer distances, to sense body movement accurately up to 3m, is the SRF08 much better?

Or any other suggestions?

The HC-SR04 recognises a body up till about 1.2m, then further away the sensor reports 0, as I guess its sending out a signal but not receiving it back.... but if I hold up a board of wood it sends back an accurate reading up to about 3m
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Mar 21, 2013, 09:28 pm

Would NewPing work with a SRF08?

I've been using a HC-SR04 but I've looking for something more accurate at longer distances, to sense body movement accurately up to 3m, is the SRF08 much better?

Or any other suggestions?

The HC-SR04 recognises a body up till about 1.2m, then further away the sensor reports 0, as I guess its sending out a signal but not receiving it back.... but if I hold up a board of wood it sends back an accurate reading up to about 3m



All the sensors are basically the same, with the same transducers and amps in most cases.  There's just slight differences (like timeouts).  I have several kinds and I would consider most to be almost identical.  Also, keep in mind that the HC-RS04 is not made by one company, many make them, with slight differences.  It could be that you just not one that wasn't too good.

Also, the SRF08 is not better just because the number is bigger.  It's not like it's version 8 so it's better than version 4.  The SRF08 is much larger, uses a lot more power, more expensive, and doesn't use the same interface at all, it uses I2C.  Instead, I would opt for the SRF06 from Yourduino (http://yourduino.com/sunshop2/index.php?l=product_detail&p=115).  There are other models of the SRF06 that have a different interface and connection header.  Those won't work with NewPing as they are very rare.  But, the SRF06 from YourDuino works very well with NewPing and is the best working sensor that I have.  It uses the least amount of power, fastest startup time, and has the longest range of any sensor I have.  The owner of YourDuino is a regular on this forum too as a bonus.

So, I would suggest either trying to buy a few additional cheapo eBay HC-RS04 sensors as you may have better luck.  Or, go with the SRF06 from YourDuino (4 pins).  Keep in mind that ultrasonic sensors are affected by sound absorbing materials, like clothing.  It won't work as well detecting detecting a dog as it will a flat board.  But, keep in mind that this still may give you what you want.  For example, having the sensor hit a far wall and get the distance (say 300cm).  When someone walks in front of the sensor, it will either bounce off and give a distance reading of say 150cm.  Or, maybe all the sound is absorbed so it gives a reading of zero.  That too could be used as a detection trigger, as normally it reads 300cm.  So, whenever there's a reading of anything less than say 280cm (all the way to 0) would mean something was in the way of the sensor.  This may not work in your situation, but it does in some (if the far wall is within the sensor range).

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bassmagnetic on Mar 23, 2013, 04:33 pm
Thanks so much Tim for your reply....

I'm in the UK so I think ordering from Yourduino is a little far... I was also looking at the http://www.maxbotix.com/ (http://www.maxbotix.com/) Maxbotix sensors, have you any experience of these? Prices seem wildly different but can't tell if that means a more accurate sensor?

I have taken your advice and changed my current patch to take into account 0 readings for non-distance people detection, but would really like to try to get accurate distance reading of people up to 3m... especially as the sensors throw out quite a few false 0 readings when there is not a person there....

Also before I said I would post the installation that I am using the sensors for, its here: http://www.apbsound.com/2013/drone/ (http://www.apbsound.com/2013/drone/)

All the best
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Mar 25, 2013, 11:43 pm

Thanks so much Tim for your reply....

I'm in the UK so I think ordering from Yourduino is a little far... I was also looking at the http://www.maxbotix.com/ (http://www.maxbotix.com/) Maxbotix sensors, have you any experience of these? Prices seem wildly different but can't tell if that means a more accurate sensor?

I have taken your advice and changed my current patch to take into account 0 readings for non-distance people detection, but would really like to try to get accurate distance reading of people up to 3m... especially as the sensors throw out quite a few false 0 readings when there is not a person there....

Also before I said I would post the installation that I am using the sensors for, its here: http://www.apbsound.com/2013/drone/ (http://www.apbsound.com/2013/drone/)

All the best


Yourduino is far, but the sensors are cheaper and shipping low so it's not bad at all.  maxbotix.com makes some good sensors.  But, you need to use their libraries or make your own as they do things totally different than all the other ultrasonic sensors.

You can use the ping_median() method if you're not already to get a few readings which could weed out erroneous "no ping" readings.  Looking at the installation, it would seem that would work very well for ultrasonic sensors.  The far wall seems to be within 15 feet and it's a nice big flat wall.  But, maybe it's not working as well as you hoped for another reason.  For example, too much ambient noise or maybe because the sensors are hidden in the wall so the echo isn't as effective returning to the sensor.  I'd be curious how well it works if you placed the sensors outside the wall and there was no other noise in the room.  I know that doesn't help with your goal, but it could be useful for tracking down the problem.  Or, maybe it's the length of the wires you have running to the sensor?

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: CyklKent on Mar 29, 2013, 01:38 am
Is there a way to adjust the sensitivity or have a minimum size of object/return to be used for the result? I ask because if you look at the attached picture you will see the HC-SR04 mounted tipped up at 10 degrees. It will always return the distance to the 1.3" x 2.5" rectangle of cardboard and will never return the distance to the wood door (I like that it does this). However, if I put the 1/16" hex key in the path like in the picture, the sensor will return this shorter distance once in a while. A larger .090" hex key will cause most all returns to be the hex key distance.
I have read to get the sensor well off of the floor, but I don't really have that option. I don't have hex keys in the path, but I used this as an example. Many real world surfaces can cause returns it seems.
Your very good median can be used for a small amount of stray results, but I have found that sometimes the extremely small object returns can be consecutive at times and bad numbers will get through the median. The oscilloscope shows that it must be very difficult to pick out the closest object, but I was hoping to have the ultrasonic ignore the very small returns. I know that this is not in NewPing, but I just wondered if anyone had changed what must be the firmware on the sensor itself.
Thank you.

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: cyclegadget on Mar 29, 2013, 03:16 am
@CyklKent

I have seen some videos where people have put tubing, or short pipe over each half of the sensor. The result looked like binoculars. I think the reason was to make a the sensor's "vision" narrower and allow the sensor to only focus on a smaller area.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Mar 29, 2013, 05:03 pm

Is there a way to adjust the sensitivity or have a minimum size of object/return to be used for the result? I ask because if you look at the attached picture you will see the HC-SR04 mounted tipped up at 10 degrees. It will always return the distance to the 1.3" x 2.5" rectangle of cardboard and will never return the distance to the wood door (I like that it does this). However, if I put the 1/16" hex key in the path like in the picture, the sensor will return this shorter distance once in a while. A larger .090" hex key will cause most all returns to be the hex key distance.
I have read to get the sensor well off of the floor, but I don't really have that option. I don't have hex keys in the path, but I used this as an example. Many real world surfaces can cause returns it seems.
Your very good median can be used for a small amount of stray results, but I have found that sometimes the extremely small object returns can be consecutive at times and bad numbers will get through the median. The oscilloscope shows that it must be very difficult to pick out the closest object, but I was hoping to have the ultrasonic ignore the very small returns. I know that this is not in NewPing, but I just wondered if anyone had changed what must be the firmware on the sensor itself.
Thank you.



As cyclegadget stated, putting the transmitting and/or receiving sensor(s) in a tube can focus the detection to a smaller range.  You can try different length tubes which will give different results.

Also, if you just want to block the ground, tilting it up slightly as you have done is a good method.  If that still doesn't give the desired results, you can add a shield below the sensors.  This is the same concept as the tube, but only blocks stray echos from below, not above.

Other than this, I haven't seen any ultrasonic sensor with any type of sensor adjustability.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: vikirobot on Mar 30, 2013, 02:20 pm
hi  im building obstacle avoidance robot  using two  hs-o4  sensor and two dc motor. im using following code

Code: [Select]
#include <NewPing.h>
#define lp 9// left side motor l293
#define ln 8// left side motor l293
#define rp 7// right side motor l293
#define rn 6// right side motor l293

#define SONAR_NUM     2 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 0;          // Keeps track of which sensor is active.
int leftsensor, rightsensor;
NewPing sonar[SONAR_NUM] = {     // Sensor object array.
  NewPing(13, 12, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(11, 10, MAX_DISTANCE),

};

void setup() {
  Serial.begin(115200);
  pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
  for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
    pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1)
      {
leftsensor =cm[0];
rightsensor =cm[1];
if ((leftsensor >=10) && (rightsensor >=10))
{
  digitalWrite(lp, HIGH);
digitalWrite(ln, LOW);
digitalWrite(rp, HIGH);
digitalWrite(rn, LOW);
Serial.println(" go straight");
Serial.println(cm[0]);
Serial.println(cm[1]);
}

if ((leftsensor <=10) && (rightsensor >=10))
{
digitalWrite(lp, HIGH);
digitalWrite(ln, LOW);
digitalWrite(rn, HIGH);
digitalWrite(rp, LOW);
Serial.println(" right turn");
Serial.println(cm[0]);
Serial.println(cm[1]);
}

if ((leftsensor <=10)&& (rightsensor >=10))
{
digitalWrite(ln, HIGH);
digitalWrite(lp, LOW);
digitalWrite(rn, HIGH);
digitalWrite(rp, LOW);
Serial.println("left turn ");
Serial.println(cm[0]);
Serial.println(cm[1]);

}
if ((leftsensor <=10) && (rightsensor <=10))
{
digitalWrite(lp,  LOW);
digitalWrite(ln, HIGH);
digitalWrite(rn, HIGH);
digitalWrite(rp, LOW);
Serial.println("back");
Serial.println(cm[0]);
Serial.println(cm[1]);




}

if ((leftsensor =0) && (rightsensor =0))
{digitalWrite(lp,  HIGH);
digitalWrite(ln, LOW);
digitalWrite(rn, LOW);
digitalWrite(rp, HIGH);
Serial.println("go stright");
Serial.println(cm[0]);
Serial.println(cm[1]);
 
}
if ((leftsensor =0) && (rightsensor >=10))
{digitalWrite(lp, HIGH);
digitalWrite(ln, LOW);
digitalWrite(rn, HIGH);
digitalWrite(rp, LOW);
Serial.println(" right turn");
Serial.println(cm[0]);
Serial.println(cm[1]);
 
}
if ((leftsensor =0) && (rightsensor >=10))
{digitalWrite(ln, HIGH);
digitalWrite(lp, LOW);
digitalWrite(rn, HIGH);
digitalWrite(rp, LOW);
Serial.println(" left turn");
Serial.println(cm[0]);
Serial.println(cm[1]);


      }
     
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }
  }
  // The rest of your code would go here.

}
}

void echoCheck() { // If ping received, set the sensor distance to array.
  if (sonar[currentSensor].check_timer())
    cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}


by using this the robot is not moving straight but it is rotating in same place slowly and if try to use serial monitor it is not printing any thing

then i tried normal code
Code: [Select]
#define ta 13// trigger
#define ea 12// eco
#define tb 11 // trigger
#define eb 10// eco
#define lp 9// left side motor l293
#define ln 8// left side motor l293
#define rp 7// right side motor l293
#define rn 6// right side motor l293

#define TIMEOUT 40000 // 40ms timeout (the HC-sr04 has 38 ms timeout)

void setup()
{
Serial.begin (19200);
pinMode(lp, OUTPUT);
pinMode(ln, OUTPUT);
pinMode(rp, OUTPUT);
pinMode(rn, OUTPUT);
pinMode(ta, OUTPUT);
pinMode(ea, INPUT);
pinMode(tb, OUTPUT);
pinMode(eb, INPUT);
digitalWrite(ta, LOW); // Ensure triger is starting with low before any pulse
delayMicroseconds(20);// Delay before first pulse
digitalWrite(tb, LOW);
delayMicroseconds(20);
}

void loop()
{
long dua, da,dub,db;

digitalWrite(ta, HIGH); // Start the a  High Pulse

delayMicroseconds(10); // Delay 10 micros

digitalWrite(ta, LOW); // End the Pulse
dua = pulseIn(ea, HIGH, TIMEOUT);
da = (dua/2) / 29.1;

digitalWrite(tb, HIGH); // Start the b High Pulse

delayMicroseconds(10); // Delay 10 micros
digitalWrite(tb, LOW); // End the Pulse
dub = pulseIn(eb, HIGH, TIMEOUT);
db = (dub/2) / 29.1;
if ((da >=10) && (db >=10))
{
 
digitalWrite(lp, HIGH);
digitalWrite(ln, LOW);
digitalWrite(rp, HIGH);
digitalWrite(rn, LOW);
Serial.println(" go straight");
Serial.println(da);
Serial.println(db);
}

if ((da <=10) && (db >=10))
{
digitalWrite(lp, HIGH);
digitalWrite(ln, LOW);
digitalWrite(rn, HIGH);
digitalWrite(rp, LOW);
Serial.println(" right turn");
Serial.println(da);
Serial.println(db);
}

if ((db <=10)&& (da >=10))
{
digitalWrite(ln, HIGH);
digitalWrite(lp, LOW);
digitalWrite(rn, HIGH);
digitalWrite(rp, LOW);
Serial.println("left turn ");
Serial.println(da);
Serial.println(db);

}
if ((da <=10) && (db <=10))
{
digitalWrite(lp,  LOW);
digitalWrite(ln, HIGH);
digitalWrite(rn, HIGH);
digitalWrite(rp, LOW);
Serial.println("back");
Serial.println(da);
Serial.println(db);




}

if ((da =0) && (db =0))
{digitalWrite(lp,  HIGH);
digitalWrite(ln, LOW);
digitalWrite(rn, LOW);
digitalWrite(rp, HIGH);
Serial.println("go stright");
Serial.println(da);
Serial.println(db);
 
}
if ((da =0) && (db >=10))
{digitalWrite(lp, HIGH);
digitalWrite(ln, LOW);
digitalWrite(rn, HIGH);
digitalWrite(rp, LOW);
Serial.println(" right turn");
Serial.println(da);
Serial.println(db);
 
}
if ((db =0) && (da >=10))
{digitalWrite(ln, HIGH);
digitalWrite(lp, LOW);
digitalWrite(rn, HIGH);
digitalWrite(rp, LOW);
Serial.println(" left turn");
Serial.println(da);
Serial.println(db);
 
}
delay(50);
}

it is behaving good in serial monitor that is print turn right when blocked in left and in vice versa...
but in real robot it is rotating in clock wise not moving forward..help me to resolve it
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: cyclegadget on Mar 30, 2013, 04:26 pm

Each movement decision is based on an "if" statement similar to this:
Code: [Select]
if ((da <=10) && (db >=10)

I recommend printing "da = " da ........and print "db = " db....... this will show what those numbers are and if they are changing. There must be a problem related to those two number results.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: vikirobot on Mar 30, 2013, 04:54 pm
most of the time it show zero in one sensor but zero may denote out of range or object very near..and i think taking mean of ping is good idea but dono how to use that method sonar.mean() and new ping is not working good in my program even serial monitor and that is not show any word tx light in uno is not glowing when i use new ping program
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: cyclegadget on Mar 30, 2013, 07:16 pm

Put "0" in the integer postions of this "if" statement.
Code: [Select]
if ((da >=10) && (db >=10))
{
 
digitalWrite(lp, HIGH);
digitalWrite(ln, LOW);
digitalWrite(rp, HIGH);
digitalWrite(rn, LOW);
Serial.println(" go straight");
Serial.println(da);
Serial.println(db);
}


If the either sensor output results as "0" you will not go straight.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: vikirobot on Mar 31, 2013, 06:23 pm
for zero this will work, in that program
Code: [Select]
if ((da =0) && (db =0))
{
digitalWrite(lp,  HIGH);
digitalWrite(ln, LOW);
digitalWrite(rn, LOW);
digitalWrite(rp, HIGH);
Serial.println("go stright");
Serial.println(da);
Serial.println(db);
 
}
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: cyclegadget on Apr 01, 2013, 03:27 am
Code: [Select]
if ((da == 0) && (db == 0)||(da >=10) && (db >=10))


Don't forget TWO == signs when doing a check with an "if" statement.

One = sign is used for setting a variable to a value.

You could add a "or' ||, to add another check. This would say if either number is NOT = 0 and is not greater than 10....go straight.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bassmagnetic on Apr 14, 2013, 08:09 pm
Hi Tim,

In the end I brought some Yourdunino SRF06's. They are accurate at their distance measurements but unfortunately their distance max's out at about 200cm, beyond that they return 0's. I was looking for something which would hopefully be accurate to about 350cm.... I have gone ahead and bought a few of Maxbotix XL EZ0 sensors. Do you think that I could modify your New Ping code to work with these sensors or would I need to start from scratch?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Apr 15, 2013, 06:16 am

Hi Tim,

In the end I brought some Yourdunino SRF06's. They are accurate at their distance measurements but unfortunately their distance max's out at about 200cm, beyond that they return 0's. I was looking for something which would hopefully be accurate to about 350cm.... I have gone ahead and bought a few of Maxbotix XL EZ0 sensors. Do you think that I could modify your New Ping code to work with these sensors or would I need to start from scratch?


Did you set the maximum distance to higher than 200cm?  Mine work well to easily over 400cm.  Maybe it's the size of the object or how sonically reflective it is?  Try using a wall as your maximum distance measurements, that's what the distance specs use.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bassmagnetic on Apr 15, 2013, 08:54 am
Yes, I set the maximum distance at 300 but then the sensors return 0's. All the sensors are pointing at a solid wall 250cm away, but the sensors are returning 0's rather than seeing the wall, thus I'm assuming out of their range. I thought it strange as the Hr04's measured/worked fine over this distance. I've tried different delay times to see if there is any interference, up to 100ms but it makes no difference to the readings
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Apr 15, 2013, 04:17 pm

Yes, I set the maximum distance at 300 but then the sensors return 0's. All the sensors are pointing at a solid wall 250cm away, but the sensors are returning 0's rather than seeing the wall, thus I'm assuming out of their range. I thought it strange as the Hr04's measured/worked fine over this distance. I've tried different delay times to see if there is any interference, up to 100ms but it makes no difference to the readings


Are you sending the sensor 5v?  Other than that, must just be your sensors.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: bassmagnetic on Apr 15, 2013, 04:28 pm
yep, even gave them an external 5v input but no change to the distance.....
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Apr 16, 2013, 10:04 pm

Hi! Fantastic library.

I simply want to use 2 HC-SR04 sensors and use the result to turn on their appropriate LED when MAX_DISTANCE is less than 30.

SR04 #1 - turns on LED1 when MAX_DISTANCE is less than 30
           - turns off LED1 when MAX_DISTANCE is greater than 30

SR04 #2 - turns on LED2 when MAX_DISTANCE is less than 30
           - turns off LED2 when MAX_DISTANCE is greater than 30


I added an if/else statement in the pingResults() function, LED 1 turns ON and remains on when
either sensor is triggered.
What do I have to do to declare both sensor 1 and sensor 2 in the function?  

Sounds pretty simple but I'm kinda new at this so be gentle!  :)

Thanks.


Here's the sketch:

#include <NewPing.h>

#define SONAR_NUM      2
#define MAX_DISTANCE 30
#define PING_INTERVAL 33
//LED setup
#define LED_1   12
#define LED_2   13

unsigned long pingTimer[SONAR_NUM];
uint8_t currentSensor = 0;

NewPing sonar[SONAR_NUM] = {  
 NewPing(4, 5, MAX_DISTANCE),
 NewPing(6, 7, MAX_DISTANCE)  
};

void setup() {
 pinMode(LED_1, OUTPUT);
 pinMode(LED_2, OUTPUT);
 
 Serial.begin(115200);
 pingTimer[0] = millis() + 75;
 for (uint8_t i = 1; i < SONAR_NUM; i++)
   pingTimer = pingTimer[i - 1] + PING_INTERVAL;
}

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);
   }
 }


}

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

void pingResult(uint8_t sensor, int cm) {  // Sensor got a ping, do something with the result.
 // The following code would be replaced with your code that does something with the ping result.
 
   if (cm < MAX_DISTANCE) {  
     digitalWrite(LED_1, HIGH);
 }
    else {
       digitalWrite(LED_1, LOW);
 
 }
 
 for (uint8_t i = 0; i < SONAR_NUM; i++) {
 Serial.print(sensor);
 Serial.print(" ");
 Serial.print(cm);
 Serial.println("cm");
 }
Serial.println();
 
}


The 15 sensor example sketch is more for advanced users that require a multi-tasking type script where multiple things will be happening at basically the same time.  Therefore, your use is well outside these parameters.

Instead, simply use the basic one sensor example sketch and add a second sensor.

Basically, you're trying to make it much more complicated than it needs to be, which is why you're having problems.

Now, if you had an already event driven sketch and you wanted to add two sensors while still keeping your sketch event-driven, then using the 15 sensor sketch would be appropriate.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: powerpsy on May 05, 2013, 03:54 pm
Hi,
I bought a HC-SR04 with Arduino Uno R3.
Without knowing anything, I wired up them together and it works like a charm.
In addition, parameters can be fine tuned (distance, sampling rate...)

Marvellous. It's really plug and play library, and examples given work !
Thank you fo your library.

Sam

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: justme1968 on May 05, 2013, 05:53 pm
some ideas about accuracy...

i have just gotten my sr04 and played a lithe with it. i intend to use it to measure oil level in a tank. so accuracy is quite important.
after reading on the web there are two main points that seem to influence the accuracy of the sensor and both are not accounted for in the newping library:

- one is temperature. it would be nice to be able to set the temperature that newping uses for the conversion to cm/inces. depending on the temperaure the error can easily be in the range of 10% if temperature is not accounted for.

- the other one is the which echo is received and evaluated. if i do repeated measurements i notice that the results will be relatively near around two or tree that are themselves further apart. this looks like it is consistent with some articles that say this error comes from reading the second or third echo and not the first and should be especialy noticeable in the short range.

so to be able to make more accurate measurements i started reading 10 or 50 pings, iterating over all of them and throwing away all that are equal to the largest and all that are equal to the smallest and then averaging the rest. if there are non available after throwing the smallest and largest away i take the smallest. the conversion to cm is then done in float.

this seems to give very accurate and reproduceable results. doing this repeatedly in a range of 1cm to 1m gives identical results up to at least 1mm.

maybe a 'slow scan' option could add this to the newping library for applications where fast response times are not needed.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 06, 2013, 04:32 am

some ideas about accuracy...

i have just gotten my sr04 and played a lithe with it. i intend to use it to measure oil level in a tank. so accuracy is quite important.
after reading on the web there are two main points that seem to influence the accuracy of the sensor and both are not accounted for in the newping library:

- one is temperature. it would be nice to be able to set the temperature that newping uses for the conversion to cm/inces. depending on the temperaure the error can easily be in the range of 10% if temperature is not accounted for.

- the other one is the which echo is received and evaluated. if i do repeated measurements i notice that the results will be relatively near around two or tree that are themselves further apart. this looks like it is consistent with some articles that say this error comes from reading the second or third echo and not the first and should be especialy noticeable in the short range.

so to be able to make more accurate measurements i started reading 10 or 50 pings, iterating over all of them and throwing away all that are equal to the largest and all that are equal to the smallest and then averaging the rest. if there are non available after throwing the smallest and largest away i take the smallest. the conversion to cm is then done in float.

this seems to give very accurate and reproduceable results. doing this repeatedly in a range of 1cm to 1m gives identical results up to at least 1mm.

maybe a 'slow scan' option could add this to the newping library for applications where fast response times are not needed.



1) Because you need an outside thermometer to measure temperature, it was decided not to overly complicate the NewPing library.  However, NewPing *IS* designed to adjust with temperature.  Simply use the ping() method which gives you a time.  Then, do your own calculation of distance based on your thermometer attached to the Arduino.  In almost all situations, the default distance works well for average indoor temperatures.  But, if you need accuracy, you're going to need additional hardware and then (of course) you're going to need to do your own calculation.  But, NewPing will work with this situation just fine.

2) This isn't a problem with the library, nor can it be fixed in a library.  This is fixed by following the instructions in my sample sketches.  Basically, if you ping a second time too quickly after a previous ping, you can get an echo.  This can't be fixed by the library as it's only reading what the sensor outputs, which is a digital signal (the library has no amplitude information).  The solution is to simply heed my warnings in my sketches.  Which is to not ping too quickly.  Your pings shouldn't be more frequently than around once every 29ms.  If you're in a highly sonicly reflective environment, or your sensor is overly sensitive, you may need to increase this amount.  If it's not something fast moving (probably like in your case) ping once every second or two even.  That way, you can be assured that you're not reading an echo.  NewPing doesn't control the speed of the pings *YOU* do.  If you want to make it slow, just make it slow.  Maybe I'm missing something?

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: robtillaart on May 11, 2013, 04:26 pm

Hi Teckel,

did investigate the duration2cm() function here - http://arduino.cc/forum/index.php/topic,165860.0.html -
might be useful in your library.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 20, 2013, 05:05 pm


Hi Teckel,

did investigate the duration2cm() function here - http://arduino.cc/forum/index.php/topic,165860.0.html -
might be useful in your library.


I tried something similar in the past, but honestly it's not worth the extra cycles adding this type of code adds.  Basically, it's pointless to try to make the math more accurate than the sensor is.  Ultrasonic sensors are not very accurate anyway.  Also, there's actually an argument as to the speed of sound (everyone likes to use a different number).  This is why I settled on an integer and the value that I default to.  It provides very accurate distance results in typical indoor temperatures and does so very fast using very little program space.

Instead of getting into this battle, I avoid it.  Just use the ping() method which returns a ping time.  Then, use whatever math you want (based on temperature or whatever).  If you want to use a fraction and want to use a different method to calculate this (like the above linked example) that's fine also.

Keep in mind that NewPing is an ultrasonic ping library, not a floating point, math, or temperature library.  I'm sure you can find or develop a library that allows you to divide a floating point number without using floating point math.  This would be then just included in your sketch along with NewPing to calculate a distance at whatever accuracy level you desired.  But keep in mind that the sensor isn't that accurate anyway (only  about 1cm).  So all this effort may be wasted anyway.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: robtillaart on May 20, 2013, 08:58 pm
The fact that the sensors are not accurate is imho no argument to use math that adds additional errors. The relative errors add up.
That said, I agree with you that most applications do not need this level of accuracy.

Thanks,
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 20, 2013, 09:55 pm

The fact that the sensors are not accurate is imho no argument to use math that adds additional errors. The relative errors add up.
That said, I agree with you that most applications do not need this level of accuracy.

Thanks,


If you want to use floating point values, more power to you, go for it!  NewPing FULLY supports doing this.  *YOU* have the ability to change the US_ROUNDTRIP_CM and US_ROUNDTRIP_IN values to whatever you want, or use ping() and do any other calculations you wish factoring in temperature, altitude, humidity, etc.

The fact is, my integer values are typically more accurate than when people try to over complicate things by using floating point values in attempts to get more accurate values.  But, if you're in search for the holy grail of ultrasonic measurement, use ping() and apply your magic formula.

This is *NOT* something that will be added to NewPing as it's outside the scope of the library to be any more accurate than it is now.  Because, to be more accurate you'd need a thermometer, and apply your own formula.  So, while this is a fine topic, it shouldn't be here as it will never be added to NewPing.  Heck, there's debate on the speed of sound, I'm just staying out of the fight.

Topic closed.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: justme1968 on May 24, 2013, 07:53 pm
yes. i do think you missed something.

if i run the new ping sampe code i get a minimum error of 1cm or 2cm even in an absolutely stable setup, if i change the calculation to float the error is a little bit smaller but still in the range of 1cm. and both will give no stable values. the results fluctuate with ever line on the console.

if i use my 'slow' method to measure i get an error that is in the range of 1mm and absolutely stable values. no fluctuation. repeated measurements give the same distance again and again.

this is a huge difference for my application. and now it makes sense to appy the temperature correction.

if you say that this is not your intendet usage scenario that is fine with me. but to say the sensors are inherently so bad that nothing can be done ist just plain wrong.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 24, 2013, 08:36 pm

yes. i do think you missed something.

if i run the new ping sampe code i get a minimum error of 1cm or 2cm even in an absolutely stable setup, if i change the calculation to float the error is a little bit smaller but still in the range of 1cm. and both will give no stable values. the results fluctuate with ever line on the console.

if i use my 'slow' method to measure i get an error that is in the range of 1mm and absolutely stable values. no fluctuation. repeated measurements give the same distance again and again.

this is a huge difference for my application. and now it makes sense to appy the temperature correction.

if you say that this is not your intendet usage scenario that is fine with me. but to say the sensors are inherently so bad that nothing can be done ist just plain wrong.


Maybe you need to turn on rounding in the header file?  #define ROUNDING_ENABLED true

I get stable values with no fluctuations with my library without any modifications with all the sensors I have.

The math doesn't change from sensor reading to sensor reading.  So, if the sensor is outputting the exact same ping time, the exact same distance calculation will occur.  With this said, it does depend on how it's rounded.  By default, NewPing truncates the distance calculation.  So if the distance is say 50.95cm it could flip between 50 and 51cm.  This has to do with the margin of error of the sensor, which is around 0.33cm.  With the rounding enabled, the same situation as shown above would yield a stable 51cm.

I think you've confused the accuracy of the sensors and the method of time to distance calculation.  But, in all cases, you can simply just use the ping() method which just gives you the ping time.  Then, you can do whatever logic you wish to convert this to a distance.  The ping_cm() and ping_in() methods are meant to be a down and dirty, fast, and tight way of getting accurate results.  This works for 99.9% of people best.  But, if you're in the 0.01% that must use a different formula and use a thermometer to get more accurate results, NewPing is already set to work for you, just use the ping() method.

Basically, what I'm saying is that you should use the ping() method and use your own math.  NewPing is not the place to debate the speed of sound (which is yet another debate that 0.01% of people want to get into).  I'm not getting into this and won't be changing NewPing making it bigger and more complex for 0.01% of people.  One of the primary goals of NewPing is to be smaller and faster than other ping libraries.  While adding rounding and temperature calculations could make it ever so slightly more accurate, it's simply not within the scope of the project, and what the ping() method is exactly designed for.  So please, use ping() and this can be the last I hear of time to distance calculations, it's an old, dead, and boring topic that I don't wish to debate further.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: chambo622 on Jun 16, 2013, 12:59 am
I'm trying to use an SR04 with the single-pin method, but I can't get it to work.  I've tried it with two different identical looking sensors purchased from Amazon and eBay.  This is on an Arduino Uno (might be a SainSmart recreation but it looks like an authentic one, not sure.

What troubleshooting steps can I try?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jun 18, 2013, 06:48 pm

I'm trying to use an SR04 with the single-pin method, but I can't get it to work.  I've tried it with two different identical looking sensors purchased from Amazon and eBay.  This is on an Arduino Uno (might be a SainSmart recreation but it looks like an authentic one, not sure.

What troubleshooting steps can I try?


Start with supplying your sketch, schematic, and exactly what your results are. "can't get it to work" is too vague to diagnose over the internet with no other information.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: MetalEd222 on Jul 01, 2013, 10:45 am
really new to arduino and coding, so I am trying to figure out this library.  I have been searching and trying things out on my own, but haven't see any examples of using the 2 commands the way I am attempting.  I think I have figured it out... at least it appears this snippet of my code is working.
What I am trying to do with this is return the center reading (median) out of 15. using convert_in to convert it to inches. I figure returning 15 readings, choosing the median one is the middle between the high and low readings.
Is this correct?

centerDist = (sonar.convert_in(sonar.ping_median(15)));
//median ping (out of 15), distance in inches and assign to centerDist on sensor named "sonar"

I run it and it seems to give me a very accurate reading, in inches.  Is there anything wrong with this format?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jul 01, 2013, 04:56 pm

really new to arduino and coding, so I am trying to figure out this library.  I have been searching and trying things out on my own, but haven't see any examples of using the 2 commands the way I am attempting.  I think I have figured it out... at least it appears this snippet of my code is working.
What I am trying to do with this is return the center reading (median) out of 15. using convert_in to convert it to inches. I figure returning 15 readings, choosing the median one is the middle between the high and low readings.
Is this correct?

centerDist = (sonar.convert_in(sonar.ping_median(15)));
//median ping (out of 15), distance in inches and assign to centerDist on sensor named "sonar"

I run it and it seems to give me a very accurate reading, in inches.  Is there anything wrong with this format?


That's correct.  That command will return the median distance measurement in inches out of 15 pings.  With that many iterations, it should give very stable results.

If you find that the distance is slightly off, it's because of the convert_in() math, which by default simply divides the ping microseconds by 146.  For example, the following code will give the same result:

Code: [Select]
centerDist = sonar.ping_median(15) / 146;

If you find that you need more accurate conversion from ping time to distance and wish to create a calculation based on temperature readings, you can replace the division by 146 (or the convert_in()) to whatever calculation you wish based on temperature, altitude, humidity, or whatever level of accuracy you wish.  The convert_in() is designed to be fast, create small code, not require additional sensors, and be fairly accurate for almost all users.  If you need higher accuracy, you can use whatever calculations you wish with NewPing.

Tim
Title: Multiple Definition of `__vector_7' Error When Compiling
Post by: teckel on Jul 11, 2013, 07:17 pm
A common problem with using NewPing is getting a `__vector_7' error during compile.  What this error means is that you're using two libraries that are both trying to use timer 2.  The timer 2 stuff is only in NewPing for the timer interrupt method ping_timer().  If you're just using the standard ping(), ping_in(), ping_cm(), or ping_median() methods, NewPing is not using timer 2.  However, the compiler is not smart enough to know that you're not using those interrupts. So you'll get this error if any other library is also using timer 2.

There's an easy solution as long as you're not using ping_timer().  Change the NewPing.cpp program and comment out the section that calls timer 2.  Find this section at around lines 210 - 216 in version 1.5:

Code: [Select]

#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
ISR(TIMER4_OVF_vect) {
#else
ISR(TIMER2_COMPA_vect) {
#endif
if(intFunc) intFunc(); // If wrapped function is set, call it.
}


Comment it all out like this:

Code: [Select]

/*
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
ISR(TIMER4_OVF_vect) {
#else
ISR(TIMER2_COMPA_vect) {
#endif
if(intFunc) intFunc(); // If wrapped function is set, call it.
}
*/


That's it!  Also, if the conflict is with the tone library, you can use a different tone library that doesn't use timer 2.  I've created a couple tone replacement libraries that not only use timer 1 instead of timer 2 to avoid a conflict, they also have many other advantages:

NewTone (https://code.google.com/p/arduino-new-tone/) - About 1,200 bytes smaller code size than the standard tone library. Faster execution time. Exclusive use of port registers for fastest and smallest code. Higher quality sound output than tone library. Plug-in replacement for Tone. Uses timer 1 which may free up conflicts with the tone library.

toneAC (https://code.google.com/p/arduino-tone-ac/) - Nearly twice the volume (because it uses two out of phase pins in push/pull fashion). Higher quality (less clicking). Capability of producing higher frequencies (even if running at a lower clock speed). Nearly 1.5k smaller compiled code. Bug fixes (standard tone library can generate some odd and unpredictable results). Can set not only the frequency but also the sound volume. Less stress on the speaker so it will last longer and sound better.

In addition, version 1.6 of the NewPing library (currently under development) will include a setting that allows you to easily turn off the timer 2 stuff if you're not using the ping_timer() method.

If, however you are using the ping_timer() method you still may have options.

First, do you really need to use the ping_timer() method?  Many people incorrectly assume that if they're using multiple sensors they must use the ping_timer() method shown in my 15 sensor example.  That's simply not the case.  It's best to do it that way for "multitasking" reasons.  But, there's no reason why you can't just ping() multiple sensors like in the NewPingExample sketch.

Secondly, maybe you can use a different library that's causing the timer 2 conflict.  I've shown two other tone libraries above that use timer 1 instead of timer 2.  But, if the timer 2 conflict is with a different library, there's still a chance that you have another option.  For example, maybe the timer 2 conflict is with an LED dimmer library.  Try to find another LED dimmer library that uses timer 1 instead.  While this may not be an option for every library, there are many libraries out there so it's worth looking into.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: terryking228 on Jul 14, 2013, 02:16 am
Hi Tim,

This is great information! Many people have no idea about timers and conflicts.

Can you include this in the NewPing documentation, or point to this post there?  I KNOW I'll need this in the future..
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jul 15, 2013, 04:20 pm

Hi Tim,

This is great information! Many people have no idea about timers and conflicts.

Can you include this in the NewPing documentation, or point to this post there?  I KNOW I'll need this in the future..



I have this post linked from the opening post in this thread.  Also, I created Wiki pages for this as well as another common question here: https://code.google.com/p/arduino-new-ping/w/list

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: terryking228 on Jul 15, 2013, 10:27 pm
Thanks, Tim!  I linked to your WIKI pages from the ArduinoInfo.Info WIKI here:
http://arduino-info.wikispaces.com/UltraSonicDistance
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: robtillaart on Jul 22, 2013, 12:06 pm
Please use code tags (# button above the smileys)
Please press CTRL-T in the IDE to autoformat the layout before copying, makes it far more readable and debugable,

Thank you
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: kevin8 on Jul 22, 2013, 07:27 pm
Quote


// walkerForwardComplete.pde - Two servo walker.
// Complete code with obstacle avoidance
// (c) Kimmo Karvinen & Tero Karvinen http://BotBook.com
// Updated by Joe Saavedra, 2010
#include <Servo.h>

Servo frontServo;  
Servo rearServo;  
/* Servo motors - global variables */
int centerPos = 90;
int frontRightUp = 72;
int frontLeftUp = 108;
int backRightForward = 75;
int backLeftForward = 105;
int walkSpeed = 150; // How long to wait between steps in milliseconds
int centerTurnPos = 81;
int frontTurnRightUp = 63;
int frontTurnLeftUp = 117;
int backTurnRightForward = 66;
int backTurnLeftForward = 96;

/* Ping distance measurement - global variables */
int pingPin = 4;
long int duration, distanceInches;
long distanceFront=0; //cm
int startAvoidanceDistance=20; //cm

long microsecondsToInches(long microseconds)
{
 return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
 return microseconds / 29 / 2;
}

long distanceCm(){
 pinMode(pingPin, OUTPUT);
 digitalWrite(pingPin, LOW);
 delayMicroseconds(2);
 digitalWrite(pingPin, HIGH);
 delayMicroseconds(5);
 digitalWrite(pingPin, LOW);

 pinMode(pingPin, INPUT);
 duration = pulseIn(pingPin, HIGH);

 distanceInches = microsecondsToInches(duration);
 return microsecondsToCentimeters(duration);
}

void center()
{
 frontServo.write(centerPos);
 rearServo.write(centerPos);  
}

void moveForward()
{
 frontServo.write(frontRightUp);
 rearServo.write(backLeftForward);
 delay(125);
 frontServo.write(centerPos);
 rearServo.write(centerPos);
 delay(65);
 frontServo.write(frontLeftUp);
 rearServo.write(backRightForward);
 delay(125);

 frontServo.write(centerPos);
 rearServo.write(centerPos);
 delay(65);
}

void moveBackRight()
{
 frontServo.write(frontRightUp);
 rearServo.write(backRightForward-6);
 delay(125);
 frontServo.write(centerPos);
 rearServo.write(centerPos-6);
 delay(65);
 frontServo.write(frontLeftUp+9);
 rearServo.write(backLeftForward-6);
 delay(125);

 frontServo.write(centerPos);
 rearServo.write(centerPos);
 delay(65);
}

void moveTurnLeft()
{
 frontServo.write(frontTurnRightUp);
 rearServo.write(backTurnLeftForward);
 delay(125);
 frontServo.write(centerTurnPos);
 rearServo.write(centerTurnPos);
 delay(65);
 frontServo.write(frontTurnLeftUp);
 rearServo.write(backTurnRightForward);
 delay(125);

 frontServo.write(centerTurnPos);
 rearServo.write(centerTurnPos);
 delay(65);
}

void setup()
{
 frontServo.attach(2);
 rearServo.attach(3);
 pinMode(pingPin, OUTPUT);
}  

void loop()
{
 distanceFront=distanceCm();
 if (distanceFront > 1){ // Filters out any stray 0.00 error readings
   if (distanceFront<startAvoidanceDistance) {
     for(int i=0; i<=8; i++) {
       moveBackRight();
       delay(walkSpeed);
     }
     for(int i=0; i<=10; i++) {
       moveTurnLeft();
       delay(walkSpeed);
     }
   }
   else {
     moveForward();
     delay(walkSpeed);
   }
 }
}






Moderator edit: Please don't use copy for forum - just cut and paste between code tags.

Was there a question?  AWOL
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: kevin8 on Jul 23, 2013, 06:49 am
Good day

Sorry I am new to this forum and Arduino. With regards to the insect bot code I posted. The question was, how do I addapt the code to use a 4 pin ultrasonic sensor.

Kind regards

Kevin
Title: NewPing - last bit of performance
Post by: robvoi on Jul 23, 2013, 03:47 pm
Hi,

first - big thanks for this fantastic library. I used it in two projects so far. Works perfectly.
With my new project I am pushing the Arduino Mega to its limits. I need to drive two steppers - that's the time critical part.
When I enable the pings (using the timer from the 15 sensor example) they sometimes start to stutter as it can't keep the step frequency. As far as I can see it's when the distance to ping is high. If I hold my hand in front of the sensor it's much better.

I went through all the rest of my code. No delays (all implemented as FSM) and no unnecessary complicated calculations.

So I thought it might be possible to get out the last bit of performance with direct addressing of the pins (http://forum.arduino.cc/index.php/topic,46896.0.html) and with an alternative solution on the micros delays in newPing::ping_trigger()
But it is above my capabilities. I assume if it would be simple it would be in the library  XD

Does someone see an "easy" to implement approach? Or am I on the wrong track at all?

Thanks
Robert
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jul 24, 2013, 12:01 pm

Good day

Sorry I am new to this forum and Arduino. With regards to the insect bot code I posted. The question was, how do I addapt the code to use a 4 pin ultrasonic sensor.

Kind regards

Kevin


You would change the distanceCm() routine to accommodate a different sensor.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: kevin8 on Jul 24, 2013, 01:11 pm
If I understand correctly, I should change the ping pin to trigger pin and add a routine with the echo pin as an input.  I'm sorry that I'm asking in detail, but I'm new to this and my strong point is not programming.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jul 24, 2013, 03:44 pm

If I understand correctly, I should change the ping pin to trigger pin and add a routine with the echo pin as an input.  I'm sorry that I'm asking in detail, but I'm new to this and my strong point is not programming.



You would replace that entire routine with something similar to the NewPing example sketch. Probably best to get the sensor working with just the example sketch and then implement it as a replacement to the distanceCm() routine.

Tim
Title: Re: NewPing - last bit of performance
Post by: teckel on Jul 24, 2013, 03:52 pm

Hi,

first - big thanks for this fantastic library. I used it in two projects so far. Works perfectly.
With my new project I am pushing the Arduino Mega to its limits. I need to drive two steppers - that's the time critical part.
When I enable the pings (using the timer from the 15 sensor example) they sometimes start to stutter as it can't keep the step frequency. As far as I can see it's when the distance to ping is high. If I hold my hand in front of the sensor it's much better.

I went through all the rest of my code. No delays (all implemented as FSM) and no unnecessary complicated calculations.

So I thought it might be possible to get out the last bit of performance with direct addressing of the pins (http://forum.arduino.cc/index.php/topic,46896.0.html) and with an alternative solution on the micros delays in newPing::ping_trigger()
But it is above my capabilities. I assume if it would be simple it would be in the library  XD

Does someone see an "easy" to implement approach? Or am I on the wrong track at all?

Thanks
Robert


NewPing is already using port register calls like in digitalWriteFast, so no additional speed would be gained. If there is a timing problem, it has nothing to do with the ATmega processor. The issue would be with the sensor and how quickly you are trying to ping. There's set delays and dead periods with ultrasonic sensors. Try changing the ping to once every 100ms, that get around any kind of delay inherent with the sensor. If you still have a problem, please post your code so someone can maybe point you in the right direction.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: kevin8 on Jul 24, 2013, 04:00 pm
Thank you time. I will try it out tonight.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: ultimatehell on Aug 08, 2013, 04:02 am
hi ;) i spent the past hour trying to figure this out, but just couldnt find an answer ;) so excuse me if i missed it!

here goes:

i want to use a HC-SR04 single pin solution with an Arduino Mega 2560, on the sketch page someone posted

Quote
This works with an Arduino Mega 2560 and a HC-SR04.

Be aware though that it draws 60-85mA during the 10?s trigger HIGH time from the Arduino pin to overrule the echo LOW, which is beyond the datasheet per-pin maximum (40mA). You can also see a small drop in VCC during these 10?s.


is this true? i want to use 4 of these sensors and that would basicly "overload" 4 pins by double of its specs every couple seconds and potentialy damage the arduino?

i dont really see a reason for this using up to 85mA on the ping pin since it should only draw those amounts of power from the 5V connection, or am i wrong?

i do not have the sensors here yet so i can not measure this my self currently ;) so i figured i just ask :) thank you for your reply!

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Aug 08, 2013, 09:53 pm

hi ;) i spent the past hour trying to figure this out, but just couldnt find an answer ;) so excuse me if i missed it!

here goes:

i want to use a HC-SR04 single pin solution with an Arduino Mega 2560, on the sketch page someone posted

Quote
This works with an Arduino Mega 2560 and a HC-SR04.

Be aware though that it draws 60-85mA during the 10?s trigger HIGH time from the Arduino pin to overrule the echo LOW, which is beyond the datasheet per-pin maximum (40mA). You can also see a small drop in VCC during these 10?s.


is this true? i want to use 4 of these sensors and that would basicly "overload" 4 pins by double of its specs every couple seconds and potentialy damage the arduino?

i dont really see a reason for this using up to 85mA on the ping pin since it should only draw those amounts of power from the 5V connection, or am i wrong?

i do not have the sensors here yet so i can not measure this my self currently ;) so i figured i just ask :) thank you for your reply!


Anyone can post any comment, incorrect or not.  I believe this person is just seeing a normal spike they would see with two pins as well.  It's also only for 10?s.  But, you could use a diode across the trigger and echo pins instead of just a jumper.  That would prevent any current from going to the echo pin if you're really worried about this.  I would have no way to accurately measure the current drawn for only 10?s.  But, I'd highly doubt it was 60-85mA.  I've also ran sensors for days and never had a problem.  I have done current draw measurements, but they were substantially lower.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: ultimatehell on Aug 08, 2013, 10:03 pm
great, exactly the response i expected ... just wanted to make sure :D thank you very much!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: jahue on Sep 19, 2013, 05:28 pm
I currently have an issue where I am trying to replace a proximity sensor, with a ping sensor... this is mostly due to distance issues (not enough)

The following code works for proximity...
Code: [Select]
const int sensorPin1 = 0; //analog pin 0
const int ledPin1 = 9;   // LED1,   connected to digital pin 9

const int sensorPin2 = 1; //analog pin 0
const int ledPin2 = 10;   // LED2,   connected to digital pin 9

const int sensorPin3 = 2; //analog pin 0
const int ledPin3 = 11;   // LED3,   connected to digital pin 9

int sensorValue1, sensorValue2, sensorValue3;

int ledVal1 = 0;
int ledVal2 = 0;
int ledVal3 = 0;
unsigned long lastFullBrightnessTimeL1 = 0;
const unsigned long fullBrightnessIntervalL1 = 5000;
unsigned long lastFadeTimeL1 = 0;

unsigned long lastFullBrightnessTimeL2 = 0;
const unsigned long fullBrightnessIntervalL2 = 5000;
unsigned long lastFadeTimeL2 = 0;


#include <NewPing.h>

#define TRIGGER_PIN  7  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     7  // 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 sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.


//const unsigned long fadeInterval = 1;

void setup() {
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);// sets the pins as output
  // pinMode(s3Pin, INPUT);
  Serial.begin(9600);  // ...set up the serial ouput in 0004 format
}

// Main program
void loop() {
  unsigned long currentMillis = millis();
  sensorValue1 = analogRead(sensorPin1);
  sensorValue2 = analogRead(sensorPin2);
  sensorValue3 = analogRead(sensorPin3);


   // Set 1
    if (sensorValue1 >= 150) {  // Person in range
      if (ledVal1 <= 254)
        ledVal1++;
      else
        lastFullBrightnessTimeL1 = currentMillis;
    }
       
    else { // Person has moved away   
      if (ledVal1 >= 1 && currentMillis - lastFullBrightnessTimeL1 > fullBrightnessIntervalL1)
        ledVal1--;
    }

    if (sensorValue1 <= 150 && ledVal1 <= 1)
  { ledVal1 = 0;
    analogWrite(ledPin1, ledVal1);
  }   
   
    analogWrite(ledPin1, ledVal1);
   
   
   //Set 2
   
   
   if (sensorValue2 >= 90) {  // Person in range
      if (ledVal2 <= 254)
        ledVal2++;
      else
        lastFullBrightnessTimeL2 = currentMillis;
    }
       
    else { // Person has moved away   
      if (ledVal2 >= 1 && currentMillis - lastFullBrightnessTimeL2 > fullBrightnessIntervalL2)
        ledVal2--;
    }

    if (sensorValue2 <= 90 && ledVal2 <= 1)
  { ledVal2 = 0;
    analogWrite(ledPin2, ledVal2);
  }   
   
    analogWrite(ledPin2, ledVal2);
   
   
   
   //Set3
      // delay(50);
  //Serial.println(sensorValue1);
  Serial.println(sensorValue1);

 
}


I moved over to the Arduino base ping sensor and was getting to many fluctuations and problems with the built in delay... so I tried your version. Much better, but I am having issues with the LEDs. The fade kinda works however it is incredibly slow, and flickers and locks on and never goes off sometimes. The original fade, builds in fairly quickly and builds out after a set time if no ones around.

The whole installation works like this, as some one approaches the LED is triggered and it fades up, if you don't get inside the set distance then it fades back out, if you get inside or stand for a brief period of time the LED locks on for a set amount of time then if the sensor goes back to reading outside of the set distance the LED fades out but only after a set amount of time.

I tried this code, Side note, I need to run several sensors and several different lights at the same time all doing their own thing. I am running all power externally (conditioned block).

Code: [Select]
#include <NewPing.h>

#define SONAR_NUM      3
#define MAX_DISTANCE 200
#define PING_INTERVAL 33

unsigned long pingTimer[SONAR_NUM];
uint8_t currentSensor = 0;

NewPing sonar[SONAR_NUM] = {
  NewPing(7, 7, MAX_DISTANCE),
  NewPing(6, 6, MAX_DISTANCE),
  NewPing(5, 5, MAX_DISTANCE)
};

const int sensorPin1 = 0; //analog pin 0
const int ledPin1 = 9;   // LED1,   connected to digital pin 9
//int sensorValue1, sensorValue2, sensorValue3;

int ledVal1 = 0;
unsigned long lastFullBrightnessTimeL1 = 0;
const unsigned long fullBrightnessIntervalL1 = 5000;
unsigned long lastFadeTimeL1 = 0;

unsigned long lastFullBrightnessTimeL2 = 0;
const unsigned long fullBrightnessIntervalL2 = 5000;
unsigned long lastFadeTimeL2 = 0;


void setup() {
  Serial.begin(115200);
  pinMode(ledPin1, OUTPUT);
  //pinMode(ledPin2, OUTPUT);
// pinMode(ledPin3, OUTPUT);// sets the pins as output
  pingTimer[0] = millis() + 75;
  for (uint8_t i = 1; i < SONAR_NUM; i++)
    pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void loop() {
 
 
  for (uint8_t i = 0; i < SONAR_NUM; i++) {
    if (millis() >= pingTimer[i]) {
      pingTimer[i] += 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 sensor1) {
  unsigned long currentMillis = millis();
  if (sensor1 <= 20) {  // Person in range
      if (ledVal1 <= 254)
        ledVal1++;
      else
        lastFullBrightnessTimeL1 = currentMillis;
    }
       
    else { // Person has moved away   
      if (ledVal1 >= 1 && currentMillis - lastFullBrightnessTimeL1 > fullBrightnessIntervalL1)
        ledVal1--;
    }

    if (sensor1 >= 20 && ledVal1 <= 1)
  { ledVal1 = 0;
    analogWrite(ledPin1, ledVal1);
  }   
   
    analogWrite(ledPin1, ledVal1);
 
  // The following code would be replaced with your code that does something with the ping result.
  Serial.println(sensor1);
  //Serial.print(" ");
  //Serial.print(cm);
  //Serial.println("cm");
}
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Sep 19, 2013, 09:01 pm

I moved over to the Arduino base ping sensor and was getting to many fluctuations and problems with the built in delay... so I tried your version. Much better, but I am having issues with the LEDs. The fade kinda works however it is incredibly slow, and flickers and locks on and never goes off sometimes. The original fade, builds in fairly quickly and builds out after a set time if no ones around.

The whole installation works like this, as some one approaches the LED is triggered and it fades up, if you don't get inside the set distance then it fades back out, if you get inside or stand for a brief period of time the LED locks on for a set amount of time then if the sensor goes back to reading outside of the set distance the LED fades out but only after a set amount of time.


Probably best to first take a look at my Help for the 15 Sensors Example Sketch (https://code.google.com/p/arduino-new-ping/wiki/HELP_15_Sensors_Example_Sketch).  My guess is that you want to constantly make changes to the LED brightness and not just after a ping happens.  Better understanding and other example code for using the 15 sensor example sketch may help.  Without building your circuit, I can't really tell what you're trying to accomplish or why it's not working.  If the distances you are getting from the sensors using NewPing are correct, then the problem must be either with when you're executing the rest of the code or what your other code is doing.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: jahue on Sep 19, 2013, 09:48 pm
Quote
Probably best to first take a look at my Help for the 15 Sensors Example Sketch.  My guess is that you want to constantly make changes to the LED brightness and not just after a ping happens.  Better understanding and other example code for using the 15 sensor example sketch may help.  Without building your circuit, I can't really tell what you're trying to accomplish or why it's not working.  If the distances you are getting from the sensors using NewPing are correct, then the problem must be either with when you're executing the rest of the code or what your other code is doing.


Thanks, I'm still working on it, I have been trying to use the 15Sensor example. The circuit for this thing is dead simple... ping sensor and led. The biggest problems I am having is when a distance is hit lets say 100cm the led should fade up and lock on for a few seconds, if the 100cm is still triggered then the led stays full bright, if the 100cm goes back to 200 then the led holds for 5 seconds and then fades to off. The fade up is only suppose to last as long as it takes for the Arduino to ++ count to 255 but with the current code the ramp up to 255 is really slow.

Thanks for the help.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: NeilM_CB24 on Oct 12, 2013, 07:58 pm
I have downloaded the zip and unpacked it. I can see it in my Sketchbook folder as NewPing. When I load the NewPingExample sketch and try to compile I get the following errors:

Arduino: 1.5.4 (Windows 7), Board: "Arduino Uno"

C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -MMD -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=154 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard C:\Users\Neil\AppData\Local\Temp\build1329833015507385255.tmp\NewPingExample.cpp -o C:\Users\Neil\AppData\Local\Temp\build1329833015507385255.tmp\NewPingExample.cpp.o

NewPingExample:11: error: 'NewPing' does not name a type
NewPingExample.ino: In function 'void loop()':
NewPingExample:19: error: 'sonar' was not declared in this scope
NewPingExample:21: error: 'US_ROUNDTRIP_CM' was not declared in this scope

Can anyone tell what's wrong and what I need to do to fix it?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: terryking228 on Oct 14, 2013, 03:01 am
Hi Neil,

Your NewPing library is not in the right place. It goes INSIDE the "libraries" folder in your sketchbook.

See the http://ArduinoInfo.Info WIKI and click on "Arduino Software Libraries"...



Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Antoan on Oct 24, 2013, 09:36 pm
I got a lot of bad readings. Is it normal?
Something like this....
Code: [Select]
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 185cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 186cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 187cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 185cm
Ping: 185cm
Ping: 180cm
Ping: 185cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 185cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Ping: 0cm
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: dbinaz on Oct 27, 2013, 07:45 am
Hi all,

Pretty new to this, but I got a Parallex PING today. It works with the old code, but with NewPing I get 0cm back no matter what.
Once I get this figured out, I want to try and get the 2 dual 7 segment LED's to work with it to use it as a parking guide.

Code: [Select]
#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(115200);
}

void loop() {
  delay(50);
  int uS = sonar.ping();
  Serial.print("Ping: ");
  Serial.print(uS / US_ROUNDTRIP_CM);
  Serial.println("cm");
}


Thx.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: RbSCR on Oct 27, 2013, 09:51 am
Code: [Select]
#define TRIGGER_PIN  12
#define ECHO_PIN     11


Why are you using different pinnumbers for the trigger- and echopin ?
The Parallex PING [at least the one I have] has a combined echo/trigger pin.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: sfranzyshen on Nov 08, 2013, 08:33 pm
I had the need to change the max_cm_distance after the constructor ... so I added a couple of functions to handle this ...

unsigned int get_max_cm_distance()
void set_max_cm_distance(int max_cm_distance)

Code: [Select]

--- NewPing/NewPing.h 2012-08-15 18:06:40.000000000 -0700
+++ Arduino/libraries/NewPing/NewPing.h 2013-11-08 10:34:16.495017080 -0800
@@ -132,6 +132,8 @@
class NewPing {
public:
NewPing(uint8_t trigger_pin, uint8_t echo_pin, int max_cm_distance = MAX_SENSOR_DISTANCE);
+ unsigned int get_max_cm_distance();
+ void set_max_cm_distance(int max_cm_distance = MAX_SENSOR_DISTANCE);
unsigned int ping();
unsigned int ping_in();
unsigned int ping_cm();
@@ -152,6 +154,7 @@
volatile uint8_t *_triggerOutput;
volatile uint8_t *_triggerMode;
volatile uint8_t *_echoInput;
+ unsigned int _maxCMDistance;
unsigned int _maxEchoTime;
unsigned long _max_time;
static void timer_setup();
@@ -159,4 +162,4 @@
};

--- NewPing/NewPing.cpp 2012-08-15 18:01:10.000000000 -0700
+++ Arduino/libraries/NewPing/NewPing.cpp 2013-11-08 10:35:21.943341620 -0800
@@ -13,6 +13,7 @@
// ---------------------------------------------------------------------------

NewPing::NewPing(uint8_t trigger_pin, uint8_t echo_pin, int max_cm_distance) {
+ _maxCMDistance = min(max_cm_distance, MAX_SENSOR_DISTANCE);
_triggerBit = digitalPinToBitMask(trigger_pin); // Get the port register bitmask for the trigger pin.
_echoBit = digitalPinToBitMask(echo_pin);       // Get the port register bitmask for the echo pin.

@@ -21,13 +22,21 @@

_triggerMode = (uint8_t *) portModeRegister(digitalPinToPort(trigger_pin)); // Get the port mode register for the trigger pin.

- _maxEchoTime = min(max_cm_distance, MAX_SENSOR_DISTANCE) * US_ROUNDTRIP_CM + (US_ROUNDTRIP_CM / 2); // Calculate the maximum distance in uS.
+ _maxEchoTime = _maxCMDistance * US_ROUNDTRIP_CM + (US_ROUNDTRIP_CM / 2); // Calculate the maximum distance in uS.

#if DISABLE_ONE_PIN == true
*_triggerMode |= _triggerBit; // Set trigger pin to output.
#endif
}

+unsigned int NewPing::get_max_cm_distance() {
+ return (_maxCMDistance); //
+}
+
+void NewPing::set_max_cm_distance(int max_cm_distance) {
+ _maxCMDistance = min(max_cm_distance, MAX_SENSOR_DISTANCE);
+ _maxEchoTime = _maxCMDistance * US_ROUNDTRIP_CM + (US_ROUNDTRIP_CM / 2); // Calculate the maximum distance in uS.
+}

// ---------------------------------------------------------------------------
// Standard ping methods
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: makerman on Dec 25, 2013, 08:19 pm
I am having problems compiling v1.5 for the Arduino Due. It compiles and works great for Uno, Mega 2560, Yun and Leonardo.

I am using the 1.5.5 version of the IDE on Ubuntu 13.10.

Here is the result of the compile:
Code: [Select]
In file included from NewPingExample.ino:5:
/home/afy/sketchbook/libraries/NewPing/NewPing.h:113: fatal error: avr/io.h: No such file or directory
compilation terminated.


I realize that this is an IDE issue, but am asking if it has already been solved for others.

Thanks.
Title: Re: NewPing (Ultrasonic) Library for HC-SR04 - Faster & Consistent
Post by: dene1988 on Jan 09, 2014, 06:03 pm


  Nice job! I just got 4 of those sensors, and I have one hooked up at home. I will can't wait to try it out!


Hye can you send me the codes for using 4 sensors
Title: Re: NewPing Library- v1.5 Compile Error
Post by: john21403 on Feb 13, 2014, 02:31 am
When I try to compile a sketch that includes the NewPing library, I receive the following error:

In file included from echo_sensor_test_NewPing_lib.ino:1:
/Applications/Arduino.app/Contents/Resources/Java/libraries/NewPing/NewPing.h:113: fatal error: avr/io.h: No such file or directory
compilation terminated.

I can't find any information about the avr/io.h file or the avr library to tell me where to find it or how to load it .

I am new to this, and didn't find any information about this error.

john
Title: Re: NewPing Library: HC-SR04- v1.5
Post by: john21403 on Feb 13, 2014, 02:36 am
Sorry, I forgot to include my environment info:
MAC OS X 10.6.8 Snow Leopard
Arduino 1.5.4
Hardware is an RFduino, version 1.7, with the HC-SR04 sensor.


When I try to compile a sketch that includes the NewPing library, I receive the following error:

In file included from echo_sensor_test_NewPing_lib.ino:1:
/Applications/Arduino.app/Contents/Resources/Java/libraries/NewPing/NewPing.h:113: fatal error: avr/io.h: No such file or directory
compilation terminated.

I can't find any information about the avr/io.h file or the avr library to tell me where to find it or how to load it .

I am new to this, and didn't find any information about this error.

john
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: mortenx on Mar 04, 2014, 12:18 am
how can i change results to mm?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: john21403 on Mar 04, 2014, 03:24 am
To convert the results to millimeters, just multiply the centimeter results by 10.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: mortenx on Mar 04, 2014, 10:32 am
no, i mean real mm ... 
multiplying adds 0 at the end..
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: elac on Mar 04, 2014, 01:54 pm
You want it to print mm instead of cm in the console?
If so change the abbreviations in the sketch:
Code: [Select]
Serial.println("cm");
to
Code: [Select]
Serial.println("mm");
And do as  john21403 says to mathematically  convert cm to mm.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: mortenx on Mar 04, 2014, 04:43 pm

To convert the results to millimeters, just multiply the centimeter results by 10.

multiplying adds 0 at the end nothing more...

You want it to print mm instead of cm in the console?
If so change the abbreviations in the sketch:
Code: [Select]
Serial.println("cm");
to
Code: [Select]
Serial.println("mm");
And do as  john21403 says to mathematically  convert cm to mm.

that changes only printed text ..


but i need real measured values in mm not  cm
because cm result is rounded to full cm, but i need to see fraction
and i cant find where the rounding process is in code..
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Mar 04, 2014, 06:39 pm

I am having problems compiling v1.5 for the Arduino Due. It compiles and works great for Uno, Mega 2560, Yun and Leonardo.

I am using the 1.5.5 version of the IDE on Ubuntu 13.10.

Here is the result of the compile:
Code: [Select]
In file included from NewPingExample.ino:5:
/home/afy/sketchbook/libraries/NewPing/NewPing.h:113: fatal error: avr/io.h: No such file or directory
compilation terminated.


I realize that this is an IDE issue, but am asking if it has already been solved for others.

Thanks.


NewPing uses port registers and timer interrupts and is therefore designed for ATmega microcontrollers.  With that said, v1.6 of NewPing will support non-AVR microcontrollers for all but the ping_timer() method.  Meaning the following methods will work:

ping()
ping_in()
ping_cm()
ping_median()
convert_in()
convert_cm()

The ping_timer() method will not be functional as custom timer interrupt code would need to be written for every microcontroller variant which at this point is a never-ending task with all the ARM-based mircocontrollers being used in different projects both Arduino and others (like Teensy 3.0/3.1).

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Mar 04, 2014, 07:59 pm


To convert the results to millimeters, just multiply the centimeter results by 10.

multiplying adds 0 at the end nothing more...

You want it to print mm instead of cm in the console?
If so change the abbreviations in the sketch:
Code: [Select]
Serial.println("cm");
to
Code: [Select]
Serial.println("mm");
And do as  john21403 says to mathematically  convert cm to mm.

that changes only printed text ..


but i need real measured values in mm not  cm
because cm result is rounded to full cm, but i need to see fraction
and i cant find where the rounding process is in code..


Just use the ping() method instead of ping_cm() then do your own conversion from distance at the speed of sound to mm.  Without your sketch it's hard to tell you exactly what to do.  But, it would be something like this:

Code: [Select]
#include <NewPing.h>

NewPing sonar(12, 11, 200); // NewPing setup of pins and maximum distance.

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

void loop() {
 delay(50);                     // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
 Serial.print("Ping: ");
 Serial.print(sonar.ping()/6); // Send ping, get distance in mm and print result (0 = outside set distance range)
 Serial.println("mm");
}


Keep in mind, I'm dividing by 6 although 5.7 to 5.9 may yield more accurate distances, with the disadvantage of much larger and slower code to do floating point math.  So, you could do something like "sonar.ping()/5.7" if you'd like, but your code will be much larger.

Also, keep in mind that the sensor is not accurate down to a mm level, which is why people typically round to the cm level.  It can give very stable results at a cm level.  However, using the above sketch will give wildly different results each time with no consistency or even more accuracy.  Which is why others have just suggested that you multiply by 10 if you really just want to get a value in mm.  As it's no more accurate to use the above sketch, and if anything more confusing as the results are always different.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Nathan_Clements on Mar 15, 2014, 11:25 am

 With that said, v1.6 of NewPing will support non-AVR microcontrollers for all but the ping_timer() method.  


Has v1.6 been released yet?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Martin2014 on Mar 15, 2014, 07:59 pm
Hi!
I have a DYP-ME007Y connected to an Arduino as follow:

Arduino          Sensor
5V                     5V
Trigger            Pin 2
Echo                Pin 4
Ground          Gnd

How do I use your NewPing files?

Thanks a lot for the help!! :)

Martin
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Mar 17, 2014, 04:32 pm


 With that said, v1.6 of NewPing will support non-AVR microcontrollers for all but the ping_timer() method.  


Has v1.6 been released yet?


No, you can check for a new version here:

https://code.google.com/p/arduino-new-ping/downloads/list

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Mar 17, 2014, 04:33 pm

Hi!
I have a DYP-ME007Y connected to an Arduino as follow:

Arduino          Sensor
5V                     5V
Trigger            Pin 2
Echo                Pin 4
Ground          Gnd

How do I use your NewPing files?

Thanks a lot for the help!! :)

Martin


Use the demo sketch and set the trigger and echo pins accordingly.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: maeishoj on Mar 24, 2014, 11:06 am
Hey dude this is great!

However I am using a Waspmote board with the DYP ME007 and I am using pulsein and I bad readings, as it seems to have problem with "high" distances (like above 160cm) and it actually "crashes" when I move the sensor to sense longer distances.

Anyone have experienced this? I am losing my head :/
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Mar 24, 2014, 01:41 pm

Hey dude this is great!

However I am using a Waspmote board with the DYP ME007 and I am using pulsein and I bad readings, as it seems to have problem with "high" distances (like above 160cm) and it actually "crashes" when I move the sensor to sense longer distances.

Anyone have experienced this? I am losing my head :/


Correct, using the pulsein method can create "crash" like situations.  Instead, use the NewPing library.  It will also be faster and use less program space.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: maeishoj on Mar 24, 2014, 02:37 pm
Hey thanks for the prompt response..

My problem is that I am using a waspmote, not arudino (although are almost the same, but have their own API etc).

So I really can't use this and I am not having a lot of time right now to even look into understanding it and try to port it to waspmote :(

Thanks anyway
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Mar 24, 2014, 03:24 pm

Hey thanks for the prompt response..

My problem is that I am using a waspmote, not arudino (although are almost the same, but have their own API etc).

So I really can't use this and I am not having a lot of time right now to even look into understanding it and try to port it to waspmote :(

Thanks anyway


Oh, this is an Arduino forum.  If your microcontroller isn't ATmega8, you're not going to get a lot of help here.  If it is ATmega8, then NewPing should work.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: maeishoj on Mar 24, 2014, 03:26 pm
Hey there again,

Most of the arduino code works almost seamlessly on the waspmote. It runs ATMEGA1281.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Mar 24, 2014, 03:38 pm

Hey there again,

Most of the arduino code works almost seamlessly on the waspmote. It runs ATMEGA1281.


Then why would you think NewPing wouldn't work?  It's designed to run on the ATmega platform.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: RobotXor on Apr 02, 2014, 03:00 pm
Hello,

I would like to use 12 x HC-SR04 with an I/O multiplexer  MCP23017 (or other) and NewPing library.
Is it possible ?
If yes, how do we configure the newping trigger et echo of the library?
If not, what solution to use knowing that I do not have enough I/O port?

Thank you in advance for your information
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Apr 03, 2014, 10:30 pm

Hello,

I would like to use 12 x HC-SR04 with an I/O multiplexer  MCP23017 (or other) and NewPing library.
Is it possible ?
If yes, how do we configure the newping trigger et echo of the library?
If not, what solution to use knowing that I do not have enough I/O port?

Thank you in advance for your information


First, you only need 12 pins to control 12 HC-SR04 sensors using NewPing.  So, using an I/O multiplexer may not even be required.  Secondly, you can't use NewPing with an I/O multiplexer as it uses direct port register calls.  If you don't have 12 available pins to control 12 sensors, you'll either need to use a Adruino Mega or develop your own custom sensor library or sketch to interface with your I/O multiplexer.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Northof49 on Apr 10, 2014, 05:55 pm
In the multiple sensor examples, how do I actually call up the data for the individual sensors to use that data?  For instance, I might want to compare the first sensor to the second, or the first to the third, or figure out which sensor has the highest or lowest reading.

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Apr 10, 2014, 09:15 pm

In the multiple sensor examples, how do I actually call up the data for the individual sensors to use that data?  For instance, I might want to compare the first sensor to the second, or the first to the third, or figure out which sensor has the highest or lowest reading.


Please see the 15 Sensors Example Sketch Help (http://forum.arduino.cc/index.php?topic=106043.msg1009294.html#msg1009294).  Everything is detailed in that post.  Basically, everything is stored in an array so you can easily extract the information you want.  The above linked help message will explain everything and gives alternative code to accomplish different tasks.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Northof49 on Apr 10, 2014, 10:00 pm
Got it working on my obstacle avoidance robot with three SR04 sensors up front and it is working very well.   Great improvement.

My apologies for an unnecessary question.  I needed to brush up on arrays.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Apr 11, 2014, 05:13 pm

Got it working on my obstacle avoidance robot with three SR04 sensors up front and it is working very well.   Great improvement.


The "multi-tasking" or maybe I should correctly stay "event-driven" or "task-switching" method of pinging even one sensor that NewPing uses is a vast improvement over other methods.  Using multiple sensors multiplies this improvement.  Glad it's working for you!

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: eforman on Apr 23, 2014, 11:24 pm
@Teckel thank you for this library contribution. Is it possible to use this with an ultrasonic sensor like the Hagisonic HG-M40DAI? Its signal output timing is from rising edge of input pulse (trigger) to rising edge of output pulse (echo). In other words, almost the reverse of sensors like Ping.

Datasheet: http://www.robotshop.com/media/files/pdf/hagisonic-anibat-data-sheet.pdf.

If you're curious why the Hagisonic sensor, this "AniBat" model has the unique advantage (AFAIK) of an extremely wide field of view - 180°.

Thanks,

Eric
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Apr 23, 2014, 11:37 pm

@Teckel thank you for this library contribution. Is it possible to use this with an ultrasonic sensor like the Hagisonic HG-M40DAI? Its signal output timing is from rising edge of input pulse (trigger) to rising edge of output pulse (echo). In other words, almost the reverse of sensors like Ping.

Datasheet: http://www.robotshop.com/media/files/pdf/hagisonic-anibat-data-sheet.pdf.

If you're curious why the Hagisonic sensor, this "AniBat" model has the unique advantage (AFAIK) of an extremely wide field of view - 180°.

Thanks,

Eric


It sounds like it's similar to the URM37 sensor (hi/low switched).  I'm sending you a private message that may help.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: pei0807 on Apr 23, 2014, 11:45 pm
Hi,

I am using 3 HC-SR04 sensors. I tried the sketch but it doesnt even print out anything. What should I do
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Apr 24, 2014, 12:44 am

Hi,

I am using 3 HC-SR04 sensors. I tried the sketch but it doesnt even print out anything. What should I do


Check your settings and sketch, as I'm 101% sure it works.  Thousands have used it.  Maybe you don't have the serial baud rate set correctly to match the sketch?

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: chrwei on Apr 25, 2014, 10:54 pm
little confused on the "code.google" site changes.  are the "issues" you marked as done going to have the changes in the next version?  also, why remove that issues list?  it seems a very effective way to track features and bugs.  the forum thread is kind of overwhelming, and very difficult to track any issues on.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Apr 25, 2014, 11:38 pm

little confused on the "code.google" site changes.  are the "issues" you marked as done going to have the changes in the next version?  also, why remove that issues list?  it seems a very effective way to track features and bugs.  the forum thread is kind of overwhelming, and very difficult to track any issues on.



I'm not notified when issues are created or when people make comments to sketches.  Also, there isn't a good way of communicating about an issue.  On this forum, I get notifications and others or myself can answer.  No issues were looked at on the code.google site.  If you have an issue or a suggestion, just post to this thread.

Thanks!

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: pei0807 on Apr 27, 2014, 05:37 pm
I just need to modify the number of sensors being used and the pin number right?



Hi,

I am using 3 HC-SR04 sensors. I tried the sketch but it doesnt even print out anything. What should I do


Check your settings and sketch, as I'm 101% sure it works.  Thousands have used it.  Maybe you don't have the serial baud rate set correctly to match the sketch?

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: eggie5 on Apr 27, 2014, 08:11 pm
Hi I'm trying to use your library with arduino due and the 1.5 version direct seem to have support. I noticed on the Google code page a note said that 1.6 will have support but it's not released yet. I tried to find the source on the Google code page but u don't seem to host the source code on it. Is there due support available?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Apr 29, 2014, 02:56 am

Hi I'm trying to use your library with arduino due and the 1.5 version direct seem to have support. I noticed on the Google code page a note said that 1.6 will have support but it's not released yet. I tried to find the source on the Google code page but u don't seem to host the source code on it. Is there due support available?


Version 1.6 does support the Due.  Well, I believe it does.  I don't have a Due to verify this.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: jaylfc on May 02, 2014, 11:29 am
Hi Tim,

I was wondering if you could advise me on how to connect a HC-SR04 to the official arduino robot, I am stumped and have promised some kids a model of R2-D2 for a music event on Sunday using the robot as it's base but only realised afterwards that it doesn't support digital sensors out of the box, please help!

Thanks,
Jay.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 02, 2014, 03:36 pm

Hi Tim,

I was wondering if you could advise me on how to connect a HC-SR04 to the official arduino robot, I am stumped and have promised some kids a model of R2-D2 for a music event on Sunday using the robot as it's base but only realised afterwards that it doesn't support digital sensors out of the box, please help!

Thanks,
Jay.


I don't know what you mean buy it doesn't support digital sensors.  The Arduino Robot's control board has 5 digital I/O ports and the motor board has 4 I/O ports.  It looks like the control board has 8 multiplexed pins labeled TK0-TK7 that can't be used with NewPing.  But, the specs say there's 5 digital I/O pins, so the interfaces to these pins are in other locations.  The motor board's 4 I/O pins TK1-TK4 do have connection ports right on the board that are not multiplexed so they can go straight to the ultrasonic sensor.  NewPing can interface with a HC-SR04 using only one pin, so you can wire both the trigger and echo pins on the sensor to the same I/O pin on the Arduino Robot.  While TK1 and TK2 are analog pins, they will work just fine as digital pins as well.  Remember, analog pins are also always digital pins (but not vice versa).

Since it seems that the motor board is the easier to connect an ultrasonic sensor via NewPing, here's some code that should work (keep in mind that I don't have an Arduino Robot so this is just a shot in the dark, anyone willing to donate one?):

Code: [Select]
#include <NewPing.h>

NewPing sonar(TK3, TK4, 200);

void setup() {}

void loop() {
  delay(50);
  unsigned int cm = sonar.ping_cm();
  // Do something with the results
}


To conserve available pins, you could also use the same pin for trigger and echo.  Also, remember that you could just as well use TK1 and TK2 even though they're analog pins, they will work as digital.

Hope this helps!

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Northof49 on May 02, 2014, 03:52 pm
Do you just name the same digital pin twice when you want to use the same pin for trigger and echo?  That simple?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 02, 2014, 04:25 pm

Do you just name the same digital pin twice when you want to use the same pin for trigger and echo?  That simple?


Yup, that simple.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: jaylfc on May 03, 2014, 11:29 am
Thank you so much Tim, I will try it and let you know how I get on!

Regards,
Jay.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: jaylfc on May 03, 2014, 01:49 pm
Thanks for your help Tim, I have now attached the sensor to D3 and I am able to get readings via serial. Could you or anybody else help me change this code to work with your library:

Code: [Select]

#include <ArduinoRobot.h>
#include <Wire.h>
#include <SPI.h>

int sensorPin = M1;  // pin is used by the sensor

void setup() {
 // initialize the Robot, SD card, and display
 Serial.begin(9600);
 Robot.begin();
 Robot.beginTFT();
 Robot.beginSD();
 Robot.displayLogos();

 // draw a face on the LCD screen
 setFace(true);
}

void loop() {
 // If the robot is blocked, turn until free
 while (getDistance() < 40) { // If an obstacle is less than 20cm away
   setFace(false); //shows an unhappy face
   Robot.motorsStop(); // stop the motors
   delay(1000); // wait for a moment
   Robot.turn(90); // turn to the right and try again
   setFace(true); // happy face
 }
 // if there are no objects in the way, keep moving
 Robot.motorsWrite(255, 255);
 delay(100);
}

// return the distance in cm
float getDistance() {
 // read the value from the sensor
 int sensorValue = Robot.analogRead(sensorPin);
 //Convert the sensor input to cm.
 float distance_cm = sensorValue * 1.27;
 return distance_cm;
}

// make a happy or sad face
void setFace(boolean onOff) {
 if (onOff) {
   // if true show a happy face
   Robot.background(0, 0, 255);
   Robot.setCursor(44, 60);
   Robot.stroke(0, 255, 0);
   Robot.setTextSize(4);
   Robot.print(":)");
 } else {
   // if false show an upset face
   Robot.background(255, 0, 0);
   Robot.setCursor(44, 60);
   Robot.stroke(0, 255, 0);
   Robot.setTextSize(4);
   Robot.print("X(");
 }
}


This is meant to be used with an analog sensor like a Maxbotix EZ10.

Thanks for your help so far!
Jay.

P.S. All of the LCD stuff isn't important, it is just the sensor working with the motors I need working. Thanks again!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 05, 2014, 05:12 pm

Thanks for your help Tim, I have now attached the sensor to D3 and I am able to get readings via serial. Could you or anybody else help me change this code to work with your library:

Code: [Select]

#include <ArduinoRobot.h>
#include <Wire.h>
#include <SPI.h>

int sensorPin = M1;  // pin is used by the sensor

void setup() {
 // initialize the Robot, SD card, and display
 Serial.begin(9600);
 Robot.begin();
 Robot.beginTFT();
 Robot.beginSD();
 Robot.displayLogos();

 // draw a face on the LCD screen
 setFace(true);
}

void loop() {
 // If the robot is blocked, turn until free
 while (getDistance() < 40) { // If an obstacle is less than 20cm away
   setFace(false); //shows an unhappy face
   Robot.motorsStop(); // stop the motors
   delay(1000); // wait for a moment
   Robot.turn(90); // turn to the right and try again
   setFace(true); // happy face
 }
 // if there are no objects in the way, keep moving
 Robot.motorsWrite(255, 255);
 delay(100);
}

// return the distance in cm
float getDistance() {
 // read the value from the sensor
 int sensorValue = Robot.analogRead(sensorPin);
 //Convert the sensor input to cm.
 float distance_cm = sensorValue * 1.27;
 return distance_cm;
}

// make a happy or sad face
void setFace(boolean onOff) {
 if (onOff) {
   // if true show a happy face
   Robot.background(0, 0, 255);
   Robot.setCursor(44, 60);
   Robot.stroke(0, 255, 0);
   Robot.setTextSize(4);
   Robot.print(":)");
 } else {
   // if false show an upset face
   Robot.background(255, 0, 0);
   Robot.setCursor(44, 60);
   Robot.stroke(0, 255, 0);
   Robot.setTextSize(4);
   Robot.print("X(");
 }
}


This is meant to be used with an analog sensor like a Maxbotix EZ10.

Thanks for your help so far!
Jay.

P.S. All of the LCD stuff isn't important, it is just the sensor working with the motors I need working. Thanks again!


To use NewPing, all you would do is include the library, setup the constructor, and send a ping.  The basic NewPing example shows how to do this.

But, basically you would include the library like this:
Code: [Select]
#include <ArduinoRobot.h>

Setup the constructor:
Code: [Select]
NewPing sonar(sensorPin, sensorPin, 100);

And initiate a ping and get the result, which in your code would look something like this:
Code: [Select]
  while (sonar.ping_cm() < 40) { // If an obstacle is less than 40cm away

However, the sensor would need to be connected to the motor board, not the control board.  I don't have an Arduino Robot to be able to tell you how to write your code.  My guess is that you need two sketches, one for the control board and one for the motor board, and your sketch would need to communicate between the two boards to accomplish this.  I have no first-hand usage of the Arduino Robot so there's no way for me to write working code for you.  I tried, and it wouldn't compile.

I do know that you would need to connect the ultrasonic senor to one of the pins on the motor board (TK1-TK4).  Other than that, you're on your own to write your own code.  It should be VERY easy if you know how to program Arduino sketches and have any experience with using the Arduino Robot.  If this is your first sketch, maybe you should start with something really basic first.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: jaylfc on May 05, 2014, 08:21 pm
Thanks Tim,

I actually managed it before seeing this post but. I have actually soldered the sensor to the control board as this passes the commands to the motor board. The only problem I seem to be having is that once it detects an object within the desired range the pinging stops as do the measurements to the serial monitor. So when it is supposed to rotate and then carry on doing the same again it just seems to end and then the motors go into a wiggling action?

Here is my code:

Code: [Select]

#include <ArduinoRobot.h>
#include <NewPing.h>
#include <SPI.h>
#include <Wire.h>

#define TRIGGER_PIN  D3
#define ECHO_PIN  D3// Arduino pin tied to both trigger and echo pins 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 sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pin and maximum distance.

void setup() {
  // initialize the Robot, SD card, and display
  Serial.begin(9600);
  Robot.begin();
  Robot.beginTFT();
  Robot.beginSD();
  Robot.displayLogos();

  // draw a face on the LCD screen
  setFace(true);
}

void loop()
{
    {
    unsigned int cm = sonar.ping_cm();
    Serial.print("Distance: ");
    Serial.print(cm);
    Serial.println("cm");
    delay(500);
    }
     

  // If the robot is blocked, turn until free
  while (sonar.ping_cm() < 20) { // If an obstacle is less than 20cm away
    setFace(false); //shows an unhappy face
    Robot.motorsStop(); // stop the motors
    delay(500); // wait for a moment
    Robot.turn(45); // turn to the right and try again
    setFace(true); // happy face
  }
  // if there are no objects in the way, keep moving
  Robot.motorsWrite(155, 155);
  delay(100);
}


// make a happy or sad face
void setFace(boolean onOff) {
  if (onOff) {
    // if true show a happy face
    Robot.background(0, 0, 255);
    Robot.setCursor(44, 60);
    Robot.stroke(0, 255, 0);
    Robot.setTextSize(4);
    Robot.print(":)");
  } else {
    // if false show an upset face
    Robot.background(255, 0, 0);
    Robot.setCursor(44, 60);
    Robot.stroke(0, 255, 0);
    Robot.setTextSize(4);
    Robot.print("X(");
  }
}


Thanks again!

Jay.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 05, 2014, 10:00 pm

Thanks Tim,

I actually managed it before seeing this post but. I have actually soldered the sensor to the control board as this passes the commands to the motor board. The only problem I seem to be having is that once it detects an object within the desired range the pinging stops as do the measurements to the serial monitor. So when it is supposed to rotate and then carry on doing the same again it just seems to end and then the motors go into a wiggling action?

Thanks again!

Jay.


My guess is that it has something to do with the while loop where you never set a ping variable and never output serial results.  Like usual, it's just doing what you're telling it to do.

I don't know why you have two nestled curly brackets after loop(), either or what that would even do.   Also, you're doing multiple pings and probably shouldn't be.  You're doing one to set the variable cm and print the results, then another ping in the while statement that's actually being used to detect an object.  My guess is that your loop() routine should be more like this:

Code: [Select]
void loop() {
 unsigned int cm = sonar.ping_cm(); // Do a ping and set the distance in centimeters to variable cm
 Serial.println(cm); // Output the ping distance in centimeters
 if (cm < 20) { // If an obstacle is less than 20cm away
   Robot.motorsStop(); // stop the motors
   setFace(false); //shows an unhappy face
   Robot.turn(45); // turn to the right and try again
   delay(500); // wait for a moment while it turns (this isn't required if Robot.turn() is a blocking command)
 } else {
   Robot.motorsWrite(155, 155); // if there are no objects in the way, keep moving
   setFace(true); // happy face
   delay(50); // Delay between pings
 }
}


But, I don't ultimately know what you're trying to accomplish, nor have an Arduino Robot to test this with.  But, this code makes more sense than what you had and it compiles.  Also, this has nothing really to do with NewPing.  This is more just simple programming debugging.  You were creating a while loop where it wasn't setting a new distance variable nor sending that value to the serial port, so of course it won't output anything for as long as it's stuck in the while loop.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: dasdas on May 08, 2014, 05:56 pm


Hi I'm trying to use your library with arduino due and the 1.5 version direct seem to have support. I noticed on the Google code page a note said that 1.6 will have support but it's not released yet. I tried to find the source on the Google code page but u don't seem to host the source code on it. Is there due support available?


Version 1.6 does support the Due.  Well, I believe it does.  I don't have a Due to verify this.

Tim


Hi Tim

I'm willing and able to test version 1.6 (even a not released version) on the Due. Do you know from where I can download it? A quick google search did not returned anything.

Thanks
Dan.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: reverendrichie on May 12, 2014, 04:37 pm
First, thank you for this valuable Ping Library,

I am attempting to use the same trigger ping for three HC-SR04 sensor on a Pro-Mini Arduino and so far, things appear to be working fine on the bench. My question is, are there any know issues with using the same trigger pin for two or more sensors?

Thank you.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 12, 2014, 05:49 pm

First, thank you for this valuable Ping Library,

I am attempting to use the same trigger ping for three HC-SR04 sensor on a Pro-Mini Arduino and so far, things appear to be working fine on the bench. My question is, are there any know issues with using the same trigger pin for two or more sensors?

Thank you.


I've never tried using the same trigger pin for multiple sensors nor is the library designed to work this way.  What NewPing would do would be to actually try to initiate a ping three times each sensor.  The sensor would probably ignore this, but there's no guarantee.  Also, I would be concerned with the higher likelihood of echos giving bad results or the pulsing from multiple sensors confusing the sensors.

It would be better (avoiding echos and cross-talk issues) and use fewer pins to just wire a single pin to each sensor's trigger and echo pin.  In other words, you would use 3 pins, each pin going to each sensor's trigger and echo pins.  This would use 3 pins instead of (I assume) the 4 pins you're currently using.  Yes, you would need to ping each sensor individually, but using the non-blocking ping_timer() method your microcontroller could be doing other things while the ping sound is traveling.  I would consider this a more "sound" way to implement 3 sensors.

May I ask, why do you want to ping all three at the same time?  Would it really matter if each ping was 30ms apart?  You could still ping 3 sensors 10 times a second while still "multi-tasking" and doing other processes in your sketch.  Insight on your project and the reasoning would be helpful.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: reverendrichie on May 12, 2014, 06:37 pm


I've never tried using the same trigger pin for multiple sensors nor is the library designed to work this way.  What NewPing would do would be to actually try to initiate a ping three times each sensor.  The sensor would probably ignore this, but there's no guarantee.  Also, I would be concerned with the higher likelihood of echos giving bad results or the pulsing from multiple sensors confusing the sensors.

It would be better (avoiding echos and cross-talk issues) and use fewer pins to just wire a single pin to each sensor's trigger and echo pin.  In other words, you would use 3 pins, each pin going to each sensor's trigger and echo pins.  This would use 3 pins instead of (I assume) the 4 pins you're currently using.  Yes, you would need to ping each sensor individually, but using the non-blocking ping_timer() method your microcontroller could be doing other things while the ping sound is traveling.  I would consider this a more "sound" way to implement 3 sensors.

May I ask, why do you want to ping all three at the same time?  Would it really matter if each ping was 30ms apart?  You could still ping 3 sensors 10 times a second while still "multi-tasking" and doing other processes in your sketch.  Insight on your project and the reasoning would be helpful.

Tim


Thank you for the very quick response Tim,

The primary reason is the limitation of available pins on the Pro-Mini. I have each sensor angled outside of each others echo zone. so there is little or no interferences that I can detect at this point. I may have to upgrade to a Arduino mega before this project is finish.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 12, 2014, 06:56 pm



I've never tried using the same trigger pin for multiple sensors nor is the library designed to work this way.  What NewPing would do would be to actually try to initiate a ping three times each sensor.  The sensor would probably ignore this, but there's no guarantee.  Also, I would be concerned with the higher likelihood of echos giving bad results or the pulsing from multiple sensors confusing the sensors.

It would be better (avoiding echos and cross-talk issues) and use fewer pins to just wire a single pin to each sensor's trigger and echo pin.  In other words, you would use 3 pins, each pin going to each sensor's trigger and echo pins.  This would use 3 pins instead of (I assume) the 4 pins you're currently using.  Yes, you would need to ping each sensor individually, but using the non-blocking ping_timer() method your microcontroller could be doing other things while the ping sound is traveling.  I would consider this a more "sound" way to implement 3 sensors.

May I ask, why do you want to ping all three at the same time?  Would it really matter if each ping was 30ms apart?  You could still ping 3 sensors 10 times a second while still "multi-tasking" and doing other processes in your sketch.  Insight on your project and the reasoning would be helpful.

Tim


Thank you for the very quick response Tim,

The primary reason is the limitation of available pins on the Pro-Mini. I have each sensor angled outside of each others echo zone. so there is little or no interferences that I can detect at this point. I may have to upgrade to a Arduino mega before this project is finish.


How many pins are you using?  4?  One pin for triggers on all sensors and 3 pins to get the results from each sensor?  If so, you could just use 3 pins by using the method I describe.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: reverendrichie on May 12, 2014, 08:40 pm



How many pins are you using?  4?  One pin for triggers on all sensors and 3 pins to get the results from each sensor?  If so, you could just use 3 pins by using the method I describe.

Tim


Please forgive me Tim, I am not understanding, I am using four pins as you have stated but I don't understand how to wire the sensor to only use three pins. This surely would be better because I can add a forth sensor pointing to the rear.

Here is the setup code I am presently using.

Code: [Select]

#define LED_STATUS_PIN 13
#define SONAR_NUM     3 // Number or sensors.
#define MAX_DISTANCE 300 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 66 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
...
unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
byte currentSensor = 0;          // Keeps track of which sensor is active.

NewPing sonar[SONAR_NUM] = {     // Sensor object array.
NewPing(7, 10, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
NewPing(7, 11, MAX_DISTANCE),
NewPing(7,  5, MAX_DISTANCE),
...
for (uint8_t i = 0; i < SONAR_NUM; i++) {       // Loop through all the sensors.
    if (millis() >= pingTimer[i]) {               // Is it this sensor's time to ping?
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1)
      {
          oneSensorCycle();
          serialCom();
      }          // Sensor ping cycle complete, do something with the results.
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 999;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }
  }

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 12, 2014, 10:23 pm




How many pins are you using?  4?  One pin for triggers on all sensors and 3 pins to get the results from each sensor?  If so, you could just use 3 pins by using the method I describe.

Tim


Please forgive me Tim, I am not understanding, I am using four pins as you have stated but I don't understand how to wire the sensor to only use three pins. This surely would be better because I can add a forth sensor pointing to the rear.

Here is the setup code I am presently using.

Code: [Select]

#define LED_STATUS_PIN 13
#define SONAR_NUM     3 // Number or sensors.
#define MAX_DISTANCE 300 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 66 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
...
unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
byte currentSensor = 0;          // Keeps track of which sensor is active.

NewPing sonar[SONAR_NUM] = {     // Sensor object array.
NewPing(7, 10, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
NewPing(7, 11, MAX_DISTANCE),
NewPing(7,  5, MAX_DISTANCE),
...
for (uint8_t i = 0; i < SONAR_NUM; i++) {       // Loop through all the sensors.
    if (millis() >= pingTimer[i]) {               // Is it this sensor's time to ping?
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1)
      {
          oneSensorCycle();
          serialCom();
      }          // Sensor ping cycle complete, do something with the results.
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 999;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }
  }




NewPing supports the ability to use one pin per sensor.  You simply wire a single pin to the trigger and the echo pins on the sensor.  That's it!  In your sketch, you would set the trigger and echo pin as the same pin.  The magic all happens in the library.  It would look something like this:

Code: [Select]

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


This would ping each device independently, and not all at once like you're doing now.  The way you're doing it could cause bad echo problems.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: reverendrichie on May 12, 2014, 11:03 pm


NewPing supports the ability to use one pin per sensor.  You simply wire a single pin to the trigger and the echo pins on the sensor.  That's it!  In your sketch, you would set the trigger and echo pin as the same pin.  The magic all happens in the library.  It would look something like this:

Code: [Select]

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


This would ping each device independently, and not all at once like you're doing now.  The way you're doing it could cause bad echo problems.

Tim


Absolutely Fantastic!!!

Thank you Tim.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: phamtuan1151 on May 15, 2014, 07:26 pm
I used newping libray but It error compiling...

sketch_may15a.cpp.o: In function `__static_initialization_and_destruction_0':
C:\Program Files\Arduino/sketch_may15a.ino:10: undefined reference to `NewPing::NewPing(unsigned char, unsigned char, int)'
C:\Program Files\Arduino/sketch_may15a.ino:10: undefined reference to `NewPing::NewPing(unsigned char, unsigned char, int)'
C:\Program Files\Arduino/sketch_may15a.ino:10: undefined reference to `NewPing::NewPing(unsigned char, unsigned char, int)'
sketch_may15a.cpp.o: In function `loop':
C:\Program Files\Arduino/sketch_may15a.ino:18: undefined reference to `NewPing::ping_cm()'

Please hlep me!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 15, 2014, 08:00 pm

I used newping libray but It error compiling...

sketch_may15a.cpp.o: In function `__static_initialization_and_destruction_0':
C:\Program Files\Arduino/sketch_may15a.ino:10: undefined reference to `NewPing::NewPing(unsigned char, unsigned char, int)'
C:\Program Files\Arduino/sketch_may15a.ino:10: undefined reference to `NewPing::NewPing(unsigned char, unsigned char, int)'
C:\Program Files\Arduino/sketch_may15a.ino:10: undefined reference to `NewPing::NewPing(unsigned char, unsigned char, int)'
sketch_may15a.cpp.o: In function `loop':
C:\Program Files\Arduino/sketch_may15a.ino:18: undefined reference to `NewPing::ping_cm()'

Please hlep me!


Sounds like you didn't install the library correctly.  Did you decompress it (keeping the directory structure in tact) and put it in your arduino's libraries folder?  I believe there's now also an option in Arduino 1.0.5 to import a library.

Also, you should really always provide your sketch (or mention if you're using an example sketch).  But, these errors are basically saying that it can't find the library AT ALL.  So, you didn't install it correctly (or you just need to close Arduino and open it again).  If you do this and verify the library is installed correctly in your libraries folder like the rest of your libraries and you still have a problem, please indicate the sketch you're using or paste the sketch to your reply.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: terryking228 on May 16, 2014, 05:07 pm
Hi,
Library Install HOW-To  HERE: (http://arduino-info.wikispaces.com/Arduino-Libraries#NewLib)

Hi Tim, Thanks for your work!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: fernandossala on May 20, 2014, 11:57 pm
I am doing an installation that works with two sr04, and I am quite satisfied with the results I am achieving so far.
The code I am using is this:
Code: [Select]
#include <NewPing.h>

#define SONAR_NUM      2
#define MAX_DISTANCE 350
#define PING_INTERVAL 33

int rele1 = 7;
int rele2 = 8;


unsigned long pingTimer[SONAR_NUM];
uint8_t currentSensor = 0;

NewPing sonar[SONAR_NUM] = {
  NewPing(13, 12, MAX_DISTANCE),

  NewPing(4, 2, MAX_DISTANCE)
};

void setup() {
  pinMode (rele1, OUTPUT);
  pinMode (rele2, OUTPUT);
 
  Serial.begin(115200);
  pingTimer[0] = millis() + 75;
  for (uint8_t i = 1; i < SONAR_NUM; i++)
    pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) {
    if (millis() >= pingTimer[i]) {
      pingTimer[i] += 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.

int i;
float f;
f = cm;

i = (int) f/2;

if ( i > 10)
{ digitalWrite (rele1, HIGH);
digitalWrite (rele2, HIGH);
}else{
i = 0;
digitalWrite (rele1, LOW);
digitalWrite (rele2, LOW);


Serial.println(i);

}
}



and I just wanted to turn on a pair of relays based on the sensors activity, and so far i got it to work almost the way i want, the sensors will work almost in parallel (slightly different angles to give'em more viewing angle).  I found the cast operator to be more friendly to deal with the cm array, but I am not sure if its the proper way of doing it.

as of the relays, i want them to turn on when there's somebody in the range of the sensors, otherwise it must be turned off, any advice or suggestion will be much apreciated, and what I got so far is, they turn on on presence, but turn off only when somebody is 10 cm or closer, but not when out of range, i tried to stop and turn the ping on again as suggested on page 19, but I'm not achieving the results I seek

and Teckel, excelent job, and thanks a bunch for your activity in this thread, as an arduino lover and a maker, I am obliged to thank people like you!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 21, 2014, 04:54 pm

I am doing an installation that works with two sr04, and I am quite satisfied with the results I am achieving so far.

and I just wanted to turn on a pair of relays based on the sensors activity, and so far i got it to work almost the way i want, the sensors will work almost in parallel (slightly different angles to give'em more viewing angle).  I found the cast operator to be more friendly to deal with the cm array, but I am not sure if its the proper way of doing it.

as of the relays, i want them to turn on when there's somebody in the range of the sensors, otherwise it must be turned off, any advice or suggestion will be much apreciated, and what I got so far is, they turn on on presence, but turn off only when somebody is 10 cm or closer, but not when out of range, i tried to stop and turn the ping on again as suggested on page 19, but I'm not achieving the results I seek

and Teckel, excelent job, and thanks a bunch for your activity in this thread, as an arduino lover and a maker, I am obliged to thank people like you!


I'm not sure why you're creating the floating variable "f" and why you're then dividing the distance by two.  That will just add a lot of overhead to your code.  But, a distance of "0" means out of range.  So, if you want to turn something on when in rage and off when out of range your code would look something like this (I cleaned it up a bit too):

Code: [Select]
#include <NewPing.h>

#define SONAR_NUM      2
#define MAX_DISTANCE 350
#define PING_INTERVAL 33

#define RELE1 7
#define RELE2 8

unsigned long pingTimer[SONAR_NUM];
uint8_t currentSensor = 0;

NewPing sonar[SONAR_NUM] = {
  NewPing(13, 12, MAX_DISTANCE),
  NewPing(4, 2, MAX_DISTANCE)
};

void setup() {
    Serial.begin(115200);

    pinMode (RELE1, OUTPUT);
    pinMode (RELE2, OUTPUT);
    pingTimer[0] = millis() + 75;
    for (uint8_t i = 1; i < SONAR_NUM; i++)
      pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}

void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) {
    if (millis() >= pingTimer[i]) {
      pingTimer[i] += 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){
  if ( cm == 0 ) {
    digitalWrite (RELE1, LOW);
    digitalWrite (RELE2, LOW);
  } else {
    digitalWrite (RELE1, HIGH);
    digitalWrite (RELE2, HIGH);
  }

  Serial.println(cm);
}


The problem with this code however is that you have two sensors.  One may detect an object and the other may not.  So, it could turn on and off so quickly you can't even tell.  You probably need to use the original multi-sensor sketch that stores the results in the array and then process the results where you can make logic decisions based upon results of maybe one sensor detecting an object and the other not, or distances that are wildly different.

Basically, while my above sketch will work the way you asked, it won't really work the way you want.  Going back to the original sketch and storing the results in the array and then using different logic is probably what you really want.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: fernandossala on May 21, 2014, 06:59 pm
When I first tried the example sketches, I printed every single piece of code I found could be handy to work with, the objects in the array cm
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 21, 2014, 07:42 pm

When I first tried the example sketches, I printed every single piece of code I found could be handy to work with, the objects in the array cm
  • and cm [1] where the variables I found most important (all other I just couldn't print), but, again I couldn't do much with them as I have poor code skills, I was looking for some piece of code that could convert whatever I was looking at to something I could do some math with , later I found I was merging the results into one, so I decided I needed to divide the result by two. Ok, not a smart decision, I know...

    And with your sketch, I did came to similar results as yours before, and what happens is, when something approaches to the sensor, it turns on, but never turns off, therefore, there's no 0 coming out when there's no activity. I thought this was a good approuch to achieve my goal, which is, when there's activity on the sensor, turn on, else, turn off
    thanks

    Fernando


Without totally writing the sketch for you (what fun would that be?) I can suggest that you start again with the standard 15 sensor sample sketch that puts the results in an array.  Then, analyze the results in the array and decide what you want to do with the data.  The distance variables are simply cm[0] and cm[1].  You wouldn't want to add them and divide by two, as that would not give accurate results.  Instead, you would need some better logic.  For example, maybe one OR the other needs to be a positive value to consider something in range.  So, you would do something like:

Code: [Select]
void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
  // The following code would be replaced with your code that does something with the ping results.
  if (cm[0] || cm[1]) {  // At least one sensor detected something in range, activate relays.
    digitalWrite (RELE1, HIGH);
    digitalWrite (RELE2, HIGH);
  } else {  // Both sensors can't detect anything, turn relays off.
    digitalWrite (RELE1, LOW);
    digitalWrite (RELE2, LOW);
  }
}


Hope that helps!

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: fernandossala on May 21, 2014, 08:02 pm


When I first tried the example sketches, I printed every single piece of code I found could be handy to work with, the objects in the array cm
  • and cm [1] where the variables I found most important (all other I just couldn't print), but, again I couldn't do much with them as I have poor code skills, I was looking for some piece of code that could convert whatever I was looking at to something I could do some math with , later I found I was merging the results into one, so I decided I needed to divide the result by two. Ok, not a smart decision, I know...

    And with your sketch, I did came to similar results as yours before, and what happens is, when something approaches to the sensor, it turns on, but never turns off, therefore, there's no 0 coming out when there's no activity. I thought this was a good approuch to achieve my goal, which is, when there's activity on the sensor, turn on, else, turn off
    thanks

    Fernando


Without totally writing the sketch for you (what fun would that be?) I can suggest that you start again with the standard 15 sensor sample sketch that puts the results in an array.  Then, analyze the results in the array and decide what you want to do with the data.  The distance variables are simply cm[0] and cm[1].  You wouldn't want to add them and divide by two, as that would not give accurate results.  Instead, you would need some better logic.  For example, maybe one OR the other needs to be a positive value to consider something in range.  So, you would do something like:

Code: [Select]
void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
  // The following code would be replaced with your code that does something with the ping results.
  if (cm[0] || cm[1]) {  // At least one sensor detected something in range, activate relays.
    digitalWrite (RELE1, HIGH);
    digitalWrite (RELE2, HIGH);
  } else {  // Both sensors can't detect anything, turn relays off.
    digitalWrite (RELE1, LOW);
    digitalWrite (RELE2, LOW);
  }
}


Hope that helps!

Tim


It works like a champion!
Thanks a bunch, next time, i will send pictures and videos of the final project!
Best Regards,
Fernando
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 21, 2014, 10:09 pm

It works like a champion!
Thanks a bunch, next time, i will send pictures and videos of the final project!
Best Regards,
Fernando


Glad I could help!  Would love to see the final project.  I hope it's something fast-moving that chases your cat around the house or something cool like that.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: berr08 on May 21, 2014, 10:32 pm
Didn't realize this thread was a main support for this library (or at least it seems to be from what I am reading).  Can anyone help with my issue, I'm using the DYP-ME007Y sensor but it isn't working as expected:

http://forum.arduino.cc/index.php?topic=241763.0 (http://forum.arduino.cc/index.php?topic=241763.0)

Thanks Everyone!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: fernandossala on May 22, 2014, 12:30 am


It works like a champion!
Thanks a bunch, next time, i will send pictures and videos of the final project!
Best Regards,
Fernando


Glad I could help!  Would love to see the final project.  I hope it's something fast-moving that chases your cat around the house or something cool like that.

Tim


not fast moving chasing cat cool, but still cool...
here's a picture of the installation without the electronics
the relays will give power to three industrial fans (one for each letter). the middle one needs to be filled first, this is why i need to relays, as soon as i put the electronics inside the case, i will take more pictures and video for you guys
cheers
Fernando
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 22, 2014, 08:38 pm

Didn't realize this thread was a main support for this library (or at least it seems to be from what I am reading).  Can anyone help with my issue, I'm using the DYP-ME007Y sensor but it isn't working as expected:

http://forum.arduino.cc/index.php?topic=241763.0 (http://forum.arduino.cc/index.php?topic=241763.0)

Thanks Everyone!


Glad you got it working!  A bad connection like that can be hard to track down.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: berr08 on May 23, 2014, 03:10 pm


Didn't realize this thread was a main support for this library (or at least it seems to be from what I am reading).  Can anyone help with my issue, I'm using the DYP-ME007Y sensor but it isn't working as expected:

http://forum.arduino.cc/index.php?topic=241763.0 (http://forum.arduino.cc/index.php?topic=241763.0)

Thanks Everyone!


Glad you got it working!  A bad connection like that can be hard to track down.

Tim


Thank you!   :D
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: phamtuan1151 on May 23, 2014, 07:14 pm
why serial.print do'nt exactly distance "?
please help me!
#include <NewPing.h>

#define TRIGGER_PIN  A0  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     A1  // 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.
#define TRIGGER_PIN2  A2  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN2     A3
#define TRIGGER_PIN3  A4  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN3     A5
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
NewPing sonar1(TRIGGER_PIN2, ECHO_PIN2, MAX_DISTANCE);
NewPing sonar2(TRIGGER_PIN3, ECHO_PIN3, MAX_DISTANCE);
void setup() {
  Serial.begin(115200);
}

void loop() {
  delay(50);                    .
  unsigned int uS = sonar.ping();
  unsigned int uS1 = sonar1.ping();
unsigned int uS2 = sonar2.ping();
Serial.print('left');
  Serial.print(uS2 / US_ROUNDTRIP_CM);
  Serial.println('');
Serial.print('right');
  Serial.print(uS1 / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)
  Serial.println();
Serial.print('frent');
  Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)
  Serial.println();
}
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: AWOL on May 23, 2014, 07:46 pm
Code: [Select]
Serial.print('left');
Double quotes

Please use code tags.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 23, 2014, 07:57 pm

why serial.print do'nt exactly distance "?
please help me!


Yes, what he said --^   Use double quotes, not single quotes.  For example:

Code: [Select]

Serial.print("stalker");


Let us know if that fixes things for you.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: fernandossala on May 27, 2014, 11:51 pm



It works like a champion!
Thanks a bunch, next time, i will send pictures and videos of the final project!
Best Regards,
Fernando


Glad I could help!  Would love to see the final project.  I hope it's something fast-moving that chases your cat around the house or something cool like that.

Tim


not fast moving chasing cat cool, but still cool...
here's a picture of the installation without the electronics
the relays will give power to three industrial fans (one for each letter). the middle one needs to be filled first, this is why i need to relays, as soon as i put the electronics inside the case, i will take more pictures and video for you guys
cheers
Fernando



here's the video of the Intervention I did with my installation in Copacabana

https://www.youtube.com/watch?v=ZDFbqTRK51s
and you can see the sensor working at its best
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 28, 2014, 02:27 pm

here's the video of the Intervention I did with my installation in Copacabana

https://www.youtube.com/watch?v=ZDFbqTRK51s
and you can see the sensor working at its best


I could tell the dog's ego was inflated due to your project.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: levak on May 29, 2014, 09:53 pm
Hello!

I noticed SR06 sensor has a temperature sensor on the board as well, which can be used for temperature compensation.
Are those measurements more accurate?
How much more? Let's say I have a sensor without temperature compensation and I set my code to 20°, but ambient temperature is 30°C. How big of a deviation would I see?

Matej
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on May 29, 2014, 11:12 pm

Hello!

I noticed SR06 sensor has a temperature sensor on the board as well, which can be used for temperature compensation.
Are those measurements more accurate?
How much more? Let's say I have a sensor without temperature compensation and I set my code to 20°, but ambient temperature is 30°C. How big of a deviation would I see?

Matej


The formula for the speed of sound is:  m/s = 331.3 + (0.606 x C°)

So, at 20°, the speed of sound is 343.42 m/s and at 30° it's 349.48.

Towards the extreme edge of the sensor range, lets say you get a ping time of 29,000 ms.  That would give you:

29,000 ms / 10,000  x 343.42 m/s / 2 = 497.96 cm
29,000 ms / 10,000  x 349.48 m/s / 2 = 506.75 cm

So, temperature does make a difference, in this example, almost 9cm.  Likewise, at 100cm, the difference would still be about 1.75 cm, so still sizable.

With this said, it's typically not an issue.  Because for normal uses, the sensor is not being used to measure an exact distance, but instead to see if something is approaching or too close relative to a previous ping.  However, if you're using the sensor to measure an exact distance (say a water level) and you must get very precise distance results over a long period of time at various temperatures, then using a thermostat and doing the above calculation would be very important.  All depends on your need.  NewPing is designed to work easily with the built-in ping_cm() method, or you can roll your own with ping().

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: levak on May 30, 2014, 07:31 am
Does NewPing library supports temperature compensation with SRF06 sensor?
Can it automatically read temperature and use it in it's calculation?

lp, Matej
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jun 02, 2014, 04:21 pm

Does NewPing library supports temperature compensation with SRF06 sensor?
Can it automatically read temperature and use it in it's calculation?

lp, Matej


The sensor does not output the temperature.  It simply reads the temp and adjusts the output based on the temp.  So yes, NewPing works along with the thermostat and is used in the calculations.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: levak on Jun 02, 2014, 08:44 pm
I did some reading on SR-06 and I found out it does the corrections on the sensor itself... So yea, your lib does support that:)



Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jun 02, 2014, 11:39 pm

I did some reading on SR-06 and I found out it does the corrections on the sensor itself... So yea, your lib does support that:)


I think that's what I said, or at least I meant to say that.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: mouchadino on Jun 17, 2014, 05:49 am
I have try upload the sketch with arduino1.05R2 but i get 1 of sensor sornar aktive  1 more not working please... help me...it.s make me crazy :p

the sketch as bellow :P
Code: [Select]

/* Code modified for analog output by: mOuchadino

Available PWM pin : 3, 5, 6, 9, 10, 11
Available Digital I/O pin : 2 to 13
*/

#include <NewPing.h>

#define SONAR_NUM 2 // Number or sensors.
#define MAX_DISTANCE 400 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 30 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0; // Keeps track of which sensor is active.

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

int pwmPins[SONAR_NUM] = {
 9, 10 }; // array Nomor pin utk keluaran PWM Analog out 0-5v
int led = 13;

void setup() {
 Serial.begin(115200);
 pingTimer[0] = millis() + 75;              // First ping starts at 75ms, gives time for the Arduino to chill before starting.
 for (uint8_t i = 1; i < SONAR_NUM; i++)  { // Set the starting time for each sensor.
   pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
 }

 for (uint8_t i = 0; i < SONAR_NUM; i++) { // pwm output pin counter
   pinMode(pwmPins[i], OUTPUT);
 }

 {              
 // initialize the digital pin as an output.
 pinMode(led, OUTPUT);    
}

 Serial.println();
}

void loop()
{
 for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
   if (millis() >= pingTimer[i]) { // Is it this sensor's time to ping?
     pingTimer[i] += PING_INTERVAL * SONAR_NUM; // Set next time this sensor will be pinged.
     if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
     sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance).
     currentSensor = i; // Sensor being accessed.
     cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor.
     sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
   }
 
 }

{
 digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 delay(1000);               // wait for a second
 digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 delay(2000);               // wait for a second
}
 // Other code that *DOESN'T* analyze ping results can go here.
}

// If ping received, set the sensor distance to array.
void echoCheck()
{
 if (sonar[currentSensor].check_timer())
   cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}

// Sensor ping cycle complete, do something with the results. Location option 1 for code processing

void oneSensorCycle()
{
 for (uint8_t i = 0; i < SONAR_NUM; i++) {
   // turn the pin on:
   // http://arduino.cc/en/Reference/analogWrite
   analogWrite(pwmPins[i], cm[i]);

   //        Serial.print(i); // print sensor number accessed
   //        Serial.print("="); // = märk
   //        Serial.print(cm[i]); // sensor distance value
   //        Serial.println("cm "); // cm
   //        Print format i = xxx cm
 }
}

===========================================================================================

#include <NewPing.h>

#define SONAR_NUM 2 // Number or sensors.
#define MAX_DISTANCE 400 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0; // Keeps track of which sensor is active.

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

int pwmPins[SONAR_NUM] = {9, 10 };  // an array of pin numbers to which pwm output is written
int led = 13;

void setup()
{
 Serial.begin(115200);
 pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting.

 for (uint8_t i = 1; i < SONAR_NUM; i++) {// Set the starting time for each sensor.
   pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
 }

 for (uint8_t i = 0; i < SONAR_NUM; i++) { // pwm output pin counter
   pinMode(pwmPins[i], OUTPUT);
  }
{              
 
  // initialize the digital pin as an output.
 
 pinMode(led, OUTPUT);    
}

 Serial.println();
}

void loop()
{
 for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
   if (millis() >= pingTimer[i]) { // Is it this sensor's time to ping?
     pingTimer[i] += PING_INTERVAL * SONAR_NUM; // Set next time this sensor will be pinged.
     if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
     sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance).
     currentSensor = i; // Sensor being accessed.
     cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor.
     sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
   }
 }
}

// If ping received, set the sensor distance to array.
void echoCheck()
{
 if (sonar[currentSensor].check_timer())
   cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}

// Sensor ping cycle complete, do something with the results. Location option 1 for code processing

void oneSensorCycle()
{
 for (uint8_t i = 0; i < SONAR_NUM; i++) {
   // turn the pin on:
   
   analogWrite(pwmPins[i], cm[i]);

           Serial.print(i); // print sensor number accessed
           Serial.print("="); // = märk
           Serial.print(cm[i]); // sensor distance value
           Serial.println("cm "); // cm
   //        Print format i = xxx cm
 }
}


moderator update: added code tags  -->  # button above smileys
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: mouchadino on Jun 17, 2014, 05:51 am
==============================================================================
i modifed the sketch like as bellow  =( still not working with 2 sonar


Code: [Select]

#include <NewPing.h>

#define SONAR_NUM 2 // Number or sensors.
#define MAX_DISTANCE 400 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 100 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).

unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0; // Keeps track of which sensor is active.

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

int pwmPins[SONAR_NUM] = {9, 10 }; // array Nomor pin utk keluaran PWM Analog out 0-5v
int ledPins[SONAR_NUM] = {12, 13};

void setup() {
 Serial.begin(115200);
 pingTimer[0] = millis() + 75;              // First ping starts at 75ms, gives time for the Arduino to chill before starting.
 for (uint8_t i = 1; i < SONAR_NUM; i++)  { // Set the starting time for each sensor.
   pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
 }

for (uint8_t i = 0; i < SONAR_NUM; i++) { // pwm output pin counter
   pinMode(pwmPins[i], OUTPUT);
 }
               
 // initialize the digital pin as an output.
 
for (uint8_t i = 0; i < SONAR_NUM; i++) { // pwm output pin counter
   pinMode(ledPins[i], OUTPUT);
 }  

 Serial.println();
}

void loop()
{
 for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
   if (millis() >= pingTimer[i]) { // Is it this sensor's time to ping?
     pingTimer[i] += PING_INTERVAL * SONAR_NUM; // Set next time this sensor will be pinged.
     if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
     sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance).
     currentSensor = i; // Sensor being accessed.
     cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor.
     sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
   }
 
 }

{
{
 digitalWrite(ledPins[12,13], HIGH);   // turn the LED on (HIGH is the voltage level)
 delay(500);               // wait for a second
 digitalWrite(ledPins[13,12], LOW);    // turn the LED off by making the voltage LOW
 delay(1000);               // wait for a second
}
}
 // Other code that *DOESN'T* analyze ping results can go here.
}

// If ping received, set the sensor distance to array.
void echoCheck()
{
 if (sonar[currentSensor].check_timer())
   cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}

// Sensor ping cycle complete, do something with the results. Location option 1 for code processing

void oneSensorCycle()
{
 for (uint8_t i = 0; i < SONAR_NUM; i++) {
   // turn the pin on:

   analogWrite(pwmPins[i], cm[i]);

           Serial.print(i); // print sensor number accessed
           Serial.print("="); // = märk
           Serial.print(cm[i]); // sensor distance value
           Serial.println(" -cm "); // cm
   //        Print format i = xxx cm
 }
}


===========================================================================

but if i.m delete the as bellow the 2 sensor work fine :p

Code: [Select]

{
 digitalWrite(ledPins[12,13], HIGH);   // turn the LED on (HIGH is the voltage level)
 delay(500);               // wait for a second
 digitalWrite(ledPins[13,12], LOW);    // turn the LED off by making the voltage LOW
 delay(1000);               // wait for a second
}

every body please help me ..... =(   =(

moderator update: added code tags  -->  # button above smileys
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: shomar on Jul 07, 2014, 05:09 am
Hi Tim,

Any Plans for releasing the version 1.6 soon?

I am using this with ATtiny  as well as arduino and trying to avoid keeping the timers commented/uncommented for each use  :)

Thanks for the great library BTW

Shomar
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: rastamankg on Aug 14, 2014, 04:45 pm
I have problem with this library. If I upload example sketch, everything works, but if I use this library for my project, Arduino loose USB communication, does anybody knows what should I do?
Thanks
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: visualxl on Sep 04, 2014, 10:22 am
Thank you for writing this library out for us.

I just got DYP-ME007Y module, and I've never played around with it. So, I straight away use your library.. and..

NewPingExample does not seem to work.

NewPingEventTimer work. But we have to only grab the first reading of the second wave onwards if the reading is important to you. Pardon me if my linggo is not correct.

So let say, the first wave (1, 2, 3, 4, 5, 6, 7), ignore this.

Then, subsequent waves onwards, it looks like (77, 67, 57, 47, 37, 28, 25). So, you may pick any one of this. I would prefer picking the first reading in my case.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: walshlg on Sep 07, 2014, 02:47 am
PLEASE, PLEASE include code for the 3 pin parallax 28015 sensors.  They are available now for 1/10 the price of the 4 pin sensors.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: walshlg on Sep 07, 2014, 03:50 am
OK here is a suprise: set the Trigger_Pin and Echo_Pin to the same port and by golly it seems to be working fine!

Ping / Parallax  28015 3-pin sensor

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: TryChick on Sep 13, 2014, 07:02 pm
I am not sure why I'm not getting a return of zero for sensor readings that are out of range.  I get wildly varying distances when there is nothing in front of the sensors, but accurate readings when I have something in front.  Any ideas? I have two HC-SR04s on my bot, so I modified the NewPingExample for 2 sensors, but it does the same thing when only one sensor is being pinged.

Code: [Select]

#include <NewPing.h>

#define L_TRIG 46  // Arduino pin tied to trigger pin on the left ultrasonic sensor.
#define L_ECHO 47  // Arduino pin tied to echo pin on the left ultrasonic sensor.

#define R_TRIG 48  // Arduino pin tied to trigger pin on the right ultrasonic sensor.
#define R_ECHO 49  // Arduino pin tied to echo pin on the right ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar_L(L_TRIG, L_ECHO, MAX_DISTANCE); // NewPing setup of pins and maximum distance for left sensor.
NewPing sonar_R(R_TRIG, R_ECHO, MAX_DISTANCE); // NewPing setup of pins and maximum distance for right sensor.

unsigned int uS; //declare variable for ping time in microseconds

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

void loop() {
  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  uS = sonar_L.ping(); // Send ping, get ping time in microseconds (uS).

  Serial.print("L Ping: ");
  Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)

   
  uS = sonar_R.ping(); // Send ping, get ping time in microseconds (uS).

  Serial.print("\tR Ping: ");
  Serial.println(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)

}
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: OhMyCod on Sep 14, 2014, 08:36 pm
Hi Tim,

Can this library be used to work with the maxsonar range of proximity sensors? Like this one.....
https://www.sparkfun.com/products/9495 (https://www.sparkfun.com/products/9495)

The sensor generates a pulse whose width is proportional to distance, the problem is that measuring the pulse width requires the use of the pulseIn() function which can take some time.

Thanks
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: Howard782 on Sep 18, 2014, 01:27 am
Hi Tim

Thanks for your great NewPing Library. I would like to ask two questions please:-

1. Can I use multiple sensors using the one wire method? or is that a no, as your 15 sensors example uses both wires?

2. I would like to know your thoughts on multiple sensors versus one sensor on a rotating platform, which is 'better' and why?

Can't wait for version 1.6!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: rugby21_22 on Oct 04, 2014, 12:51 pm
hi all anybody can  tell me that what is that US_ROUNDTRIP_IN in the code? and how can i get distance in INCHES kindly waiting for you reply ?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: AWOL on Oct 04, 2014, 02:44 pm

hi all anybody can  tell me that what is that US_ROUNDTRIP_IN in the code? and how can i get distance in INCHES kindly waiting for you reply ?
Have look at reply #502 and see if that gives you any clues.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Nov 17, 2014, 04:48 pm
OK here is a suprise: set the Trigger_Pin and Echo_Pin to the same port and by golly it seems to be working fine!

Ping / Parallax  28015 3-pin sensor
Correct, NewPing is designed to use a unified pin for both trigger and echo.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Nov 17, 2014, 04:55 pm
Hi Tim,

Can this library be used to work with the maxsonar range of proximity sensors? Like this one.....
https://www.sparkfun.com/products/9495 (https://www.sparkfun.com/products/9495)

The sensor generates a pulse whose width is proportional to distance, the problem is that measuring the pulse width requires the use of the pulseIn() function which can take some time.

Thanks
No, those use different methods of communicating distance, none of which are standard for every other ping sensor.  The trigger methods are different as well.  Basically, that sensor needs a totally different library.  They're good sensors, just different (and way over priced).  But, you'll go to heaven if you buy one ;)

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Nov 17, 2014, 04:56 pm
Hi Tim

Thanks for your great NewPing Library. I would like to ask two questions please:-

1. Can I use multiple sensors using the one wire method? or is that a no, as your 15 sensors example uses both wires?

2. I would like to know your thoughts on multiple sensors versus one sensor on a rotating platform, which is 'better' and why?

Can't wait for version 1.6!
Yes, you can use one wire for each sensor even when communicating with 15+ sensors.  Just use the same pin for both trigger and echo.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Nov 17, 2014, 05:02 pm
hi all anybody can  tell me that what is that US_ROUNDTRIP_IN in the code? and how can i get distance in INCHES kindly waiting for you reply ?
See the NewPing syntax wiki (https://code.google.com/p/arduino-new-ping/wiki/Using_NewPing_Syntax)

You can just use the sonar.ping_in() method or do a regular sonar.ping() and convert it to inches with sonar.convert_in().  Basically, for all the examples, just replace the CM with IN and the results are in inches.  I use CM as a default because it's more granular.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: enfeather on Nov 18, 2014, 03:27 pm
Hi Tim,

Apologies if this falls slightly out width the scope of this thread: I am using your NewPing library with the 4-pin Ultrasonic HC-SR04. I wish to read the distance (serial) data into Maxuino using Firmata. Is there a simple way to integrate the NewPing code into the StandardFirmata sketch and hence read the values in Maxuino?

Any thoughts would be much appreciated,

Thanks,

Michael
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: mcain99 on Nov 24, 2014, 10:13 pm
I am looking at the NewPing15Sensors example and I'm trying to understand the code in the loop():
Code: [Select]
void loop() {
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }
  }
  // The rest of your code would go here.
}


The currentSensor global variable gets set, then the ping_timer function is called and the for loop goes on to the next sensor check.  However it is possible (but probably not likely) for the next sensor check to overwrite the currentSensor variable before the echoCheck function for the previous sensor is called.  Or am I not understanding what is happening in the example?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: z3t0 on Dec 05, 2014, 06:04 am
Not sure if this has been asked... but which pins on the arduino uno r3 can be used for sonar? I mean for the single pin sketch.

Thanks.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: larryd on Dec 05, 2014, 06:26 am
Which sensor are you going to use?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: z3t0 on Dec 08, 2014, 05:28 am
Which sensor are you going to use?
Sorry for late reply. I am currently using the Parallax Ping Sensors.
Are there any better ones you would suggest? Or maybe something slightly... cheaper :D.

Its a school project so I have to consider how much  money it costs so everyone can participate.

Thanks!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: NomNom on Dec 18, 2014, 03:57 pm
I am not sure why I'm not getting a return of zero for sensor readings that are out of range.  I get wildly varying distances when there is nothing in front of the sensors, but accurate readings when I have something in front.  Any ideas? I have two HC-SR04s on my bot, so I modified the NewPingExample for 2 sensors, but it does the same thing when only one sensor is being pinged.

Hey TryChick,

Did you ever get this issue resolved?

I've been having the same problem with the sensor setup to read between 100cm-400cm
Using a DYPME007Y sensor and an Attiny84.Instead of showing a '0' for anything past 400cm, the readings are fluctuating all over the place but the sensor is accurate when something is in front of it.

Any assistance would be super appreciated from anyone who can chyme in on this.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 18, 2014, 05:57 pm
The currentSensor global variable gets set, then the ping_timer function is called and the for loop goes on to the next sensor check.  However it is possible (but probably not likely) for the next sensor check to overwrite the currentSensor variable before the echoCheck function for the previous sensor is called.  Or am I not understanding what is happening in the example?
It would be possible, but only if you had unrealistic timing set between pings.  In other words, in the example sketch it's not possible, but if you change the time between pings to be 1ms, then yes, it could happen.  But then, there would be a ton of other problems anyway.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 18, 2014, 05:59 pm
Sorry for late reply. I am currently using the Parallax Ping Sensors.
Are there any better ones you would suggest? Or maybe something slightly... cheaper :D.

Its a school project so I have to consider how much  money it costs so everyone can participate.

Thanks!
You can get sensors on eBay for about $3 (probably less) including shipping.  You can use any pin.  I'd stay away from pin 13 because it has the led on it.  But the rest shouldn't have a problem.  There's not really a best pin to use, all work equally well.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 18, 2014, 06:04 pm
Hey TryChick,

Did you ever get this issue resolved?

I've been having the same problem with the sensor setup to read between 100cm-400cm
Using a DYPME007Y sensor and an Attiny84.Instead of showing a '0' for anything past 400cm, the readings are fluctuating all over the place but the sensor is accurate when something is in front of it.

Any assistance would be super appreciated from anyone who can chyme in on this.
It's possible that 400cm is just too far to get consistent readings.  While the specs on most sensors say they work to 500cm, I find that that's no typically the case.  Try setting the limit to maybe 200cm and see if you get more predictable results.

Also, returning zero is correct when something is out of range.  1-max is what you get when something is in range, and zero is out of range.  This is so you can setup logic for in and out of range.  Making out of range be max, for example, is different than something that isn't there at all.  Anyway, with it set to zero, you can use your own logic because you have a unique condition on out of range.  There's a define setting in the library that you could change to set the out of rage to another value.  So, you could do something like 500 if you wanted it to be a different value instead of zero.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: NomNom on Dec 18, 2014, 07:07 pm
It's possible that 400cm is just too far to get consistent readings.  While the specs on most sensors say they work to 500cm, I find that that's no typically the case.  Try setting the limit to maybe 200cm and see if you get more predictable results.

Also, returning zero is correct when something is out of range.  1-max is what you get when something is in range, and zero is out of range.  This is so you can setup logic for in and out of range.  Making out of range be max, for example, is different than something that isn't there at all.  Anyway, with it set to zero, you can use your own logic because you have a unique condition on out of range.  There's a define setting in the library that you could change to set the out of rage to another value.  So, you could do something like 500 if you wanted it to be a different value instead of zero.

Tim
Hey Tim,

Thanks for getting back to me on this issue. Please bare with me since I'm still in 10th grade and fairly new to some of these aspects

I have tried a simple sketch that will blink an LED if anything is between 100cm to 400cm on an Arduino and the code worked perfectly. The light would turn ON when an object was within that range and if i pointed the sensor straight up towards the sky the LED would turn OFF and on the serial monitor i would see 0cm repeated.The sensor I'm using reads pretty well up to 480cm.

BUT when i put the same code onto an Attiny84@ 8mhz everything works perfect ,including detecting objects at closer range, except for the part where me pointing the sensor to the sky would still activate the LED instead of it being read as a '0' and keeping the LED turned OFF.

The Attiny84 is communicating with the sensor through a logic level converter, since i need to run the Attiny84 from a 3.6v Lipo battery but the sensor is running off a 5v step up module so that i can save power when the sensor is not needed.

Could the issue be the logic level converter?
Or, possibly the power supply for the Sensor and/or Attiny 84.

I attached a very rough drawing of what the circuit looks like but hopefully it could point to a potential fault.
Also I attached the fairly straightforward code I'm using with the Attiny84, all timer related parts are commented out in the NewPing library.

Hope this can be of some help, thanks again.


Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 18, 2014, 07:40 pm
Hey Tim,

Thanks for getting back to me on this issue. Please bare with me since I'm still in 10th grade and fairly new to some of these aspects

I have tried a simple sketch that will blink an LED if anything is between 100cm to 400cm on an Arduino and the code worked perfectly. The light would turn ON when an object was within that range and if i pointed the sensor straight up towards the sky the LED would turn OFF and on the serial monitor i would see 0cm repeated.The sensor I'm using reads pretty well up to 480cm.

BUT when i put the same code onto an Attiny84@ 8mhz everything works perfect ,including detecting objects at closer range, except for the part where me pointing the sensor to the sky would still activate the LED instead of it being read as a '0' and keeping the LED turned OFF.

The Attiny84 is communicating with the sensor through a logic level converter, since i need to run the Attiny84 from a 3.6v Lipo battery but the sensor is running off a 5v step up module so that i can save power when the sensor is not needed.

Could the issue be the logic level converter?
Or, possibly the power supply for the Sensor and/or Attiny 84.

I attached a very rough drawing of what the circuit looks like but hopefully it could point to a potential fault.
Also I attached the fairly straightforward code I'm using with the Attiny84, all timer related parts are commented out in the NewPing library.

Hope this can be of some help, thanks again.
Have you tried not using the logic level converter?  I would guess that a 3.6v trigger would cause the sensor to ping and the Arduino would sense the 3.6v output signal as well.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: MarianaaRoldan on Dec 18, 2014, 08:35 pm
Hello teckel, my name is Mary.

Let me tell you that i'm working on my thesis and I decided to use two HC-SR04 sensors to measure two different distances and then obtain the difference between them. I'm using a 16x2 LCD display to show both numbers but I have a problem with this. This is my program:

#include <LiquidCrystal.h>
#define PIN_TRIG 9
#define PIN_ECO  13
#define PIN_ECO2 8

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {

  Serial.begin (9600); 

  pinMode(PIN_TRIG, OUTPUT);
  pinMode(PIN_ECO, INPUT);
  pinMode(PIN_ECO2, INPUT);



}

void loop() {
  float duration, distance;
  float duration2, distance2; 
  float diference;
 
 
  digitalWrite(PIN_TRIG, LOW); 
  delayMicroseconds(2);
  digitalWrite(PIN_TRIG, HIGH); 
  delayMicroseconds(10);       
  digitalWrite(PIN_TRIG, LOW);
     
 
  duration = pulseIn(PIN_ECO, HIGH);
  duration2 = pulseIn(PIN_ECO2, HIGH);

 
  distance = (duration/2) / 29;
  distance2 = (duration2/2) / 29;
 
 
  difference= distance - distance2;
 
 
  lcd.clear();
  lcd.setCursor(0, 0);
 
 
  lcd.setCursor(0,1);
  lcd.print(difference);
  lcd.print(" cm");
   
   
  delay(100);
 
}

I see that the numbers vary slightly in its decimal part, and my question: Is there any kind of mean filter or way to obtain a "static" result in the decimal part?

Thank you for your time! Greetings!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 18, 2014, 09:04 pm
Hello teckel, my name is Mary.

Let me tell you that i'm working on my thesis and I decided to use two HC-SR04 sensors to measure two different distances and then obtain the difference between them. I'm using a 16x2 LCD display to show both numbers but I have a problem with this. This is my program:

#include <LiquidCrystal.h>
#define PIN_TRIG 9
#define PIN_ECO  13
#define PIN_ECO2 8

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {

  Serial.begin (9600); 

  pinMode(PIN_TRIG, OUTPUT);
  pinMode(PIN_ECO, INPUT);
  pinMode(PIN_ECO2, INPUT);



}

void loop() {
  float duration, distance;
  float duration2, distance2; 
  float diference;
 
 
  digitalWrite(PIN_TRIG, LOW); 
  delayMicroseconds(2);
  digitalWrite(PIN_TRIG, HIGH); 
  delayMicroseconds(10);       
  digitalWrite(PIN_TRIG, LOW);
     
 
  duration = pulseIn(PIN_ECO, HIGH);
  duration2 = pulseIn(PIN_ECO2, HIGH);

 
  distance = (duration/2) / 29;
  distance2 = (duration2/2) / 29;
 
 
  difference= distance - distance2;
 
 
  lcd.clear();
  lcd.setCursor(0, 0);
 
 
  lcd.setCursor(0,1);
  lcd.print(difference);
  lcd.print(" cm");
   
   
  delay(100);
 
}

I see that the numbers vary slightly in its decimal part, and my question: Is there any kind of mean filter or way to obtain a "static" result in the decimal part?

Thank you for your time! Greetings!
You're using the "standard" way of communicating with ping sensors.  This doesn't work well at all, which is why I developed the NewPing library.

I would suggest implementing my library in your script and use the ping_medium() method.  Also, separating out the triggers to two pins (one for each sensor) instead of trying to do both at the same time.  When using ping_medium(), NewPing will by default do 5 pings and then select the medium distance.  This will be the filter you're looking for to get more stable results.  You can also increase the number of pings to further filter the results.  For example, ping_medium(15) will find the medium ping over 15 pings, which should be very stable.

I also use a very fast algorithm to get the medium value, so the computation is very fast.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: NomNom on Dec 20, 2014, 12:19 am
Have you tried not using the logic level converter?  I would guess that a 3.6v trigger would cause the sensor to ping and the Arduino would sense the 3.6v output signal as well.

Tim
Hey Tim,

I believe i might have figured out the issue, turns out the boost converter was outputting an inconsistent voltage which was causing these strange fluctuations. I added a 400uf capacitor which seems to have smoothed out the voltage output and solved the problem.

I just wanted to make sure i came back and wrote down my solution in case someone else is running into a similar issue and also to thank you for being the badass behind this awesome library and for the continued support :)
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Dec 21, 2014, 11:21 pm
Hey Tim,

I believe i might have figured out the issue, turns out the boost converter was outputting an inconsistent voltage which was causing these strange fluctuations. I added a 400uf capacitor which seems to have smoothed out the voltage output and solved the problem.

I just wanted to make sure i came back and wrote down my solution in case someone else is running into a similar issue and also to thank you for being the badass behind this awesome library and for the continued support :)
Ah yes. Putting caps before & after voltage regulators or converters is always a good idea. Typically boost converters have a built-in capacitor on the output. But if it was a bare IC, check the spec sheet for the appropriate capacitor to use.

Glad to hear you got it sorted out.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06,...__srf06 pinout?
Post by: All4U on Jan 12, 2015, 04:26 am
Hi Tim,

In referred with SRF06 datasheet, said:

"The other set of 5 pins:
The 5 pins marked "programming pins" are used once only during manufacture to program the Flash memory on the PIC16F630 chip. The PIC16F630's programming pins are also used for other functions on the SRF06, so make sure you don't connect anything to these pins, or you will disrupt the modules operation."

So, kindly pls hepls which pin on SRF06 is connected?
Many thanks!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: All4U on Jan 12, 2015, 08:26 am
Hi Tim,

I checked again and figured out those SRF06 that i have on my table are differ from you indicated ones,

They are the same with this: http://www.robot-electronics.co.uk/htm/srf06tech.htm, they already have a uC (PIC16F630) doing the ping task and return 4-20mA at two crew terminals. Others five pins may be the ICSP for onboard uC...

Then i think these type of SRF06 will not work with NewPing Lib. And may be i need to do the same that I have used them with ADC input before, .......to try your NewPing, guess i have change to SRF05.. :(

Thanks and Best Regards!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 13, 2015, 11:02 pm
Hi Tim,

I checked again and figured out those SRF06 that i have on my table are differ from you indicated ones,

They are the same with this: http://www.robot-electronics.co.uk/htm/srf06tech.htm, they already have a uC (PIC16F630) doing the ping task and return 4-20mA at two crew terminals. Others five pins may be the ICSP for onboard uC...

Then i think these type of SRF06 will not work with NewPing Lib. And may be i need to do the same that I have used them with ADC input before, .......to try your NewPing, guess i have change to SRF05.. :(

Thanks and Best Regards!
You are correct.  That's a totally different SRF06 type.  It's the wild wild west when it comes to ultrasonic sensors with dozens of companies making [mostly] slightly different units with the same model number.  For your particular sensor, it's totally different than the SRF06 that works with the NewPing library.  The one that I have that works with NewPing looks like this:



http://i00.i.aliimg.com/img/pb/296/610/503/503610296_888.jpg (http://i00.i.aliimg.com/img/pb/296/610/503/503610296_888.jpg)

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: spyguy518 on Jan 19, 2015, 03:32 am
Every time I try this, I get an error, saying "NewPing does not name a type". I also get one that says " sonar was not declared in this scope" I have not changed the code, I am only using your example code! Please help!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 19, 2015, 08:56 pm
Sounds like you didn't install the library?

Tim
Every time I try this, I get an error, saying "NewPing does not name a type". I also get one that says " sonar was not declared in this scope" I have not changed the code, I am only using your example code! Please help!
Maybe you didn't install the library?

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: psolyom on Jan 27, 2015, 10:32 pm
Hi,

I am using NewPing library to run HC-SR04 sensor.
Using the sample application attached to NewPing library
and the most simple sketch connecting the four PINs:
Vcc >> 5v
GND >> GND
Trig >> 12
Echo >> 11

It works fine, but a strange issue appears depending the distance of the closest object:
- when the closest object is closer then 10mm
- when the closest object is farther then about 2m
The sensor stops measuring and I have the impression the transducer stops pulsing - can't hear the pulsing noise anymore.
Then I move the sensor or put an object in about 100mm distance, but the sensor is still hanging - still no pulsing noise.
After this I give a light hit to the sensor with my finger. It starts pulsing and measuring again.
I tried to power off / on the sensor, it did not help.

Somehow I can accept the case, when the object is too close to the sensor, but seeing in long distance can't be avoided.

I bought 3 sensors, each with the same strange behavior.

Do you have any idea, if this issue can be avoided/solved by the software?

Thanks,Peter
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: teckel on Jan 28, 2015, 05:28 am
Hi,

I am using NewPing library to run HC-SR04 sensor.
Using the sample application attached to NewPing library
and the most simple sketch connecting the four PINs:
Vcc >> 5v
GND >> GND
Trig >> 12
Echo >> 11

It works fine, but a strange issue appears depending the distance of the closest object:
- when the closest object is closer then 10mm
- when the closest object is farther then about 2m
The sensor stops measuring and I have the impression the transducer stops pulsing - can't hear the pulsing noise anymore.
Then I move the sensor or put an object in about 100mm distance, but the sensor is still hanging - still no pulsing noise.
After this I give a light hit to the sensor with my finger. It starts pulsing and measuring again.
I tried to power off / on the sensor, it did not help.

Somehow I can accept the case, when the object is too close to the sensor, but seeing in long distance can't be avoided.

I bought 3 sensors, each with the same strange behavior.

Do you have any idea, if this issue can be avoided/solved by the software?

Thanks,Peter
By guess is that you're using the example sketch which sets the maximum distance at 200cm.  If you want to get measurements beyond 200cm, you'll need to change the max distance to something greater than 200cm, or remove the setting which will default to 500cm.

Also, the sensors are not very good at detecting objects that are very close.  Typically, you can get readings down to around 3cm, but it depends on the sensor manufacture.

Also, I suggest that you try the beta version 1.6 of NewPing.  That may yield different results as some of the timeouts were changed in v1.6.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5
Post by: korzprod on Jan 28, 2015, 03:01 pm
Thank you! I used your library for my project in school.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: DenkiKouji on Feb 03, 2015, 10:11 pm
Hi, thanks for the library. I am new to this and have two SR04 sensors from eBay. This library finally got them working, but some strange behaviour is driving me crazy. Using the sample NewPing sketch the sensors give a reading, but when I move the breadboard around to point in a different direction, the reading goes to 0cm and no reset button or power reset will bring it back. I have to either replug the sensor while everything is up and running, or disconnect/reconnect GND a few times may also bring it back. I just changed all the jumper wires just in case it was a connection, but it did not change the behaviour. Both sensors behave the same.

I have the setup as in the example sketch, Trig on pin 12, Echo on 11. arduino uno
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: teckel on Feb 03, 2015, 10:44 pm
Hi, thanks for the library. I am new to this and have two SR04 sensors from eBay. This library finally got them working, but some strange behaviour is driving me crazy. Using the sample NewPing sketch the sensors give a reading, but when I move the breadboard around to point in a different direction, the reading goes to 0cm and no reset button or power reset will bring it back. I have to either replug the sensor while everything is up and running, or disconnect/reconnect GND a few times may also bring it back. I just changed all the jumper wires just in case it was a connection, but it did not change the behaviour. Both sensors behave the same.

I have the setup as in the example sketch, Trig on pin 12, Echo on 11. arduino uno

Have you tried using the v1.6 beta release of NewPing?  I've never experienced anything like this with any of my sensors.  But, you're the second person to report this in just the last couple weeks.  Maybe you're the same person or maybe there's a bad batch of sensors on eBay?  But, first trying v1.6 beta would be well worth it as the timing and timeouts have changed quite a bit.

Let me know what you find!

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: trippme on Feb 03, 2015, 11:38 pm
My son and I are trying to build a parking distance meter.  We have a SR04 sensor and are using the NewPing v.16b routine and the example given.

Using a breadboard I have GND->GND, Vcc->5v, Trig->pin 12, Echo->pin 11

We are getting a funky result so I feel like i'm doing something wrong (I am a novice at Arduino).  The distances I get back in CM or IN are WAY wrong and they get bigger as I get closer to the sensor.  Also when I setup a ruler and an item in the sensor's field of view (say 3" away from the sensor) it was reading ~34".

I'm wondering if my Arduino is messed up but not sure how to test/verify this.

Any suggestions would be much appreciated!

Thanks,
Tripp
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: teckel on Feb 04, 2015, 01:13 am
My son and I are trying to build a parking distance meter.  We have a SR04 sensor and are using the NewPing v.16b routine and the example given.

Using a breadboard I have GND->GND, Vcc->5v, Trig->pin 12, Echo->pin 11

We are getting a funky result so I feel like i'm doing something wrong (I am a novice at Arduino).  The distances I get back in CM or IN are WAY wrong and they get bigger as I get closer to the sensor.  Also when I setup a ruler and an item in the sensor's field of view (say 3" away from the sensor) it was reading ~34".

I'm wondering if my Arduino is messed up but not sure how to test/verify this.

Any suggestions would be much appreciated!

Thanks,
Tripp
Would need to see the sketch to diagnose this.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: DenkiKouji on Feb 04, 2015, 06:37 am
Have you tried using the v1.6 beta release of NewPing?  I've never experienced anything like this with any of my sensors.  But, you're the second person to report this in just the last couple weeks.  Maybe you're the same person or maybe there's a bad batch of sensors on eBay?  But, first trying v1.6 beta would be well worth it as the timing and timeouts have changed quite a bit.

Let me know what you find!

Tim
Hi Tim, thanks for your attention. I am not the same person... anyway, 1.6b did not help, but I also tried another hack bit of code that does not use the library and worked the sensor, and it also showed erratic behaviour so I believe it is a hardware problem. Wasted a lot of time on this, but as a beginner you always think you are doing something wrong yourself, right?

Thanks for helping to clear it up!

Dirk
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: trippme on Feb 04, 2015, 06:47 am
Would need to see the sketch to diagnose this.

Tim
The last sketch I tried was the example in the examples directory:
// ---------------------------------------------------------------------------
// Example NewPing library sketch that does a ping about 20 times per second.
// ---------------------------------------------------------------------------

#include <NewPing.h>

#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 sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

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

void loop() {
  delay(50);                     // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  Serial.print("Ping: ");
  Serial.print(sonar.ping_cm()); // Send ping, get distance in cm and print result (0 = outside set distance range)
  Serial.println("cm");
}
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: teckel on Feb 04, 2015, 06:39 pm
The last sketch I tried was the example in the examples directory:
// ---------------------------------------------------------------------------
// Example NewPing library sketch that does a ping about 20 times per second.
// ---------------------------------------------------------------------------

#include <NewPing.h>

#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 sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

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

void loop() {
  delay(50);                     // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  Serial.print("Ping: ");
  Serial.print(sonar.ping_cm()); // Send ping, get distance in cm and print result (0 = outside set distance range)
  Serial.println("cm");
}
Try the non-beta version 1.5 of NewPing.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: trippme on Feb 04, 2015, 06:42 pm
I first tried 1.5 and after reading this thread I gave 1.6b a shot.

Maybe I should buy a second arduino to double check that my current one isn't jacked up.

Thanks so much for the library and the support!
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: teckel on Feb 04, 2015, 07:22 pm
I first tried 1.5 and after reading this thread I gave 1.6b a shot.

Maybe I should buy a second arduino to double check that my current one isn't jacked up.

Thanks so much for the library and the support!
Interesting, so it locks up with both 1.5 and 1.6 beta.  These sensors are made by all kinds of different manufactures from mostly in China.  It's also possible that the sensors you have just don't work correctly.  Just because it says HC-SR04 on it doesn't mean it's the same as another HC-SR04.  I have several sensors that are different but all have HC-SR04 printed on them.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: trippme on Feb 08, 2015, 07:55 am
Any suggestion on where to get a sensor that will work?
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: brainscrew on Feb 09, 2015, 02:11 pm
Hello,

I have some sensors that can auto-ping. In that case only one pin is needed in input, no ping trigger. I looked at the one-pin modules supported by NewPing, and it looks like they all need triggering, although on the same pin, so switching from input to output.

Is it possible to add a setting to deactivate pinging altogether ? (I mean I see how to disable it in the source code, but it would be nice to have that supported by NewPing)

Of course if I misunderstand how the trigger works, and that the API allows setting one pin as echo input only, I will greatly appreciate more info on how to do that properly.

BTW: The modules I have are described here http://www.procyonengineering.com/embedded/sonamini/index.html

Thanks a lot !
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: AWOL on Feb 09, 2015, 03:20 pm
I wouldn't recommend using multiple units like that in a practical design.
Because they auto ping, you're almost certain to get interference between sensors, since you can't know if an echo is from a particular device's most recent ping, or a ping from another device.

Have a look at the function of pin 4.
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: Djanson on Feb 09, 2015, 10:48 pm
How would I go about getting separate values for each of the sensors ?

I have an LCD screen where I have 3 sensors I would like to get distances from.
How would I get it so the LCD displays :

" Distance = sensor1 value
  Distance = sensor2 value
  Distance = sensor3 value "

Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: teckel on Feb 09, 2015, 11:23 pm
How would I go about getting separate values for each of the sensors ?

I have an LCD screen where I have 3 sensors I would like to get distances from.
How would I get it so the LCD displays :

" Distance = sensor1 value
  Distance = sensor2 value
  Distance = sensor3 value "


Ping sensor 1, display the distance value, ping sensor 2, display the distance value, etc...

-or-

Ping all 3 sensors, then display the distances from all three sensors.

Just depends on how you want to do it.  Basically, your question is kind of vague and in a way implies you want someone to write a sketch for you from scratch not knowing what kind of display or sensors you have nor now they're connected and to what device.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: Djanson on Feb 10, 2015, 08:36 am
I'm actually using the newPing 15 sensors example code and trying to modify it to get 3 sensors sending data to the LCD. I'm new to using forums and using Arduino, so sorry if I get anything wrong.

I have a 20x4 LCD (J204A) and am using 3 x HC-SR04, all connected to the Arduino Mega 2560.

Code: [Select]
#include <NewPing.h>
#include <LiquidCrystal.h>


#define SONAR_NUM     3 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

int backLight = 6;    // pin 13 will control the backlight


unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM];         // Where the ping distances are stored.
uint8_t currentSensor = 0;          // Keeps track of which sensor is active.

NewPing sonar[SONAR_NUM] = {     // Sensor object array.
  NewPing(43, 42, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
  NewPing(45, 44, MAX_DISTANCE),
  NewPing(41,40, MAX_DISTANCE)
///////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////
};

void setup() {
  Serial.begin(115200);
  pingTimer[0] = millis() + 75;           // First ping starts at 75ms, gives time for the Arduino to chill before starting.
  for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
    pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
 /////////////////////////////////////////
    lcd.begin(20, 4);
     lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Reversing Sensor");

lcd.setCursor(0,1);
lcd.print("Dist1: ");
lcd.setCursor(8,1);
lcd.print("cm");
lcd.setCursor(0,2);
lcd.print("Dist2: ");
lcd.setCursor(8,2);
lcd.print("cm");
lcd.setCursor(0,3);
lcd.print("Dist3: ");
lcd.setCursor(8,3);
lcd.print("cm");

}

void loop() {
 

  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.
 
 
  for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
    if (millis() >= pingTimer[i]) {         // Is it this sensor's time to ping?
      pingTimer[i] += PING_INTERVAL * SONAR_NUM;  // Set next time this sensor will be pinged.
      if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
      sonar[currentSensor].timer_stop();          // Make sure previous timer is canceled before starting a new ping (insurance).
      currentSensor = i;                          // Sensor being accessed.
      cm[currentSensor] = 0;                      // Make distance zero in case there's no ping echo for this sensor.
      sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
    }
  }
 
 ///code for LCD ping test insert here///


 
 
}

void echoCheck() { // If ping received, set the sensor distance to array.
  if (sonar[currentSensor].check_timer())
    cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
  for (uint8_t i = 0; i < SONAR_NUM; i++) {
   Serial.print(i);
    Serial.print("=");
    Serial.print(cm[i]);
    Serial.print("cm ");
  }
  Serial.println();
}


I was looking at the syntax for newping and used this code, but it didn't work
Code: [Select]

lcd.setCursor(6,1);
sonar[1].ping_cm();
lcd.print(NewPing sonar[1]);   /// tried this and it didn't work
lcd.setCursor(6,2);
sonar[2].ping_cm();             
lcd.print(sonar[2]);            /// tried this way first and didn't work



Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: teckel on Feb 10, 2015, 06:23 pm
The way your sketch works is that once it pings all the sensors it goes to the oneSensorCycle() function where you would output the results.  The ping results are in the cm[] array (values zero through 2).  Inside the for() loop, this is where you would send the value to your display.  For example:

Code: [Select]

void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
  for (uint8_t i = 0; i < SONAR_NUM; i++) {
    lcd.setCursor(6, i+1);
    lcd.print(cm[i]);
  }
}


This is stated in the oneSensorCycle() function, that a sensor ping cycle is complete, and this is where you would do something with the results.

Also, why are you turning the backlight display light on inside loop()?  Seems that would go in setup().  This, and other things, make me believe you may not know what you're doing well enough to accomplish this.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: williru on Feb 13, 2015, 03:55 pm
Hello Everybody,
i am very new to arduino (in fact, 3 days.  ;)  and i come with a probably very stupid question:
i have tried newping on a SR04 module: works great with my leonardo, from the scratch...
i have tried serLCD on a sparkfun 2x16 serial LCD, works great as well...
now i try to match these two and i´m stuck...i have a hint of an idea that i can not use two serial interfaces on my leonardo, is that right? all the lcd-examples with ultrasonic distance sensors i have found use parallel lcd...
can someone help me?
sorry if this is a very stupid question, i have searched for hours...
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: teckel on Feb 13, 2015, 04:19 pm
Hello Everybody,
i am very new to arduino (in fact, 3 days.  ;)  and i come with a probably very stupid question:
i have tried newping on a SR04 module: works great with my leonardo, from the scratch...
i have tried serLCD on a sparkfun 2x16 serial LCD, works great as well...
now i try to match these two and i´m stuck...i have a hint of an idea that i can not use two serial interfaces on my leonardo, is that right? all the lcd-examples with ultrasonic distance sensors i have found use parallel lcd...
can someone help me?
sorry if this is a very stupid question, i have searched for hours...
You say you're stuck, but not exactly WHAT is happening.  Are you getting an error?  Newping doesn't use a serial interface, so it's not that.  But, it could be all kinds of other things.  First things first, sketch and what the error is.

Tim
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: williru on Feb 13, 2015, 05:57 pm
Hi Tim,
thanks for your support... when i say i´m stuck i meant i dont know what to do: both sketches (newping and serLCD use serial port (as far as i understand); they both adress different serial "ports" (newping example use "serial.print" to adress the serial monitor, serLCD use "myserial.write" (softwareserial library) to adress the display). so i wonder if i can use both serial commands, better: how i can transfer the ping data (e.g. distance) to the myserial.write-command for LCD transfer... just write it into some integer? as you see, i am not very familiar with arduino, sorry...
Title: Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.6 BETA
Post by: teckel on Feb 13, 2015, 10:58 pm