Skip to content
romartakPublic

About

Pocket spectrum analyzer + multimode radio + signal decoder on a Raspberry Pi Zero 2 W and RTL-SDR, used from your phone's browser. Sweep 0.5–1766 MHz, tap a signal to hear it, identify digital modes, decode pagers, APRS, sensors and ADS-B, record, scan and watch 24/7. Offline, receive-only, EN/ES.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

11 stars

Watchers

1 watching

Forks

Repository files navigation

SDR-Kit

A pocket spectrum analyzer, multimode radio and signal decoder — built from a Raspberry Pi Zero 2 W and an RTL-SDR, used from your phone.

CI Release License: MIT Raspberry Pi Zero 2 W Python 3.11+ Receive only UI: English | Español

📦 Install · ✨ Features · 🧪 Try without hardware · 📚 Docs · 🇪🇸 Leer en español


SDR-Kit turns ~US$90 of off-the-shelf parts into a field instrument in the spirit of the tinySA: sweep the spectrum from 0.5 to 1766 MHz, find a signal, tap once to listen to it, identify what it is, decode it, record it — all from a phone browser, with no app to install and no internet required. At home it joins your WiFi; in the field it creates its own hotspot; anywhere else it is one Tailscale hop away.

Spectrum analyzer and waterfall Multimode radio Decoded pager and APRS messages Offline aircraft radar

Note

No hardware yet? Try the panel on any computer with demo mode: pip install numpy && python3 files/sdrkit_server.py --demo --port 8080 → http://localhost:8080

Tip

In a hurry? Flash the Pi, SSH in and run one line — jump to the 3-minute version.

🔌 One-command install 🛟 Self-rollback updates ⓘ Help everywhere 🌍 EN + ES 🔒 Offline & private
curl … | sudo bash breaks → restores itself on every control panel, installer, CLI no cloud, no telemetry

📑 Contents

Highlights · At a glance · Monitor your business · Hardware · Installation · Updates · Demo · Languages · How it works · Docs · Roadmap · Contributing · Legal

✨ Highlights

📈 Spectrum analyzer

  • Live spectrum + waterfall, tinySA-style readouts
  • Tuner without touching the graph: −/+ steps, slider, jump to the next active signal
  • 4 markers with delta and peak tracking
  • Measurements: channel power, OBW, ACPR, −3/−6/−20/−26 dB bandwidth, SNR, counter, harmonics, pulses
  • Zero span with trigger, max/min hold, average, persistence, reference
  • Calibrated units (dBm, dBµV…), limit line with pass/fail
  • 24/7 monitor with occupancy map and phone alerts (ntfy)

📻 Radio

  • FM, wide FM, AM, WFM (broadcast), USB/LSB
  • Digital voice — DMR, P25, D-Star, Fusion, NXDN, dPMR, M17 (DSD-FME, optional)
  • Automatic recognition of digital signals by their shape (2/4-FSK, GMSK, AFSK, symbol rate)
  • CTCSS/DCS tone squelch detection and DTMF
  • Per-transmission recording with an activity log
  • ⏪ Instant replay — "what did they say?" plays the last 30 s again
  • Scanner over whole services, seek, memories
  • Fox-hunt mode to find a transmitter by ear

🔓 Decoders

  • Pagers POCSAG / FLEX, APRS with positions, EAS alerts (multimon-ng)
  • 433/868/915 MHz sensors: weather stations, tyre sensors, doorbells… (rtl_433)
  • Offline aircraft radar on 1090 MHz (dump1090)
  • Offline ship map (AIS, 162 MHz) with name, type, speed and distress beacons
  • Listen-only password for guests: they can look and listen, never change or delete
  • 40+ more modes in the advanced receiver (OpenWebRX+): FT8, WSPR, SSTV, HF fax, ACARS…
  • Every service's channel plan built in: PMR446, FRS/GMRS, marine VHF, airband, CB, ham bands…

🔭 At a glance

flowchart LR
  P["📱 Phone<br/>spectrum · waterfall<br/>audio · help"] <-->|"WiFi · hotspot · Tailscale"| Z["🥧 Raspberry Pi Zero 2 W<br/>SDR-Kit + OpenWebRX+"] <-->|"USB"| R["📡 RTL-SDR<br/>0.5–1766 MHz"]
Loading
You want to… Where Powered by
See what is on the air Analyzer tab built-in sweeps
Listen to a signal tap it → Radio built-in demodulators
Know what a signal is auto-recognition built-in classifier
Read pagers / APRS / EAS Decode tab multimon-ng
Read sensors (433/868/915 MHz) Decode tab rtl_433
Track aircraft offline Radar dump1090
Hear digital voice (DMR, P25, M17…) Radio → Digital DSD-FME (optional)
FT8, WSPR, SSTV, ACARS… Advanced receiver OpenWebRX+

🏪 Use case: keep an ear on your business from anywhere

Picture a restaurant, a hotel, a warehouse or a building site that runs on walkie-talkies (FRS/PMR, business VHF/UHF or ham radios). You travel abroad and want to know the day is going well. Leave SDR-Kit at the business and listen in from your phone, from any country.

flowchart LR
  W["📻 Your team's<br/>walkie-talkies"] -. radio .-> Z["🥧 SDR-Kit at the business<br/>on its WiFi"]
  Z <-->|"Tailscale<br/>(encrypted)"| P["📱 Your phone<br/>in another country"]
Loading

What you need

  • Internet at the business. Tailscale works over the internet, so the Pi has to be on the business WiFi (or a 4G router). The Pi's own hotspot is for the field and does not reach the internet, so it is not enough for this.
  • Fixed power: a USB charger instead of the power bank, so it runs 24/7.
  • Tailscale on both ends, signed in to the same account.

Set it up (once, before you travel)

  1. Connect the Pi to the business WiFi (More → WiFi).
  2. On the Pi run sudo tailscale up and open the link it prints to sign in (or set TAILSCALE_AUTHKEY before installing).
  3. Install the Tailscale app on your phone, sign in with the same account and turn it on.
  4. Open http://sdrpi (or the Pi's Tailscale IP from More → System → Access addresses). It's the same panel as at home.
  5. Save your team's channels as a memory group (More → Channels → ★ Save as group, or add them by hand) and start the scanner on that group.

What you can do from abroad

  • Listen live to your team's channels: the scanner stops on whoever is talking.
  • Turn on auto-record in the Radio (“Record every transmission automatically”): it keeps going with your phone closed, so you can play back what happened while you slept.
  • Check the activity log (time, channel, duration, tone) or download it as CSV.
  • See which tone/code each radio uses, to check nobody else is on your channel.
  • Or, instead of listening, use Analyzer → 24/7 monitor to get a phone alert (ntfy, set NTFY_TOPIC) when a signal shows up on your channels. The dongle does one thing at a time: either the radio or the 24/7 monitor.

Important

Only listen to your own channels, and tell your staff the radios are monitored and recorded. Recording conversations is regulated differently in each country. Encrypted digital radios can't be heard. Never port-forward the panel to the internet: use Tailscale, which encrypts the connection end to end.

🧰 Hardware

Part Recommended ≈ Price
🥧 Computer Raspberry Pi Zero 2 W US$15
📡 SDR RTL-SDR Blog V4 (kit with the adjustable dipole antennas) · the V3 works too US$40
💾 Storage 32 GB microSD, A1/A2 (SanDisk, Samsung) US$8
🔋 Power 10 000–20 000 mAh power bank (5 V / 2.4 A) + short, thick micro-USB cable US$20
🔌 Adapter Short micro-USB OTG → USB-A adapter (+ a short USB extension with ferrite) US$5

Runtime is about 6–10 h on a 10 000 mAh bank.

Note

Got an RTL-SDR Blog V3? It's supported: plug it in and the panel recognizes it by its R820T tuner. Everything from VHF up works the same as on the V4. Below 24 MHz (AM, shortwave, CB) it switches to direct sampling on its own, with less sensitivity than the V4's built-in upconverter. CI checks both dongles on every change — see hardware.

➕ Optional extras (HackRF, AMBE3000, discone, second dongle)
Extra What it adds
HackRF One Sweeps from 1 to 6000 MHz (experimental, auto-detected)
AMBE3000 USB stick Hardware vocoder for licensed digital voice via OpenWebRX+
Discone antenna Wideband reception for scanning
Second RTL-SDR Dedicated dongle for aircraft radar or sensors

Details and wiring: docs/hardware.md.

📦 Installation, step by step

⚡ The short version

# 1) Flash Raspberry Pi OS Lite 64-bit (hostname: sdrpi, WiFi 2.4 GHz, SSH on)
# 2) SSH into the Pi:
ssh <user>@sdrpi.local
# 3) Install (20–45 min, reboots by itself):
curl -fsSL https://raw.githubusercontent.com/romartak/sdrkit/main/get.sh | sudo bash
# 4) Open http://sdrpi.local on your phone

🗺️ The road map of the install

flowchart LR
  A["1️⃣ Flash<br/>Pi OS Lite 64-bit"] --> B["2️⃣ Boot & SSH<br/>sdrpi.local"]
  B --> C["3️⃣ One command<br/>get.sh"]
  C --> D["4️⃣ Answer 3 questions<br/>language · passwords"]
  D --> E["☕ Wait 20–45 min<br/>auto-reboot"]
  E --> F["5️⃣ Open the panel<br/>📱 phone"]
Loading

✅ Before you start

  • Hardware assembled (Hardware) — RTL-SDR on the Pi's data micro-USB port via the OTG adapter
  • A computer (or a phone SSH app such as Termius) and a microSD card reader
  • Your home WiFi (2.4 GHz) name and password — the Pi needs internet during install
  • About 45 minutes

1️⃣ Flash the microSD card

  1. Open Raspberry Pi Imager.

  2. Device: Raspberry Pi Zero 2 W · OS: Raspberry Pi OS Lite (64-bit) (Trixie recommended, Bookworm works).

  3. Click Edit settings and set:

    Setting Value
    Hostname sdrpi
    Username / password your choice (you will use them for SSH)
    WiFi your home network, 2.4 GHz, and your country
    Services ✅ Enable SSH
  4. Write the card, put it in the Pi and power it on. First boot takes ~2 minutes.

2️⃣ Connect over SSH

ssh <your-user>@sdrpi.local

Note

If sdrpi.local does not resolve (some Windows/Android setups), find the Pi's IP in your router and use that.

3️⃣ Run the installer

curl -fsSL https://raw.githubusercontent.com/romartak/sdrkit/main/get.sh | sudo bash

The installer asks only a few things:

Question Notes
🌍 Language English or Spanish (installer and sdrkit command)
📶 Hotspot password For the WiFi the Pi creates (SDR-Pi) — at least 8 characters, no "
🔑 Panel password For the web panel and OpenWebRX+ — at least 4 characters, no "
🎙️ Digital voice (DSD-FME)? Default no — it shows the codec patent notice first

Then it installs everything and reboots on its own. Don't unplug it.

🔍 What the 11 installer steps do
# Step What happens
1 Preparing the system Swap to 1 GB, WiFi country, apt update
2 Base packages Python, NumPy, rtl-sdr, avahi, git…
3 RTL-SDR driver Blacklists DVB-T modules; builds the Blog driver on Bookworm
4 OpenWebRX+ Adds its repository and the available decoders
5 Digital voice Only if accepted: builds mbelib + DSD-FME (30–50 min)
6 SDR-Kit panel Installs to /opt/sdrkit, the sdrkit command and services
7 WiFi hotspot Automatic hotspot + known networks + watchdog
8 Power & microSD care Bluetooth off, logs in RAM, fewer SD writes
9 Tailscale Optional remote access
10 Starting services Health check: panel answers, RTL-SDR on USB
11 Done Prints addresses, records the version, reboots in 15 s

Full detail: docs/installation.md.

📴 No internet on the Pi? Offline install from the microSD

You can copy the kit onto the card and install from there. See docs/installation.md.

4️⃣ Open the panel

Where you are How to connect Address
🏠 At home Phone and Pi on the same WiFi http://sdrpi.local
🏕️ In the field Join the WiFi SDR-Pi http://192.168.4.1
🌐 Anywhere Tailscale on the Pi and the phone http://sdrpi

Tip: use your browser's Add to Home screen to install it like an app.

🩺 If something goes wrong

sdrkit doctor                  # full check-up: ✔/✖ and what to do about each failure
sudo sdrkit backup             # save your settings and memories (restore with: sudo sdrkit restore FILE)
The panel doesn't open
  1. Wait 2 minutes after the reboot.
  2. Try the IP address instead of sdrpi.local.
  3. In the field, make sure you joined SDR-Pi, not your home WiFi.
  4. Re-run the installer safely: sudo bash /opt/sdrkit-src/install.sh.

More: docs/troubleshooting.md.

The dongle is not detected

Check the OTG adapter and cable (use a short, thick one), then run lsusb — you should see 0bda:2838 or 0bda:2832. A weak power bank is the usual culprit.

🗺 Roadmap, rating and sharing

The panel shows where the project is heading (More → System → About SDR-Kit → Roadmap, also in the welcome tour): one new feature a day, from instant replay and aircraft alerts to a long-term unified server where anyone could connect their Pi and listen to Pis all over the world — always optional, off by default, and your choice what to share. You can rate the project (stars stay on your device), share it (WhatsApp, Telegram, X, Facebook, email, copy link) or leave a ⭐ on GitHub. The full plan is in ROADMAP.md.

🔄 Updates that cannot brick your kit

sudo sdrkit update            # shows what changed, asks, installs

…or tap More → System → Check for updates. Your settings, recordings and memories are never touched; new settings are merged in automatically. After installing, SDR-Kit checks that the panel answers — if it does not, it rolls back to the previous version by itself. sudo sdrkit rollback goes back by hand. Details: docs/updating.md.

The version you run is shown next to SDR-Kit at the top of the panel, with a dot: 🟢 up to date, 🟠 a new version is out, ⚪ not checked yet. The first time you open the panel it asks whether you want new-version notices: while the Pi is on your WiFi it checks GitHub when it connects and every 6 hours, and when there is a new version a notice pops up so you decide whether to install it. Nothing is installed without your confirmation and no data of yours is sent (only public repository information is read).

flowchart LR
  U["sudo sdrkit update"] --> S["Show changes"] --> I["Install"] --> H{"Panel<br/>answers?"}
  H -- "✅ yes" --> OK["New version"]
  H -- "❌ no" --> R["↩️ Automatic rollback"]
Loading

🧪 Try it without hardware

The demo mode simulates an RTL-SDR with real, decodable signals — POCSAG pagers, APRS packets, an M17 digital-voice call, DMR-like and NXDN-like 4FSK, FM broadcast — so you can explore every screen on a laptop:

git clone https://github.com/romartak/sdrkit.git && cd sdrkit
pip install numpy                                   # apt install multimon-ng to decode the demo pagers/APRS
python3 files/sdrkit_server.py --demo --port 8080   # → http://localhost:8080

🎬 See it in action

Recorded straight from the demo panel on a phone-sized screen:

Spectrum analyzer Radio Aircraft radar (ADS-B) Pager messages
Sweeping the FM band and jumping between stations with the tuner Listening to a channel with live signal level Offline aircraft radar updating POCSAG pager messages arriving
sweep 87.5–108.5 MHz, tap ⏭ to jump to the next station tune, see the signal and the detected mode, listen on the phone aircraft around you, no internet decoded live as they arrive

Regenerate them with tools/gifs.mjs + tools/make_gifs.py.

🌍 Two languages

The whole kit is bilingual: panel, help, frequency guide, antenna tools, installer and CLI. The panel follows your browser's language; switch any time with the EN / ES chip in the header or in More → System. Adding a language is a catalog file away — see docs/development.md.

🏗️ How it works

flowchart LR
  phone["📱 Phone browser<br/>panel · EN/ES"] <-- "HTTP + Server-Sent Events<br/>hotspot · home WiFi · Tailscale" --> server
  subgraph pi["Raspberry Pi Zero 2 W"]
    server["sdrkit_server.py<br/>web panel · API · sweeps"]
    radio["sdrkit_radio.py<br/>demodulators · tones · DTMF<br/>recorder · scanner"]
    decoders["sdrkit_decoders.py<br/>multimon-ng · DSD-FME<br/>rtl_433 · dump1090 · classifier"]
    owrx["OpenWebRX+<br/>(advanced receiver)"]
    server --> radio --> decoders
    server --> decoders
  end
  sdr["📡 RTL-SDR Blog V4"] -- USB --> server
  server -. hands the dongle over .-> owrx
Loading

A single Python process owns the dongle and switches it between the analyzer, the radio and the external decoders on demand; the browser draws the spectrum and waterfall from compact JSON frames pushed over Server-Sent Events and plays 16-bit PCM audio streamed over HTTP through Web Audio. No cloud, no accounts, no telemetry. Deep dive: docs/architecture.md · HTTP API: docs/api.md.

📚 Documentation

Hardware Bill of materials, power, assembly
Installation Flashing, one-line install, offline install, first connection
User guide Every tab and control
Digital voice DMR, P25, D-Star, Fusion, NXDN, dPMR, M17
Antennas Lengths per band, placement, cable loss
Updating Updates, rollback, test branches
Troubleshooting · FAQ Symptoms → causes → fixes
Architecture · API · Configuration For tinkerers
Development Demo mode, tests, translations, releases
Guía en español La guía completa en español

🗺️ Roadmap

📅 Daily feature plan: ROADMAP.md lists 31 new features, one shipped per day, plus the long-term vision (a unified server where everyone can share and listen to each other's Pis worldwide), with what's done and what's next.

  • HackRF One sweeps up to 6 GHz in the analyzer (detected automatically; needs more field testing)
  • Second-dongle profiles: aircraft radar or sensors 24/7 while using the analyzer
  • Weather-satellite images (Meteor-M, 137 MHz) on a Pi 4/5
  • Small OLED status display (IP address, mode, battery)
  • More languages — contributions welcome

🤝 Contributing

Bug reports, ideas, translations and pull requests are welcome — read CONTRIBUTING.md and the Code of Conduct. Every change runs through CI: unit tests for the DSP and decoders, an end-to-end decode of real POCSAG and APRS signals, translation checks and a browser test in both languages.

⚖️ Legal

Important

SDR-Kit is receive-only. Listening is legal in most countries, but disclosing or using the content of private communications may not be — know your local law. Encrypted traffic is never decrypted.

The optional digital-voice decoder (DSD-FME + mbelib) implements patented AMBE/IMBE vocoders, so the installer leaves it off unless you explicitly opt in. See docs/legal.md.

🙏 Acknowledgements

Built on the shoulders of OpenWebRX+, rtl-sdr and the RTL-SDR Blog drivers, rtl_433, dump1090, multimon-ng, DSD-FME, mbelib, codec2 and the M17 Project, and inspired by the wonderful tinySA. The curated list of related projects in docs/resources.md was put together with the help of RFSec-ToolKit by @cn0xroot (雪碧 / 0x0root).

📄 License

MIT © romartak and SDR-Kit contributors. Third-party programs installed by the kit keep their own licenses.

About

Pocket spectrum analyzer + multimode radio + signal decoder on a Raspberry Pi Zero 2 W and RTL-SDR, used from your phone's browser. Sweep 0.5–1766 MHz, tap a signal to hear it, identify digital modes, decode pagers, APRS, sensors and ADS-B, record, scan and watch 24/7. Offline, receive-only, EN/ES.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

11 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages