Tuesday, January 22, 2013

Arduino MicLoc or an Acoustic Location System

(update: MicLoc is further documented here)

I always liked the general concept of signal triangulation. I always wanted to write some software related to this. Maybe even design some hardware. We see it countless times in movies as a standard way to catch the bad guys. So as I studied through the various techniques of triangulation, trilateration, multilateration, I came across with Acoustic Location. Acoustic location methods use sound to determine the distance and direction of something and sounded perfect (pun intended) for my intents, which will became clearer later on.

In order for this to work I needed least 3 input sources which I strategically placed in my backyard. (you can see the rain protection mechanism in the photo)

If you have a stereo mic line in your PC, you already have 2 input channels, but you can't have 3 mics in 2 channels... So I went on and designed a multiplexing circuit with a 555 timer, a JK flip-flop and a 4066 digital switch (which I had readily available) to connect up to 4 mics sharing the mic input. If you sample at 44.1khz from the soundboard, divide bandwidth by 2, you get around 22 samples per millisecond. The speed of sound is around 334mm/ms so the setup should give some results... but it was a big FAIL!
That's because switching from theory to practice is a nasty business. The switching circuit introduced way too much noise to be useable and I ended up loosing too many samples to have any kind of decent precision.
So I went on to plan B...

Arduino MicLoc

Arduino has some cool features, one of them being the ADC, which allow us to sample analog signals from some source. I wanted to sample the microphones output at a pretty high sampling rate, so I started to investigate the limits of the ADC.
The ADC clock is 16 MHz divided by a prescale factor. The prescale default value is set to 128 (16MHz/128 = 125 KHz) in wiring.c. A conversion takes 13 ADC clocks, so the sampling rate is about 125KHz/13 or 9600 Hz. But you can mess around with the prescale factor, which allows you to sample at a much higher rate, which is essential to proper sound location. The setup is not complicated, despite all the wires. I have 3 microphones connected to 3 2N3904 based amplifier and feed into 3 analog channels (A0,A1,A2) on the arduino nano. A temperature sensor was also added.

The arduino samples each of the channels in turn and if the value (i.e. sound intensity) is above a certain threshold it records it. If the 3 mic are above the threshold within a certain time frame, the arduino write them out to the serial port. I wrote a daemon the is listening for this data to come in from the serial line, and then does its magic, using some fancy math with  the speed of sound, temperature, time difference between the samples, mic position and sample rate. After that, it spits out the most probable geographic position of the sound source in kml, which I directly connected as a network source to Google Earth and ended up with a realtime passive acoustic locating system.

You can see the mic positions on the satellite image, on the left. The Shot 1,2 and 3 are the actual location where I shot a BB gun and the red icons is where the Arduino MicLoc estimated the location of the shots. 
I was surprised with the accuracy of this project, given that I worked on in for a weekend and extra cheap materials I used. I believe a sub meter precision shouldn't be very hard to achieve, adding some more mics, better quality amplifiers and a little software tunning.

So why MicLoc? I was pretty sure the local hunters are hunting too close to my house. I just wanted to actually see where they were shooting, in realtime!
Oh, and because MicLoc is cool.