Go Down

Topic: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.7 (Read 574418 times) previous topic - next topic

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 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
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

teckel


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
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

teckel


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
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

duxiaoshi

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

AWOL

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.

duxiaoshi


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?

JesterSig

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

teckel


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:


  • Doesn't lag for 1 second if no ping/echo is received.

  • Uses port registers for a faster interface to the pins and smaller code size.

  • Allows you to set a maximum distance where pings beyond that distance are read as no ping "clear".

  • Ease of using multiple sensors.

  • More accurate distance calculation.

  • Same library works with different ultrasonic sensor models.

  • Doesn't use pulseIn, which gives incorrect results with some ultrasonic sensor models.

  • Timer interrupt method for event-driven sketches.

  • Being actively developed with features being added and bugs/issues addressed.



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
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

JesterSig

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.

teckel


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
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

duxiaoshi



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)

teckel


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
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

teckel

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?
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

teckel

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
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

cyclegadget


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!
Good links: Eagle tutorial= http://www.youtube.com/playlist?list=PLDE1858BD83D19C70
General Arduion tutorials = http://tronixstuff.wordpress.com
http://www.gammon.com.au/forum/bbshowpost.php?bbtopic_id=123

Go Up