{"id":30210090,"url":"https://github.com/mdwasserman/raspi_audio_geolocation","last_synced_at":"2026-06-20T04:31:24.510Z","repository":{"id":270617015,"uuid":"910197107","full_name":"mdwasserman/Raspi_Audio_Geolocation","owner":"mdwasserman","description":"A proof-of-concept implementation of TDOA for audio signals using Raspi. ","archived":false,"fork":false,"pushed_at":"2025-01-05T20:40:02.000Z","size":12420,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-08T21:43:23.285Z","etag":null,"topics":["geolocation","localisation","raspberry-pi","tdoa"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mdwasserman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-30T17:40:49.000Z","updated_at":"2025-01-05T20:40:06.000Z","dependencies_parsed_at":"2025-03-02T07:51:37.535Z","dependency_job_id":"246b1117-a522-4385-a485-6043bfba57ad","html_url":"https://github.com/mdwasserman/Raspi_Audio_Geolocation","commit_stats":null,"previous_names":["kdwaterman/raspi_audio_geolocation","mdwasserman/raspi_audio_geolocation"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mdwasserman/Raspi_Audio_Geolocation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdwasserman%2FRaspi_Audio_Geolocation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdwasserman%2FRaspi_Audio_Geolocation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdwasserman%2FRaspi_Audio_Geolocation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdwasserman%2FRaspi_Audio_Geolocation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mdwasserman","download_url":"https://codeload.github.com/mdwasserman/Raspi_Audio_Geolocation/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdwasserman%2FRaspi_Audio_Geolocation/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34557551,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["geolocation","localisation","raspberry-pi","tdoa"],"created_at":"2025-08-13T19:57:08.834Z","updated_at":"2026-06-20T04:31:24.499Z","avatar_url":"https://github.com/mdwasserman.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Raspberry Pi Audio Geolocation\n\nThis 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. \n\n---\n\n![Map Example](images/map_example.jpg)\n*Figure 1: Hyperbolic curves for three receivers.*\n\n\n## Table of Contents\n\n1. [Introduction](#introduction)\n2. [Hardware Description](#hardware-description)\n3. [Setup Guide](#setup-guide)\n   - [Receiver Setup](#receiver-setup)\n   - [Server Setup](#server-setup)\n4. [Running the Project](#running-the-project)\n   - [Step-by-Step](#step-by-step)\n   - [TDOA Calculation](#tdoa-calculation)\n   - [Visualization](#visualization)\n6. [Future Work](#future-work)\n\n---\n\n## Introduction\n\nTime 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. \n\n\u003e 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. \n\n---\n\n## Hardware Description\n\nAt 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). \n\n### Receivers\n\n- **Raspberry Pi**: Each receiver uses a Raspberry Pi to collect and process data.\n- **GPS Module**: Provides precise timing information via PPS (Pulse Per Second) signals.\n- **Omnidirectional USB Microphone**: Captures audio signals for TDOA calculations.\n\n![Reciever Example](images/reciever_example.jpg)\n*Figure 2: Hardware setup showing Raspberry Pi with GPS module and omnidirectional microphone.*\n\n### Server\n\n- **Laptop or Desktop Computer**: Runs the central processing node, which receives data from the receivers, performs TDOA calculations, and visualizes the results.\n\n---\n\n## Setup Guide\n\nThis section explains the hardware and software setup required to replicate the project.\n\n### Receiver Setup\n\n#### Configure SSH and VNC on the Raspberry Pi\n\n1. 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. \n2. Assign unique hostnames to each Raspberry Pi to simplify network management. **Make sure the server code is updated to reflect these.**\n3. Start up your Pi.\n4. SSH into the Raspberry Pi once it's on the network.\n5. Access configuration settings via `sudo raspi-config`, then enable VNC and set the resolution:\n   - **Interface Options** → **Enable VNC**\n   - **Display Options** → **Set VNC resolution**\n   - Finish and reboot.\n\n#### GPS and PPS Setup\n\nThe 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.\n\n##### Wiring the GPS Module\n\n1. Identify the pins on your GPS module:\n   - TX: Transmit Data\n   - PPS: Pulse Per Second\n   - GND: Ground\n   - VCC: Power\n2. Connect the GPS pins to the Raspberry Pi GPIO as follows:\n   - TX (GPS) → RX (Raspberry Pi)\n   - PPS (GPS) → GPIO (e.g., GPIO 18, pin 12)\n   - GND → GND\n   - VCC → 3.3V or 5V (per module specifications).\n\n##### Configure the Raspberry Pi\n\n1. Enable UART and PPS:\n   ```bash\n   sudo nano /boot/config.txt\n   ```\n   Add:\n   ```\n   enable_uart=1\n   dtoverlay=pps-gpio,gpiopin=18\n   ```\n2. Reboot the Raspberry Pi.\n3. Install required packages:\n   ```bash\n   sudo apt update \u0026\u0026 sudo apt upgrade\n   sudo apt install gpsd gpsd-clients pps-tools chrony portaudio19-dev\n   ```\n\n##### Configure GPSD and Chrony\n\nGPSD 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.\n\n1. Edit GPSD configuration:\n   ```bash\n   sudo nano /etc/default/gpsd\n   ```\n   Set:\n   ```text\n   DEVICES=\"/dev/serial0\"\n   GPSD_OPTIONS=\"-n\"\n   ```\n2. Disable serial-getty service:\n   ```bash\n   sudo systemctl stop serial-getty@ttyS0.service\n   sudo systemctl disable serial-getty@ttyS0.service\n   ```\n3. Remove `console=serial0` references from `/boot/cmdline.txt`.\n4. Configure Chrony:\n   ```bash\n   sudo nano /etc/chrony/chrony.conf\n   ```\n   Add:\n   ```\n   refclock SHM 0 offset 0.5 delay 0.2 refid GPS\n   refclock PPS /dev/pps0 poll 3 refid PPS\n   ```\n5. Restart Chrony:\n   ```bash\n   sudo systemctl restart chrony\n   ```\n6. Verify configuration:\n   - Run `cgps` to confirm GPS data is received.\n   - Run `chronyc sources` to check PPS synchronization.\n\n#### Python Environment\n\nNow 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. \n\n1. Clone the repository to your Pi and navigate to the directory.\n2. Create a virtual environment:\n   ```bash\n   python3 -m venv tdoa_env\n   source tdoa_env/bin/activate\n   ```\n3. Install the dependencies:\n   ```bash\n   cd Raspi_Audio_Geolocation\n   pip install -r receiver-requirements.txt\n   ```\n4. Run and test the `main.py` code to check everything is working.\n\n### Server Setup\n\nThe server processes information from the receiver nodes and generates visualizations of the TDOA hyperbolas. Follow these steps to set it up.\n\n#### Configure the Laptop for VNC Access\n\n1. Install the VNC Viewer application to remotely access each Raspberry Pi.\n\n#### Python Environment\n\n1. Clone the repository and navigate to the directory.\n2. Create a virtual environment:\n   ```bash\n   python3 -m venv tdoa_server\n   source tdoa_server/bin/activate\n   ```\n3. Install the dependencies:\n   ```bash\n   pip install -r server-requirements.txt\n   ```\n4. Run the `tdoa_server.py` script to process receiver data:\n   ```bash\n   python3 tdoa_server.py\n   ```\n\n---\n\n## Running the Project\n\n## Step-by-Step\n\n1. **Set Up the Receivers**\n   - VNC into each Raspberry Pi and set the `main.py` script running.\n2. **Start the Central Node**\n   - On the central node (laptop/desktop), run the `tdoa_server.py` script.\n3. **Generate a Signal**\n   - 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. \n   - Open the html file that was generated on your server and view generated hyperbolic curve(s) and source localization on the visualization map.\n   \n### TDOA Calculation\n\nThe 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](https://en.wikipedia.org/wiki/Hyperbola#Definitions) 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. \n\n\u003e 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.\n\n#### Key Parameters\n\n- **Receiver Locations**: Latitude and longitude of two receivers.\n- **Delta Time (Δt)**: Time difference of arrival between the receivers.\n- **Propagation Speed (v)**: Speed of sound (default: ~343 m/s).\n\n### Visualization\n\nThe project uses the Folium library to visualize TDOA hyperbolas and receiver locations on an interactive map. \n\n---\n\n## Future Work\n\n- [x] Add support for more receivers to enable true geolocation.\n- [ ] Transition to real-time TDOA analysis using streaming data.\n\n---\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdwasserman%2Fraspi_audio_geolocation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmdwasserman%2Fraspi_audio_geolocation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdwasserman%2Fraspi_audio_geolocation/lists"}