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