Locating the Sound Source by using 3 Sound sensors in 2D

Hi there! I'm new around here, so please don't mind me asking ridiculous questions.

I have been trying to find a way to locate a sound source with using three sound sensors. I don't need to find its exact position. An estimated location of it would still be okay. I have researched a lot and seen 'Triangulation', but I can't put it in codes. Is there any similar projects to this one?

Thanks in advance for your answers!

Comes up quite often in this forum, but most don't get very far.

Trilateration is a better search term. This paper (in English) shows how to do it in 3D: https://www.th-luebeck.de/fileadmin/media_cosa/Dateien/Veroeffentlichungen/Sammlung/TR-2-2015-least-sqaures-with-ToA.pdf

Arduino code to do that with Ultra Wide Band radio ranging beacons is here: GitHub - jremington/UWB-Indoor-Localization_Arduino: Open source Indoor localization using Arduino and ESP32_UWB tags + anchors

Of course you need to determine the distances from the microphones to the sound source, which is easiest for something like a hand clap or gunshot sound. I'll leave that to you.

It's not simple at all. First you have to record 3 perfectly synchronized audio streams - that's a must, and getting them is not simple within Arduino setup (barely possible, at reduced quality, on 8-bit variants due to the lack of memory). But if you are using, say, ESP32 - then you have enough memory.
When you have those records in memory (you don't need too much, maybe 50~ish milliseconds at, say, 11k samples per seconds, so like 500 points on each channel) - you need to run cross-correlation between them: finding such a time shift which gives you best match between samples from each of the 3 pairs you can select from 3 microphones.
Then from those time shifts you can calculate angle to the source from each pair: each of those would give you 2 possible directions, and only one would be common for all 3 pairs - that is the real direction to the sound source. This is triangulation itself, and it's the simplest part of such project (you need to know only school level geometry and very basic understanding of sound wave propagation to solve it).

Overall Arduino is not the right stack for that - it's not impossible, but introduces additional challenges - it's much simpler to make it on stm32 with its great DMA capabilities

1 Like

http://www.telecom.ulg.ac.be/triangulation/

hopefully you can tweak the code there for your purpose! :wink: (triangulation.c is the main code)

hope that helps....

Of course you need to determine the distances from the microphones to the sound source, which is easiest for something like a hand clap or gunshot sound. I'll leave that to you.

First of all, thank you so much for your answers. I have reviewed the links/articles that you sent.

To be honest, this is the part where I'm having some trouble. I'm using DAOKI Microphone Sensors (https://www.amazon.com/DAOKI-Sensitivity-Microphone-Detection-Arduino/dp/B00XT0PH10) for this project. It seems like I can't get any specific information like a hand clap's intensity. If I could find a way to determine the distances from the microphones to the sound source, which might be random everytime, I would be able to, maybe, set some thresholds. Also, FYI, my project is about directing an automatic camera, which is a Sony EVI-D31v, using sound source localization.

How will you distinguish the "sound source" from all the audio noise in the environment?

That is the really hard part.

I can't obtain an STM32 for this one and believe me, I've been trying to implement that geometry and sound wave propagation into coding.

Well, I was thinking something like this. As you know, those sound sensors have potentiometers on them to adjust their sensitivity. If I could set them to the perfect level, they would only detect my hand clap. Also, the source's precise and exact location isn't needed at this point. I could use an estimated location with certain intervals to rotate the camera towards to the source.

Thank you so much. I will examine the codes and try to implement it in Arduino environment.

Acoustic Gunshot Detection | Electronic Frontier Foundation (eff.org)

I suspect that researching the above deeply will lead to patents and proprietary tech.

If you get it stuffed into an Arduino, many will be interested on your approach.

Solve that problem before implementing the simple part (localization). Obviously, the hand clap is the simplest sort of source to identify, and that is harder than you imagine.

Fast sampling and real time waveform analysis is a popular approach.

Hello

You may start reading:

and

1 Like

What did you set the sensitivity level to? "
Real-time output of the microphone voltage signal / DO. when the sound intensity reaches a threshold "

You should get a digital output when the intensity is over the threshold setting. Those sensors and no other sensor can tell you the distance to a sound source!

before implementing the simple part (localization)

How would you approach to this simple part? I'm going to be honest, I feel like an idiot when you say like implementing the localization is the simple part. Instead of thinking about the sensitivity/detection problem of the sensor, I'm focusing on my main problem which is not being able to locate the sound source. I would be appreciated, if you tell me how simple that is or how you'd implement it in your code.

Thanks a lot for your answer! Unfortunately, I can't give you a specific value about the sensitivity since I don't have the equipment to check it. I'm just double-checking it with the led on the sensor that blinks whenever it detects a sound.

Those sensors and no other sensor can tell you the distance to a sound source!

I know that this sensor isn't capable to do that. That's why I'm going around and searching in order to find a way to calculate the distance and locating the sound source.

In post #2, I linked the methods paper, and my Github site, showing how trilateration is implemented in Arduino in a few dozen lines of code. Did you bother to look?

Maybe that does not seem simple to you, but that would be because you have seem to have no idea how difficult it is to capture, identify and derive timing and distance information from "a sound source". I imagine that you haven't tried much of anything yet, or done much research.

If you can't succeed in the latter, there is no point at all in wasting your time with the simple part, especially considering that it has already been done, many times.

In fact I misunderstood the problem - I've previously solved it with assumption that sound source is much much further than distance between microphones (that was always true for my case), and it's much simpler then. When sound source is close, trigonometrical solution becomes very cumbersome (I just spent ~20 minutes trying to solve it, and I don't like where it's going). But instead it can be quite easily solved numerically, using gradient descent:

  1. you need to write a function that calculates time differences for a given x,y coordinates of the source (that's trivial: time is proportional to distance, you calculate three times, then calculate three differences)
  2. you need to take a random x,y point at reasonable distance as a starting point
    then you make a loop:
    3.1. for current (x,y) you calculate time differences, then calculate them for (x+dx, y) and for (x, y+dy)
    3.2 you calculate errors in (x,y), (x+dx, y) and (x, y+dy) as E(x,y)=sqrt((calc_dt1 - real_dt1)^2 + (calc_dt2-real_dt2)^2 + (calc_dt3-real_dt3)^2)
    3.3 you calculate gradients on x, y: Edx = E(x+dx,y)-E(x,y), Edy=E(x,y+dy)-E(x,y)
    3.4 you move current x,y in the following way: if Edx>0 then new_x = x-step_x, else new_x=x+step_x, same for y
    3.5 you repeat this loop for quite a few times (like 100-200-500, depending on step_x, y size, in advanced version you can use larger steps for the first half of iterations and smaller ones for the rest)
    At the end of the loop, you will have either good solution (if your starting point was on the generally right side) - then error would be small-ish, or some completely wrong solution. To be sure, you can repeat the process with several random starting points and select one for which the error is minimal.

That's not pretty, but I've used this approach in some cases (including triangulation with multiple UWB modules - when you have more than 3 and particular number can be different in each cycle, that is a good way to take into account all the information) - and it works well, producing small errors. With 100 iterations in the gradient loop I was able to perform 100 triangulations per second on 72 MHz MCU (and do a lot of other stuff in parallel, if carefully implemented, it's not very computationally expensive)

It is trivial to solve by least squares. See the methods paper in post #2.

Well, while I feel comfortable with matrix operations - I find it difficult to explain them in the right way to people who are not already familiar with the concept (also when matrix is more than 3x3 like it was in my case, inversion takes certain additional effort as well - but for 3x3 it's simple enough)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.