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

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:

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:

#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

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:

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

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

teckel:
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

fairorgan:
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:

#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

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

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?

sbright33:
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

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?

sbright33:
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

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

sbright33:
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

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!

sbright33:
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

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.

sbright33:
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?

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.

sbright33:
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

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

sbright33:
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 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 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 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