mixing ping_timer and ping_median

Issue #9 closed
Olivier Allouch created an issue

I love them both ! Do you have an example code that would work ?

Thx in advance.

Olivier Allouch

Comments (10)

  1. Tim Eckel repo owner

    Use the 15 sensor example sketch but use maybe 5 virtual sensors (each with the same pins). Basically, it will ping the same single sensor 5 times if you do this. Then, you take the 5 results and find the median (or whatever type of averaging you want to do).

    I've considered creating a ping_timer_median() method, but there's some complexities and unknowns when doing it so I haven't yet.

    Hope this helps!

  2. Tim Eckel repo owner

    That library uses a very slow and poor way to find the median, and it also stores the values as float which makes it worse (and uses more program memory). While it would probably work, it would require some effort on your part to make it work well and the overhead would be large.

    If you look at the NewPing source, you can review the ping_median method which does the median calculation. The code snippet is here:

    unsigned long NewPing::ping_median(uint8_t it) {
        unsigned int uS[it], last;
        uint8_t j, i = 0;
        unsigned long t;
        uS[0] = NO_ECHO;
    
        while (i < it) {
            t = micros();  // Start ping timestamp.
            last = ping(); // Send ping.
    
            if (last != NO_ECHO) {         // 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 sort starting point.
                uS[j] = last;              // Add last ping to array in sorted position.
                i++;                       // Move to next ping.
            } else it--;                   // Ping out of range, skip and don't include as part of median.
    
            if (i < it && micros() - t < PING_MEDIAN_DELAY)
                delay((PING_MEDIAN_DELAY + t - micros()) / 1000); // Millisecond delay between pings.
    
        }
        return (uS[it >> 1]); // Return the ping distance median.
    }
    

    With this, the ping happens inside the loop. What you would do instead is just retrieve the ping durations from the array that's created when using the 15 sensor example. It would't take much to modify this method to be a simple function that you would call after the sensor is read.

    If you have a problem doing this, let me know and I can probably combine the 15 sensor sketch and this median method for you as a working example.

    Tim

  3. Olivier Allouch reporter

    yes I saw the source

    I think I'll use your ping_median with a callback after each ping (or delay).

    Anyway, thx for your time (and lib)

  4. Magnus

    Hello, I want to thank you for the committment and sharing of your library.

    Im trying to solve the same issue, using median value on multiple sensors instead of a single one. I'd appreciate the help to combine the 15 sensor sketch with median method as you proposed to Oliver. I've tried both examples independetly but I'm not good at programming, especially not C++ to make it work.

    What I intend to use the ultrasonic sensors for are a music instrument connected to raspberry pi 3, I have accomplished to send and receive MIDI to the raspberry with another sketch using the MIDI library to send midi inputs from a single ultrasonic, but I'd like to use it with NewPing, So I'd be using both NewPing with MIDI library for my sketch.

    My current project contains of using 2 sensors, for a theremin-like instrument (one sensor for volume/velocty and one for pitch), but I'll improve and add more sensors after Ive accomplished the theremin project, to create a piano-like layout instrument.

  5. Tim Eckel repo owner

    This library is for Arduino AVR, not the Raspberry Pi, the 15 sensor sketch wouldn't work on your hardware as it uses AVR-specific timers. The median code above could help, but you'll need to write your own ping routine using Raspberry Pi timers first before you considered getting a median from the results.

  6. spike90

    Hi Tim! can you post an example sketch for use multiple sensor and median filter? I don't know where to call the median filter method

  7. Tim Eckel repo owner

    It would simply be this sketch but remove a sensor and replace the ping_cm() with ping_median(). Also, for questions don't use the issue system, there's a support forum for help.

  8. Log in to comment