Go Down

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

teckel

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

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

Human


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

Human


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.

teckel


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

Human


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.

Human


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

Human

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

Human

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.

teckel


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

Human


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.

Human

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.

cappyjack

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.

teckel


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

vcberta

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.

Go Up