Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 18 of 18

Thread: Measuring distance... with sound?

  1. #1
    Junior Member
    Join Date
    Aug 2018
    Posts
    8

    Measuring distance... with sound?

    Hi, some advice would be greatly appreciated to understand what is wrong here...
    I would like to measure distance between two points using sound.
    Ultrasonic transducers can be used for this goal, but they must face the point to measure.
    I would like to use "normal" speaker and microphone, so the sound is not so directional, and to some point, I can measure the distance between microphone and speaker even if they do not face each other.
    I am using Teensy 3.6,
    microphone is this https://www.amazon.it/gp/product/B07...?ie=UTF8&psc=1,
    speaker is connected to pin 8 through 100ohm resistor.

    Photo of the setup, where speaker and microphone is about 10cm. Click image for larger version. 

Name:	11.jpg 
Views:	10 
Size:	118.9 KB 
ID:	20004

    Code
    Code:
    // Speed of sound 0.34029 millimeters / microsecond 
    // 10cm = 100mm = approx 300us ??
    
    
    #include <ADC.h>
    
    ADC *adc = new ADC();; // adc object
    volatile int elapsed; 
    int readPin = A21; // ADC0
    int value = 0;
    
    void setup() {
    
        pinMode(readPin, INPUT);
        Serial.begin(1000000);
        adc->setAveraging(0); // set number of averages
        adc->setResolution(12); // set bits of resolution
        adc->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED); // ,  change the conversion speed
        adc->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED); // change the sampling speed
        adc->startContinuous(readPin);
     
    
    tone(8, 10000);
    }
    
    void loop() {
    
      
    unsigned long startTime = micros ();
    tone(8, 1000);
    delay(50);
    
    
    int uu=0;// (uint16_t)adc->analogReadContinuous(ADC_0);//=analogRead(A21);
    
    //do { uu=(uint16_t)adc->analogReadContinuous(ADC_0); } while (uu<2000);
     while (uu<2150)
     { if (adc->isComplete(ADC_0))
       { uu=(uint16_t)adc->analogReadContinuous(ADC_0); } 
     }
    
    
      unsigned long endTime = micros ();
    
      unsigned long elapsedTime = endTime - startTime;
      Serial.println (elapsedTime);
      noTone(8); 
      delay(50);
    
      
    }
    For each loop, I start tone, wait 50 microseconds, then start reading the ADC, until i get signal above a threasold that I have measured is slightly under the peak measured during the tone.

    The problem is that I get approx 50045us as a reading (50000us are the 50ms that I wait for the tone to "stabiliyze"), so just 45us? It should be approx 300us for 100mm.
    I tried with different frequencies for the tone from 200 to 14000, the better result I get is that if I move mic and speaker closer (about 1cm) the reading is about 15us.
    But something is wrong, I think.
    Thanks!

  2. #2
    Senior Member
    Join Date
    Feb 2018
    Location
    Corvallis, OR
    Posts
    116
    The major problem with your code is that you are waiting 50milliseconds after your tone starts and then starting to read the ADC values, but you don't really know the phase relationship between your tone and the actual collection at the ADC.

    You should try sending a brief burst of sound, then reading the ADC until you get a return. The problem with that is that the length of the burst will determine your minimum distance. The simplest output that might work with your simple amplitude detection would be a very short 'click'

    Code:
    digitalWriteFast(speakerpin, HIGH);
    delayMicroSeconds(100);
    digitalWriteFast(spekerpin, LOW);
    starttime = micros();
    int uu=0;// (uint16_t)adc->analogReadContinuous(ADC_0);//=analogRead(A21);
    
    
     while (uu<2150){
         if (adc->isComplete(ADC_0)){
               uu=(uint16_t)adc->analogReadContinuous(ADC_0); 
         } 
     }
      etc. etc.

    The problem is that such a short click really doesn't put much energy into the speaker unless you have an amplifier. Your tone output is putting 3.3V across (100 ohms + speaker impedance) or < 1/10 Watt (Pwr = V*V/R) . Most small speakers will have pretty high impedance at 10KHz, further reducing the power. Small speakers also don't respond instantly.

    In an earlier project I found that the piezo speaker in ultrasonic transducers take a while to get started and you have to pulse very near their resonant frequency--which makes wide-bandwidth chirps impossible. That was what prompted me to use a powered speaker and audio frequencies.


    I spent many hours last week working on a similar, but more complex, project.

    Instead of sending a tone, I sent a 4-millisecond chirp that went from 3000 to 6000Hz. I also applied a sine window to the chirp amplitude and sent the output to the DAC output to drive a powered speaker. The return was captured by a Sparkfun electret microphone connected to an ADC input.

    The return echo was detected using autocorrelation with the chirp data to reduce noise sensitivity and add processing gain.

    I was able to measure distances from about 4 feet to 18 feet with reasonable reliability and a resolution of about 0.1 foot.
    The generation of the chirps, the collection and processing of the data is encapsulated in a C++ object, so it's not something I would want to toss at someone unfamiliar with C++ and correlation detection. However, if you're interested I can post the code.

  3. #3
    Junior Member
    Join Date
    May 2020
    Posts
    3
    You don't mention what Speaker you use, but from the picture I am guessing is a piezo transducer.
    These guys have a resonant point that is easy to excite with a pulse. To make it more efficient and get more amplitude (assuming can handle it) what you can do is to connect it between two I/O pins and toggle them inverted each other as simultaneously as possible (use fast digitalWrite). After half the period of the resonant frequency toggle reverse and after other half equalize voltage in both pins and wait the longest reasonable fly time and repeat (if you are not measuring farther than 2m, that would be about 6mS). Essentially what will happen is like when you hit a pot with a solid object, the piezo will resonate with a sine wave and a number of bounces creating a sine burst decaying (in the oscilloscope looks like an sine arrow. What your mic has to catch is the beginning of that burst. I use to design devices like this for small robotics with hardware and software with resolution down to mm. The trick is to create a good fast swim and back. In the mic you need to look the output with a scope to make sure you see what you expect and adjust for the DC level if any. Also very recommended is to do this with a timer interrupt, where you reset the counter as you swim the piezo, and then trigger capture count with the microphone (just adapt the mic level to the logic threshold). To make your life easier, they sell in Amazon electret audio detectors that use an adjustable comparator for this purpose (rather than a pre amp). Here: https://www.amazon.com/DAOKI-Sensiti...9011339&sr=8-2 .
    This way you can avoid ADC conversion that can be slow for this application.
    Hope this helps.

  4. #4
    Junior Member
    Join Date
    Aug 2018
    Posts
    8
    Thank you very much mborgerson and RHormigo for the answers.
    I will try to apply them. The distance I have to measure is between 0 and 20 cm, 1 mm resolution would be very good, is this feasible? Thanks again.

  5. #5
    Senior Member
    Join Date
    Feb 2018
    Location
    Corvallis, OR
    Posts
    116
    I think you're out of luck trying to measure with 1mm resolution using sound at frequencies below 100KHz. Given that the speed of sound is about 343mm/millisecond,
    one mm resolution means a time resolution in measuring the propagation delay of about 3microseconds.

    At 20KHz, the sound waves have a wavelength of 17mm. I don't think you can determine the propagation time with a peak detector to 1/17th of a wavelength. Over a long time period, you might get that kind of resolution with a phase-locked loop and continuous waves, but with a peak detector and ambient noise I don't think it is feasible.

    Your problem looks like it might be better solved with one of the optical time-of-flight detectors. Here is an example:
    https://www.sparkfun.com/products/12785

  6. #6
    Junior Member
    Join Date
    May 2020
    Posts
    3

    Smile

    For that type of resolution you will need definitively to track your micros() with interrupts to mark start (when you toggle the piezo pin) and stop (when you heard back). Even a bit better if you use a dedicated hard counter that you can reset (this would help to avoid the roll over tracking). Also use fast digital write definitively to avoid the latency and likely lack of determinism. Keep in mind that audio takes about 3uS to fly 1mm in air, so your measurements needs to be more deterministic than 3uS. The sonars I developed in the past that could achieve this were using a much slower pic CPU, so in this front should be easier. However I used ultrasound transducers with much faster rising/falling times (rT, fT), here you want to use quite low frequencies with a piezo that even for a 5KHz transducer your rT/fT will be more like 100uS, what should not be a problem in ideal acoustic conditions, but unfortunately is not such thing. Angular position, mulipath scattering, surrounding resonances, even moisture... can displace randomly the threshold points that within these 100uS fT/rT can introduce a big error. You may want also to average over multiple readings to correct as possible.
    As you don't want to go further than 200 mm. In theory you can keep kicking your piezo very fast up to each 300 uS?, if the CPU and software can keep on it. What I would try is to do several measurements fast, average the value, and store that value in a low level fast loop, then work with and report the stored value.

    I hope that help,
    Rick.

  7. #7
    Senior Member
    Join Date
    Feb 2018
    Location
    Corvallis, OR
    Posts
    116
    I just caught on to the fact that you want to measure the distance between the microphone and the speaker. That's somewhat easier than the problem I was working on: measuring the distance from the mic/speaker and a reflective object. In your case, you have a much stronger received signal---particularly with a 20cm maximum range.

    One technique to consider takes advantage of the change in sound wavelength with frequency. A 1700Hz tone has a wavelength of 20.33 cm. A 16KHz tone has a wavelength of 2.16cm. To take advantage of this linear change, you can sweep your output frequency over that range and look for the maximum Pk-Pk signal when you sample at times 1/2 wavelength apart. At that point your microphone is 1 wavelength away from the speaker. And, let's face it, a minimum range of 0 cm is not going to happen with real-world transducers. Better to accept a minimum range of 2cm to keep your frequencies in a range that your speaker and microphone can handle. You can add an RC filter to reduce harmonics at the lower frequencies. That will reduce your output amplitude at higher frequencies---but at higher frequencies, you expect the mic and speaker to be closer together, so the signal will be stronger due to the smaller distance.

    Given the fast floating-point calculations and the DAC on the T3.6, you should be able to generate clean sine waves over the 1700Hz to 16Khz range with an interval timer ranging from 17,000 samples/second to 170,000 samples/second. That gives you 10 samples per output cycle, which should reduce output harmonics when compared to a simple square wave driving the speaker.

    Warning: much hand-waving, buzz words like "Auto-correlation", "Speaker harmonics", "harmonic distortion" and lots of experimentation lie between this simple proposal and a working system.

  8. #8
    Junior Member
    Join Date
    Aug 2018
    Posts
    8
    Click image for larger version. 

Name:	Schema1.png 
Views:	3 
Size:	6.0 KB 
ID:	20104

    I have thought about ToF sensors, I have used them before.
    The problem, as is maybe easier to understand with the above scheme, is that I would like to measure the distance from point A to point B. They do not always face each other, so a Tof sensor is not suitable, and ultrasonic have the same problem.
    I had some luck with a solenoid and a hall sensor, good resolution, but range is limited to a few cm.
    This is why I have thought that an audio source and a mic could have been a good solution for the problem. But I am open to any possible other solution.
    I even build a small wire rope sensor based on a potentiometer, but ideally the sensor/recevier at point A and B should be small and less invasive as possible.
    Thank you all again.

  9. #9
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    990
    But I am open to any possible other solution.
    Measuring the angle at the joints and calculate the distance?

  10. #10
    Junior Member
    Join Date
    Aug 2018
    Posts
    8
    Unfortunately nothing can be applied except on point A and point B. The 2 joints are actually much more complex, the drawing is a very simplified view.

  11. #11
    Member
    Join Date
    Feb 2020
    Location
    Dublin, Ireland
    Posts
    30
    Hi,
    What about having a single tone produced at A, a second tone at twice that frequency produced at joint 2 (or some other fixed distance from B), with both synchronised, and a microphone at B? Use filters to separate out the two signals, and then measure the time difference between zero crossings. You could average over multiple cycles for improved accuracy. Frequencies of around 800 and 1600Hz could work.

  12. #12
    Senior Member
    Join Date
    Feb 2018
    Location
    Corvallis, OR
    Posts
    116
    The problem with all these proposals are some things I hadn't yet considered:
    1. Many speakers that have adequate output at 500 to 2500Hz are an inch or two in diameter. The resulting audio output may have some interference effects (near edge vs far edge, etc.) in near-field applications like this. Remember that a 1715Hz tone has a wavelength of 20cm
    2. Amplitude and zero-crossing detection is going to get messed up by echoes from nearby objects--and for a 10milliSecond ping, objects nearer than about 5 feet will have echoes that return within the duration of the outgoing ping. That's one of the reasons to use an outgoing chirp with significant frequency modulation and correlation detection.

    I bring up these issues, because I spent some time with a sketch using chirps and correlation detection yesterday. I got mixed results at distances from 5 to 20cm. Even when I sampled and correlated at 160KHz, I wasn't able to get distance resolution better than 2mm. i also found that changes in chirp characteristics made cm-level changes in the distance measured. But hey---if it was easy, everyone would do it! (Tom Hanks as Jimmy Dugan in "A league of their own". "There's no crying in baseball!" is even better, but off topic here.)

  13. #13
    Member
    Join Date
    Feb 2020
    Location
    Dublin, Ireland
    Posts
    30
    I agree - there are lots of potential problems. The speed of sound in air is highly temperature dependent, so you'll have difficulty getting accuracy of +/-1mm over a 20cm range for that reason alone without some method of compensation.

  14. #14
    Junior Member
    Join Date
    Aug 2018
    Posts
    8
    Any ideas about how to recreates something similar, how it practically works? Maybe this can ba a solution too.
    https://www.partitalia.com/close-to-me/
    Wondering what the resolution is, anyway.

  15. #15
    Senior Member
    Join Date
    Mar 2013
    Posts
    131
    Our 2015 paper on audio localization gives some resolution numbers: https://quod.lib.umich.edu/i/icmc/bb...e=150;view=pdf

  16. #16
    Junior Member
    Join Date
    Apr 2020
    Location
    Heidelberg, Germany
    Posts
    17
    If you orient your sensors so that their axes are neutral to each other then you can neglect any change in response of the transducers with angle, so point them in the z-axis (upwards) based on your 2D diagram.

    A technique I used many years ago for determining the effects of barriers on acoustic loss was to use Maximum Length Sequence as the source noise generation and signal processing. This allows the impulse response of the system to be determined in low signal to noise ratio (SNR) environments.
    28 years ! ago this was done using an ISA card in a PC costing €10k, nowadays you may be able to do this on a teensy.

    See this link for what MLS are

    There would be some delay to get the impulse response measurement/calculation but it should be accurate.

  17. #17
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,698
    I like to through in a complete different idea.
    measure the phase shift between transmitted and received signal.
    OK, you may first to calibrate the electronic phase shift and you need a frequency that is low enough to result in unique results

  18. #18
    Junior Member
    Join Date
    Apr 2020
    Location
    Heidelberg, Germany
    Posts
    17
    Quote Originally Posted by mocher72 View Post
    If you orient your sensors so that their axes are neutral to each other then you can neglect any change in response of the transducers with angle, so point them in the z-axis (upwards) based on your 2D diagram.

    A technique I used many years ago for determining the effects of barriers on acoustic loss was to use Maximum Length Sequence as the source noise generation and signal processing. This allows the impulse response of the system to be determined in low signal to noise ratio (SNR) environments.
    28 years ! ago this was done using an ISA card in a PC costing 10k, nowadays you may be able to do this on a teensy.

    See this link for what MLS are

    There would be some delay to get the impulse response measurement/calculation but it should be accurate.
    Link didnt appear

    Try

    https://en.wikipedia.org/wiki/Maximum_length_sequence

    and

    http://www.commsp.ee.ic.ac.uk/~mrt10...S%20Theory.pdf

    Should be a case of generate the Maximum Length sequence -> send to speaker -> measure with microphone -> convolute with original MLS signal -> impulse response -> first peak is the delay time

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •