Show Posts
Pages: 1 ... 24 25 [26] 27 28 ... 35
376  Using Arduino / Sensors / Re: High precision detection of distance and movement on: August 16, 2012, 03:17:43 pm
I want to detect and follow a fly in the room in the hope that in a next stage I can shoot it down with a laser.

You have my attention!  Have you considered a low-tech solution to your fly problem?  Like maybe fly paper ribbon?  An 8-pack for $5.17 including free shipping sounds like a cheaper and easier solution to me.

377  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5 on: August 15, 2012, 05:29:22 pm
By the way, I went with just the median method for digital filtering.  It's fast, the overhead is much smaller, and the results were just as effective as finding the mean of a centered sample.  Using ping_median() is just as simple as using ping() too.  There's nothing to figure out, just change ping() to ping_median() in your sketch and it will automatically do 5 pings and return the median ping.  To specify a different number of samples, just specify the number of iterations you want like this: ping_median(9).  Here's a sample sketch that uses ping_median:

#include <NewPing.h>

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

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

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

void loop() {
  delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  Serial.print(sonar.ping_median(3) / US_ROUNDTRIP_CM); // Send 3 pins and return the median ping converted to centimeters.

378  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.5 on: August 15, 2012, 05:19:17 pm
NewPing v1.5 released, here's what's new:

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

Download NewPing v1.5

379  Using Arduino / Sensors / Re: Distance sensor (ultrasound) water / dirt resistant for car. on: August 11, 2012, 11:21:30 pm

i want to build something like a park distance control.
The problem with the popular cheap sensors like HC-SR04 is that they will get wet or dirt will fill them when i look at the pictures.

When i look at the pdk´s you can buy at ebay or what car manufactt. use, they got closed housings (or at least very small gaps).
Also im wondering about the fact that they have both reciver and sening unit in one housing.
First i thought one sends all the time and one recives. But even the HC-SR04 seems to send and wait for signal, but why 2 sensors on the board?

I found some 14C01 sensors or USTR40-14A. But im not sure if they work.

Maby you can get me some advice, i found a mass of tutorials but only with these popular sensors that already have circuits and are not water/dirtproofed

thx smiley

Is this for parking in a garage?  If so, instead of putting the sensor on the car, you can put a HC-SR04 in the garage.

Or, are you wanting to make backup sensors?  Maybe a detailed example of what you're trying to do so we can better help.

380  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4 on: August 11, 2012, 01:32:42 am
Here's also a simplified version that just finds the median.

unsigned int NewPing::ping_median(uint8_t it) {
int uS[it], last;
uint8_t j, i = 0;
uS[0] = NO_ECHO;
while (i < it) {
last = ping();           // Send ping.
if (last == NO_ECHO) {   // Out of range ping.
it--;                // Skip, don't include as part of median.
last = _maxEchoTime; // Adjust "last" variable so delay is correct length.
} else {                       // Ping in range, include as part of median.
if (i > 0)                 // Don't start sort till second ping.
for (j = i; j > 0 && uS[j - 1] < last; j--) // Insertion sort loop.
uS[j] = uS[j - 1]; // Shift ping array to correct position for sort insertion.
else j = 0;                // First ping is starting point for sort.
uS[j] = last;              // Add last ping to array in sorted position.
i++;                       // Move to next ping.
if (i < it -1) delay(PING_MEDIAN_DELAY - (last >> 10)); // Millisecond delay between pings.
return (uS[it >> 1]); // Return the ping distance median.

This saves 112 bytes of complied code size so it's worth considering.  I could add both a ping_median() and ping_mode() but I feel that's a little excessive.  Any statistic types out there may want to chime in on if a pure median calculation is good enough in removing digital noise.  Or, if the addition of the truncated mean with removed +/-2cm outliners is worth the 112 byte loss.  Median and truncated mean yield different cm results about 10% of the time, but which one is better or more correct?  When they return two different values there's not one value that's clearly more accurate more consistently as far as I can tell.

I'm leaning towards the above ping_median method as a digital filter.  It's 112 bytes smaller and seemingly just as effective (albeit sometimes different).

381  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4 on: August 11, 2012, 01:11:36 am
Okay, I believe I've got the new digital filtering method down to as lean as it's going to get with all the kinks worked out.  For the coders out there, here's the method:

unsigned int NewPing::ping_ave(uint8_t it) {
int uS[it], last, median;
uint8_t i, j, cnt = 0;
unsigned long total = 0;
uS[0] = last = ping();   // Send first ping (done here to assist insertion sort).
for (i = 1; i < it; i++) {                                                    // Ping iterations.
if (last != NO_ECHO) cnt++;                                               // Array median tracking.
delay(PING_AVE_DELAY - ((last == NO_ECHO ? _maxEchoTime : last) / 1000)); // Delay between pings.
last = ping();                                                            // Send ping.
for (j = i; j > 0 && uS[j - 1] < last; j--) uS[j] = uS[j - 1];            // Insertion sort (big to small).
uS[j] = last;                                                             // Add last ping to array in correct order.
if (last != NO_ECHO) cnt++; // Array median tracking.
median = uS[cnt >> 1];      // Find median.
cnt = 0;                    // Reset counter.
for (i = 0; i < it; i++) {                           // Loop through results.
if (abs(median - uS[i]) < US_ROUNDTRIP_CM * 2) { // Exclude values outside +/-2cm range (digital noise).
total += uS[i];                              // Building truncated mean.
cnt++;                                       // Increment counter.
return (total / cnt); // Return the ping distance mean minus digital noise (truncated mean).

To actually implement it you would need to define PING_AVE_DELAY to 29 and add the method to the class (I set the iterations [it] to default to 5).  I know not everyone is adept at doing this, but this is a preview for those that are.  Also, if there's any statistical gurus out there that want to poke holes in my code, feel free (statistics is not my thing).

The method uses two passes to calculate a truncated mean with outliner pings removed (digital noise).  The first pass collects the pings, keeps track of successful pings, and sorts on-line using the very simple and fast insertion sort.  Before the second pass it then calculates the median ping (with the unsuccessful pings filtered out).

Once the median value is found, it then does another pass to calculate the truncated mean.  Outliner pings are those outside +/-2cm (these are not calculated as part of the mean).  Because insertion sort is done on-line instead of in another pass (like a typical bubble sort), even the max of 255 ping iterations can be done without any perceived slow-down (although 255 is a little excessive, 3-9 is typically plenty).  Insertion sort is *very* fast with a small quantity of values to sort.  So fast that highly complex sort algorithms like quicksort resort to insertion sort when there's only a few values to sort (like in this case).  Also, insertion sort has a very small stack footprint (only one variable) and extremely small code size (because it's so simple, 2 lines of code).  It's really the only sort to use on Arduino.

In laymen terms, the new method does a user-specified number of pings as fast as it can (29ms per ping) ignores out of range pings, sorts the ping values, gets the middle distance ping value, filters out pings outside +/-2cm of the middle distance ping, and returns the average of these pings in microseconds.

unsigned int us = sonar.ping_ave(); // Defaults to 5 iterations, returns the truncated mean in microseconds.
unsigned int us = sonar.ping_ave(3); // Do 3 iterations, returns the truncated mean in microseconds.
unsigned int cm = sonar.convert_cm(sonar.ping_ave(9)); // Do 9 iterations and get the truncated mean in cm.

A few explanations about the method specific to the programming.  First, some things may not appear as clean as they could be.    In many cases this is done to make the code smaller once compiled.  By making these changes around 100 bytes was saved on the final compiled code.  I believe this is a fair compromise with the limited memory in the ATmega.  Secondly, there are some items that may not be statistically perfect.  An example is the median when there's an even number of values.  The code only picks one median value, even if there technically should be the average of two.  This again was done to reduce compiled code size and it also doesn't make much difference as there's a lot of fuzzy logic in a truncated mean anyway.

Basically, the function could be re-worked to be more clear, logical, and maybe slightly more statistically accurate.  But, that's technically how the function started.  I tweaked it over the course of a few days to try and squeeze as many bytes as I could out of it.

With that said, if there's something wrong, a suggestion, or another performance tweak that doesn't make the compiled code larger, please let me know (that's one of the reasons I'm posting the method before it's released).

382  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4 on: August 10, 2012, 02:17:39 am
my robot is working fine with just one single sonar and using that same old ping library
 all i did was calibrating the time of servo movement with the time taken by sonar to take a reading
digitalWrite(trigPin, LOW);                   // Set the trigger pin to low for 2uS
  digitalWrite(trigPin, HIGH);                  // Send a 10uS high to trigger ranging

  digitalWrite(trigPin, LOW);                   // Send pin low again
  int distance = pulseIn(echoPin, HIGH);        // Read in times pulse
  distance= distance/58;  // Calculate distance from time of pulse
  delay(10);                            // Wait 50mS before next ranging

I can see that your robot has problems at times which NewPing would fix.  Using the code listed will cause problems.  While you don't specifically ask for help, you must be wanting help resolving roblems I see in your video with your robot.

Switching out that code for my NewPing library will allow for faster pings and no long ping timeouts that I can see sometimes with the video of your robot.  It doesn't happen often because you have a wall around the area it's in.  But, if you didn't have that wall and it was in the wild, it would oddly pause at times.  I'm sure you've experienced this as I can see it in your video.  NewPing fixes this.

Further, you're not using event-driven programming so your robot is doing nothing when it could be doing something else (for example, multiple ping sensors or different types of sensors at the same time).  NewPing has an interrupt-driven ping method that allow you to do other things at the same time you're waiting for a ping echo.  For example, with NewPing your sketch could create a ping every 29ms while you rotate the servo.  When it received a ping echo it would trigger an interrupt that would turn your robot.  There would be no delays in your sketch so more processing could be done without resorting to slowing down the ping rate.

Hope that helps!

383  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4 on: August 10, 2012, 12:30:19 am
Only a day has passed and I've gone a totally different direction with the new multiple ping (digital filter) method.  Come to find out, the algorithm I was focusing on yesterday was missing something. Once added, the code size went up over 100 bytes.  Because of this, I threw out the code and switched to a more advanced digital filtering.  The new algorithm saves the ping results in an array, insertion sorts the array, ignoring the NO_ECHOs finds the median, and finally calculates the mean from results within 4cm of the median.

It's a more effective digital filter and the code is tight.  I'm working on making it even better by trying to implement an online median algorithm which would eliminate the need to sort (although the insertion sort currently being used is also an online algorithm and *extremely* small).

Still tweaking and testing (shaved 44 bites from the compiled code while I was writing this post).

384  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4 on: August 09, 2012, 01:13:55 am
I've been developing a new method in NewPing to do multiple pings, ignore pings that seem to be in error, and average the results.  I've implemented it several different ways, from a simple mean average, removing the min and max, and creating an array of ping distances with processing happening in a second pass.  To be honest, they all seem to give very similar (if not identical) results.  The exception is the simple mean average, which can give inaccurate results if the ping sample is small.

Because the other algorithms yield basically the same results, I've been focusing on using whatever algorithm results in the smallest code and uses the least amount of stack space.  I've got everything working quite well.  When using this method there's only a code penalty of around 300 bytes (only if you use the new average method, other methods create the same program size as before).

The algorithm looks at the first and second ping, if they're within 2cm it averages the two.  If the first two pings are greater than 2cm, it discards the first ping result.  It then averages the rest of the pings as long as they're within 2cm of the running average.  The only way this algorithm gives an inaccurate result is if there were two erroneous pings in a row, and these two were also the first two pings (very rare).  It's not the perfect, but seems to give almost identical results as fancy multiple pass digital noise filtering algorithms.

I'll be doing more testing and releasing it in the next several days.

385  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4 on: July 30, 2012, 06:15:03 pm
First of all thank your published work.
I got my HC SR04 today and searched on the internet how to get all working. I came across your library and another source from (I have seen someone posted it before) It worked flawlessly. After that I wanted to try your library. I wired all the same using pins 12 and 11 but all I got in serial monitor was junk all in one row.
I used your sketch  in the example menu.
I have a UNO r3 clone and using the newest arduino IDE
I'm a beginner so please be patient  smiley-mr-green

Did you specify the correct BAUD rate as set in the sketch?  The NewPing example sketches uses 115200 while I believe the Trollmaker sketch uses 9600 BAUD.  If you don't select the correct speed as set in the sketch, you'll get garbage.  You could also set the BAUD rate in the NewPing sketch to 9600 as well, just as long as you set the same speed both in your sketch and in the serial monitor you will see the results.

Also, with NewPing you can use just one Arduino pin instead of two.  So, you can wire both the trigger and echo to Arduino pin 10, for example, which would look something like this example sketch:

Also, I would not suggest using the Trollmaker example as a basis for a sketch; There's several problems with it, including size and speed.  It's not even okay as a training example, because the HIGH notch is not to sensor specs at 1000 uS (should be 10uS).  It also doesn't insure that the trigger pin is LOW before starting the HIGH notch.  Basically, while it may work as an example, it's really not correct and you'll have problems when you try to implement it in a larger sketch.

386  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4 on: July 30, 2012, 05:53:55 pm
Well, I found the source of the false short ping readings. I had placed the 2 sensors 5 & 10 cm away from the Arduino Uno (with wav shield) on my pedestal. Something on the board emits a directional noise that the sensors heard and misreported the distance as short. When I moved the sensors 20 cm away and put a piece of wood between them and the computer, the noise no longer spoofed the Ping sensors.  Thanks, everyone, for helping with suggestions. Tim - I am going to implement your new ping library next. I will post my results after testing.

Glad to hear you got it working with the PING))) sensor.  I didn't test the library with this sensor and trusted a user who said it worked.

387  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4 on: July 27, 2012, 10:33:37 am

I tried to modify the NewPing15Sensors but i still get the same problem of

0=123cm 1=2cm 2=0cm
0=117cm 1=3cm 2=0cm
0=126cm 1=3cm 2=0cm
0=122cm 1=3cm 2=0cm
0=122cm 1=3cm 2=0cm
0=125cm 1=3cm 2=0cm
0=117cm 1=4cm 2=0cm

I assume the problem is that you're getting 0cm from the third sensor (sensor 2)?  It seems that sensor 0 and sensor 1 are giving realistic results.  Am I assuming correctly?  You don't specifically state the problem, only provide the results so one must assume what you're reporting as a problem.

If so, sensor 2 is reporting 0cm probably because you're using pin 11.  As the multi-sensor sketch uses the timer 2 interrupt, there could be issues using pins 3 and 11.  This is mentioned in the v1.3 release notes here:

New in v1.3 - Released 6/8/2012:
Big feature addition, event-driven ping! Uses Timer2 interrupt, so be mindful of PWM or timing conflicts messing with Timer2 may cause (namely PWM on pins 3 & 11 on Arduino, PWM on pins 9 and 10 on Mega, and Tone library).

Also, as of v1.4 there's no need to use two Arduino pins.  Just specify the same trigger and echo pins in your sketch and wire from the Arduino pin to the trigger pin on the sensor, then from the trigger to echo pin of the sensor.  So, for 3 sensors you would only need to use 3 Arduino pins instead of 6 as you have it wired now.  Your pin assignment code would look something like this:

NewPing sonar[SONAR_NUM] = {
  NewPing(5, 5, MAX_DISTANCE),
  NewPing(8, 8, MAX_DISTANCE),
  NewPing(12, 12, MAX_DISTANCE)

388  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4 on: July 26, 2012, 10:47:00 pm
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?

389  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4 on: July 26, 2012, 10:21:59 pm
For me, any loop() delay >= 21ms yielded zero false negatives when testing stationary objects, between 1cm and 50cm from the sensor's emitter.

Is there any reason this should be?  Just a variation between specific hardware and the spec?  I don't mind using 39ms to be safe, but there seems to be a very harsh cutoff between the behavior at 20ms delay and the behavior at 21ms delay.

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

390  Using Arduino / Sensors / Re: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.4 on: July 18, 2012, 01:55:59 pm
My testing indicates that a 10ms delay was always too short and a 20ms delay was too short for close objects (which is counter-intuitive to me) - at least for my SR04 sensor.

Increasing the delays in my larger code base reduced but did not eliminate my false negatives.  Testing with my actual head while as stationary as I could make it produced lots of false negatives, depending on what it bounced off.  In some cases, there were no false negatives.  Moving my head while not walking was problematic, too.  I suspect I will get more false readings while walking because this adds sensor vibration.

To sum up: Minimum delay between pings for my hardware was 40ms. I have some inherent false negatives due to the target shape, target motion, and sensor vibration in my application. I'm going to keep using my digital filter, unless I've missed some other solution. I'd be happy to share my filter with others if it's of general use.

Okay, so really the only problem is the delay between pings.  I'm not suprised that a 10ms delay causes a lot of problems.  I'm actually kind of suprised that I don't have a problem with a 10ms delay as that's really too quick (sensor is getting an echo from a previous ping).  It could be the environment I'm in absorbs more sound or maybe my ping emitters are not as strong as yours.  It also makes sense that a 20ms delay causes some problems, but not as many.

Because most of these ultrasonic sensors are designed to work up to 500cm away, that distance takes sound around 29ms to travel.  So, 29ms between pings is the fastest you should really ping a sensor.  If you ping faster, you risk getting an echo from a previous ping, causing the current ping to give a zero reading.

If we follow the baseline guide I've set for NewPing, and not delay less than 29ms between pings, my guess is that you will get basically no false negatives.  The reason that 20ms gave better results with the trollmaker sketch with close objects with a 20ms delay is that the NewPing library has a timeout value for the initiation of the echo sensor while trollmaker using pulseIn can wait up to a full second.  That timeout value in NewPing is the MAX_SENSOR_DELAY which is set to 18000us (18ms).  This is plenty long, and it should never really be an issue as long as you keep the pings 29ms apart.

Set the delay to 29ms in the sketch and see if you get any false negatives.  I would suspect you get basically none.

So the question is, were you all along trying to do pings too quickly which is why you concluded that the SR04 sensor gave many false negative readings?  All of my sample sketches show delays in the 33 to 35ms range with comments not to go quicker than 29ms.

Pages: 1 ... 24 25 [26] 27 28 ... 35