This repository demonstrates a proof-of-concept for using Raspberry Pi based receivers to perform Time Difference of Arrival (TDOA) calculations on audio signals to geolocate the emitter. Vaguely inspired by Ukraine's SkyFortress system, I wanted to see how easy it might be to implement the skeletal - but ultimately extendable - workings of a cheap audio geolocation system using Raspberry Pi. This project offers the outline of a workable system for geolocating pulses of audio using Raspberry Pi receivers utilising cheap GPS modules and simple omnidirectional microphones.
Figure 1: Hyperbolic curves for three receivers.
Time Difference of Arrival (TDOA) is a technique used to locate a signal source by analyzing the time delay of the signal reaching multiple receivers. This project demonstrates how inexpensive hardware can be used to implement this geolocation technique for the detection and localisation of pulsed audio signals.
For more complex detection problems, additional receivers and streaming of audio data may be necessary. The former would be an easy alteration to this code base, the latter more complex.
At its most simple, this project requires two receivers to detect and process audio signals, a server to process their outputs, and some form of generating a consistent audio signal. It may also be necessary to add in a WiFi AP to create a LAN if you are out of domestic WiFi range (I used a Pi Zero with a USB WiFi adaptor).
- Raspberry Pi: Each receiver uses a Raspberry Pi to collect and process data.
- GPS Module: Provides precise timing information via PPS (Pulse Per Second) signals.
- Omnidirectional USB Microphone: Captures audio signals for TDOA calculations.
Figure 2: Hardware setup showing Raspberry Pi with GPS module and omnidirectional microphone.
- Laptop or Desktop Computer: Runs the central processing node, which receives data from the receivers, performs TDOA calculations, and visualizes the results.
This section explains the hardware and software setup required to replicate the project.
- Use the Raspberry Pi Imager to configure networking and enable SSH before burning the OS onto the SD card. I used Bullseye, as I have repeated issues with version clashes in the newest release.
- Assign unique hostnames to each Raspberry Pi to simplify network management. Make sure the server code is updated to reflect these.
- Start up your Pi.
- SSH into the Raspberry Pi once it's on the network.
- Access configuration settings via
sudo raspi-config
, then enable VNC and set the resolution:- Interface Options → Enable VNC
- Display Options → Set VNC resolution
- Finish and reboot.
The use of GPS in this project is pretty self-explanatory, but 'PPS' might not be so obvious. 'Pulse Per Second' is a highly accurate timing signal service provided by GPS, which facilitates extremely accurate timing and synchronization between devices. In our case the receivers. This synchronization is central to TDOA. There are alternatives, but using PPS saves a lot of hassle.
- Identify the pins on your GPS module:
- TX: Transmit Data
- PPS: Pulse Per Second
- GND: Ground
- VCC: Power
- Connect the GPS pins to the Raspberry Pi GPIO as follows:
- TX (GPS) → RX (Raspberry Pi)
- PPS (GPS) → GPIO (e.g., GPIO 18, pin 12)
- GND → GND
- VCC → 3.3V or 5V (per module specifications).
- Enable UART and PPS:
Add:
sudo nano /boot/config.txt
enable_uart=1 dtoverlay=pps-gpio,gpiopin=18
- Reboot the Raspberry Pi.
- Install required packages:
sudo apt update && sudo apt upgrade sudo apt install gpsd gpsd-clients pps-tools chrony portaudio19-dev
GPSD is the GPS Daemon we will be using, and Chrony is the timing software. If either are not on your device, please install them to follow the instructions below.
- Edit GPSD configuration:
Set:
sudo nano /etc/default/gpsd
DEVICES="/dev/serial0" GPSD_OPTIONS="-n"
- Disable serial-getty service:
sudo systemctl stop [email protected] sudo systemctl disable [email protected]
- Remove
console=serial0
references from/boot/cmdline.txt
. - Configure Chrony:
Add:
sudo nano /etc/chrony/chrony.conf
refclock SHM 0 offset 0.5 delay 0.2 refid GPS refclock PPS /dev/pps0 poll 3 refid PPS
- Restart Chrony:
sudo systemctl restart chrony
- Verify configuration:
- Run
cgps
to confirm GPS data is received. - Run
chronyc sources
to check PPS synchronization.
- Run
Now the hardware is configured, we need to get the processing software setup. I've used Python in this example, utilising PyAudio to perform the fourier transform and signal detection.
- Clone the repository to your Pi and navigate to the directory.
- Create a virtual environment:
python3 -m venv tdoa_env source tdoa_env/bin/activate
- Install the dependencies:
cd Raspi_Audio_Geolocation pip install -r receiver-requirements.txt
- Run and test the
main.py
code to check everything is working.
The server processes information from the receiver nodes and generates visualizations of the TDOA hyperbolas. Follow these steps to set it up.
- Install the VNC Viewer application to remotely access each Raspberry Pi.
- Clone the repository and navigate to the directory.
- Create a virtual environment:
python3 -m venv tdoa_server source tdoa_server/bin/activate
- Install the dependencies:
pip install -r server-requirements.txt
- Run the
tdoa_server.py
script to process receiver data:python3 tdoa_server.py
- Set Up the Receivers
- VNC into each Raspberry Pi and set the
main.py
script running.
- VNC into each Raspberry Pi and set the
- Start the Central Node
- On the central node (laptop/desktop), run the
tdoa_server.py
script.
- On the central node (laptop/desktop), run the
- Generate a Signal
- Produce an audio signal at the target frequency (e.g., 4000 Hz) within the area covered by the receivers. I used a CO2 air pistol for this.
- Open the html file that was generated on your server and view generated hyperbolic curve(s) and source localization on the visualization map.
The Python script tdoa_server.py
implements the core TDOA calculations. At its most simple, this works by producing a curve between the receivers where if every point on this curve was the source of an emission the time difference of arrival of this signal between the receivers would be constant. For a slightly more technical understanding, please see this section of a relevant wikipedia article. If you swap a here for the time difference derived distance between the receivers instead of the physical distance, you will get the concept.
This script performs some basic checks to ensure the hyperbolic curve is valid before plotting. i.e. that the time distance is not larger than the physical distance.
- Receiver Locations: Latitude and longitude of two receivers.
- Delta Time (Δt): Time difference of arrival between the receivers.
- Propagation Speed (v): Speed of sound (default: ~343 m/s).
The project uses the Folium library to visualize TDOA hyperbolas and receiver locations on an interactive map.
- Add support for more receivers to enable true geolocation.
- Transition to real-time TDOA analysis using streaming data.