A single-pass, multi-band, explainable RF detector built on Software-Defined Radio.
English · Türkçe
SpectraSentinel is a receive-only cognitive spectrum sensor. It scans the RF environment across several bands, detects and classifies emissions (Bluetooth / BLE, Wi-Fi, ZigBee, LoRa, LTE, radar), and produces a stable, explainable device fingerprint for each emitter — all in a single clean pass, with fully reproducible, machine-readable logs.
🛡️ Passive by design. There is no transmission, jamming, or active interference anywhere in this system. SpectraSentinel only listens.
- Why SpectraSentinel
- Key Features
- Monitored Bands
- System Architecture
- Signal Processing Pipeline
- Specific Emitter Identification (SEI)
- Repository Layout
- Installation
- Usage
- Output & Log Schema
- Hardware
- Roadmap
- Legal & Ethical Notice
- Author
Most RF scanners answer only "is something there?". SpectraSentinel goes three steps further:
| Question | Classic scanner | SpectraSentinel |
|---|---|---|
| Is energy present? | ✅ | ✅ |
| What protocol is it? | ✅ BT/BLE, Wi-Fi, ZigBee, LoRa, LTE, radar | |
| Which specific device is it? | ❌ | ✅ deterministic RF fingerprint (SEI) |
| Why did it decide that? | ❌ | ✅ explainable reason / debug fields |
| Can I reproduce the run? | ❌ | ✅ config snapshot + schema version in every log |
The result is a detector that is cognitive (adapts its gain and noise model per band), explainable (every decision carries evidence), and scientific (every run is reproducible and auditable).
- Welch PSD estimation with CA-CFAR (Cell-Averaging Constant False Alarm Rate) detection
- Per-band adaptive noise-floor tracking — EMA and a Kalman noise estimator working together
- Spectral entropy and kurtosis features; Spectral Kurtosis (SK) curve for GUI vector plots
- Optional matched-filter detection (custom
.npytemplate or a synthetic BPSK preamble) - Adaptive IIR smoothing feedback (tightens when a target is present)
- HackRF-side AGC loop — band-profile-aware, adaptive baseband gain
- Light Bayesian fusion — per-band vote/score decision fusion
- Cyclostationary feature extractor — SCF-style summary metrics
- Cumulant engine — 2nd/3rd/4th-order moment & cumulant summaries
- Time–frequency ridge — STFT density / ridge metrics
- Hilbert–HHT fingerprint — IMF energy profile, instantaneous-frequency clusters, compressed Hilbert Spectrum Signature (HSS)
- Subspace SEI metrics — CSR (Cyclo-Subspace Rank), CEE (Covariance Eigen-Entropy), CNES (CFO-Normalized Eigen Spread)
- Haar + SDAE embedding — multi-scale wavelet features passed through a Stacked Denoising Autoencoder (graceful PCA / random-projection fallback if no trained model)
- Hybrid clustering — HDBSCAN + OPTICS device grouping with small-sample safety guards
- Single-pass, clean-exit design (no runaway infinite loops)
- Reproducible experiments — config version + hash + snapshot stamped into every record
- Explainable output — human-readable
reason/debugfields per detection - Hardware-free PC mode — automatic fake-GPIO fallback so the full pipeline runs on a laptop without a Raspberry Pi
- Structured JSONL logs — global + per-band, append-mode, one detection per line
| Label | Center | Coverage | Primary targets | Technique highlights |
|---|---|---|---|---|
EU868 |
868.3 MHz | 20 MHz | LoRa / EU ISM | PSD + CFAR + cyclo/cumulant |
915MHz |
915 MHz | 20 MHz | ISM 915 / LoRa | PSD + CFAR + cyclo/cumulant |
Bluetooth |
2446 MHz | 2.4 GHz ISM | BT Classic (FHSS), BLE, Wi-Fi, ZigBee | 5×1 s sub-centers, hop evidence, grid-fit |
BAND4 |
2650 MHz | 2570–2690 MHz | LTE 2.6 GHz presence | plateau + entropy + SK + CFAR (conf ≥ 0.83) |
BAND5 |
5400 MHz | 5 GHz | Wi-Fi ↔ Radar discrimination | PAPR, flatness, CP-corr, duty cycle, CFAR |
Bands are fully configurable via a JSON file (
--config). The table above lists the shipped defaults.
flowchart LR
A["📡 HackRF One<br/>(RX only)"] --> B["SP8T RF Switch<br/>antenna routing"]
B --> C["GNU Radio flowgraph<br/>IQ capture + IIR/Welch"]
C --> D["Core DSP<br/>PSD · CA-CFAR · entropy · kurtosis · SK"]
D --> E["Cognitive Layer<br/>AGC · Kalman/EMA noise · cyclo · cumulants · Bayesian fusion"]
E --> F["Burst Extraction<br/>segment candidate emissions"]
F --> G["SEI / Fingerprint<br/>Hilbert-HHT · Subspace · Haar+SDAE"]
G --> H["Clustering<br/>HDBSCAN + OPTICS → device IDs"]
H --> I["Explainable Decision<br/>proto_class · final_class · reason"]
I --> J["📝 JSONL logs<br/>global + per-band"]
I --> K["🖥️ Optional Qt GUI<br/>spectrum + SK plots"]
The SP8T RF switch is driven over Raspberry Pi GPIO to route the correct antenna per band; on a PC the driver transparently falls back to a fake-GPIO stub so nothing hardware-specific blocks the pipeline.
flowchart TD
IQ["IQ samples @ 20 MSa/s"] --> PSD["Welch PSD"]
PSD --> NF["Adaptive noise floor<br/>EMA + Kalman"]
NF --> CFAR["CA-CFAR detection"]
CFAR --> FEAT["Feature block<br/>entropy · kurtosis · SK · SCF · cumulants · TF-ridge"]
FEAT --> FUSE["Light Bayesian fusion<br/>(per-band votes/scores)"]
FUSE --> CLASS["Protocol classification<br/>BT/BLE · Wi-Fi · ZigBee · LoRa · LTE · Radar · Spy"]
CLASS --> BURST["Burst extraction"]
BURST --> SEI["SEI fingerprint"]
SEI --> ID["Stable device identity (hash)"]
Each stage contributes evidence, and the final class is a fused, explainable decision rather than a single threshold — which is what keeps the false-alarm rate low and the results auditable.
The differentiator of this project is not merely detecting a signal, but assigning it a stable identity so the same physical device is recognized again across time. Three complementary fingerprinting engines feed the clustering stage:
| Engine | Module | Produces | Scientific basis |
|---|---|---|---|
| Hilbert–HHT | hilbert_hht_engine.py |
IMF energy profile, IF cluster centers, HSS vector | Empirical Mode Decomposition / Hilbert spectrum |
| Advanced Subspace | subspace_engine_advanced.py |
CSR, CEE, CNES, effective rank | Covariance eigen-analysis |
| Haar + SDAE | rff_haar_sdae_engine.py |
Noise-robust low-dimensional embedding | Mallat, Group Invariant Scattering (2012); Vincent et al., Stacked Denoising Autoencoders (JMLR 2010) |
Fingerprints are grouped by a hybrid HDBSCAN + OPTICS engine (cluster_engine_planC.py) that is safe for streaming, single-burst, and low-burst conditions, yielding per-band device counts and cluster summaries.
SpectraSentinel/
├── core/ ⭐ The SpectraSentinel application
│ ├── HEDEF.py Flagship scanner — Raspberry Pi GPIO (real hardware)
│ ├── HEDEF_fake.py Flagship scanner — PC / hardware-free (auto fake-GPIO)
│ ├── hilbert_hht_engine.py Hilbert–HHT fingerprint
│ ├── subspace_engine_advanced.py CSR / CEE / CNES subspace SEI
│ ├── rff_haar_sdae_engine.py Haar wavelet + SDAE embedding
│ ├── cluster_engine_planC.py Hybrid HDBSCAN + OPTICS clustering
│ ├── burst_engine_mit.py Burst detection / segmentation
│ ├── lowband.py Per-band burst clustering (DBSCAN device estimation)
│ ├── switch_controller.py SP8T RF switch — Raspberry Pi GPIO
│ ├── switch_controller_fake.py SP8T RF switch — PC fake-GPIO fallback
│ ├── SCOPE_2P4.md 2.4 GHz detection scope & acceptance criteria
│ └── logs/ Runtime JSONL output (per band + global)
├── research/ 🔬 Development lineage (experimental iterations)
│ ├── plan_C.py · plan_C_upgrade.py · plan_C_AI.py Plan-C SEI experiments
│ ├── boss_1.py · boss_prof.py · boss_prof_2.py Early GNU Radio flowgraphs
│ ├── detected_e.py · HEDEF_fake.py Standalone detection variants
│ └── README.md
├── samples/example_logs/ 📊 Example JSONL captures (inspect without hardware)
├── docs/ARCHITECTURE.md Deep-dive design document
├── assets/banner.svg
├── requirements.txt
└── LICENSE
On the layout:
core/is the working application — its strongest model,core/HEDEF_fake.py, is fully self-contained and runs on a PC (automatic fake-GPIO) or a Raspberry Pi. Theresearch/folder preserves the development lineage (boss_*GNU Radio flowgraphs,plan_C*SEI experiments, standalone variants) so the engineering evolution stays transparent and reproducible.
# Debian / Ubuntu
sudo apt update
sudo apt install -y gnuradio gr-osmosdr hackrf libhackrf-dev
hackrf_info # verify the HackRF is detectedgit clone https://github.com/<your-username>/SpectraSentinel.git
cd SpectraSentinel
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
gnuradio,osmosdrandRPi.GPIOare system / platform packages and are intentionally not pinned inrequirements.txt. See the comments inside that file. On a PC (no Raspberry Pi) the switch controller falls back to fake-GPIO automatically.
All entry points live in core/, next to the engine modules they import:
cd corePC / hardware-free mode (no Raspberry Pi — recommended first run):
python3 HEDEF_fake.py --logdir ./logsFlagship, full SEI on a Raspberry Pi (real RF switch over GPIO):
python3 HEDEF.py --config bands.json --logdir ./logs --samplerate 20e6 --fftsize 16384With the Qt GUI and the Spectral-Kurtosis vector plot:
python3 HEDEF_fake.py --gui --sk| Flag | Default | Description |
|---|---|---|
--config |
(built-in defaults) | JSON band configuration file |
--logdir |
./logs |
Output directory for JSONL logs |
--samplerate |
20e6 |
Sample rate in Hz |
--fftsize |
16384 |
FFT size |
--gui |
off | Enable the Qt spectrum GUI |
--sk |
off | Enable Spectral Kurtosis / cyclo curve plot (GUI only) |
[
{"label": "EU868", "center_freq_hz": 868300000, "bandwidth_hz": 20000000, "dwell_time_s": 7},
{"label": "Bluetooth", "center_freq_hz": 2446000000, "bandwidth_hz": 20000000, "dwell_time_s": 5}
]Every detection is written as one JSON object per line (JSONL), in both a global log and a per-band log. Per the project scope, each record is self-describing and reproducible:
Sample captures are included under samples/example_logs/ so the schema can be inspected without any hardware.
| Component | Role |
|---|---|
| HackRF One | Wideband (1 MHz–6 GHz) receive-only SDR front-end |
| SP8T RF switch | Selects the correct antenna per band |
| Raspberry Pi | Drives the switch over GPIO (8-channel A/B/C + EN decode) |
| Band antennas | Per-band matched antennas (868/915, 2.4 GHz, 2.6 GHz, 5 GHz) |
No Pi? The pipeline still runs end-to-end on a PC via the automatic fake-GPIO fallback.
- Merge
core/HEDEF.pyandcore/HEDEF_fake.pyinto a single--sim/--hwmode switch - Ship a pre-trained SDAE model for the Haar-embedding engine
- Offline IQ replay harness for deterministic regression tests (per SCOPE §6)
- Web dashboard for live device tracking
- Extend scope to full 5 GHz band optimization
SpectraSentinel is a passive, receive-only research and educational instrument for RF spectrum sensing and emitter identification. It performs no transmission, jamming, or active interference of any kind.
Radio reception and monitoring are regulated differently across jurisdictions. You are responsible for operating this software in compliance with your local laws and licensing requirements. Use it only on spectrum and equipment you are authorized to monitor. This project is provided for legitimate research, education, and spectrum-management purposes.
Remzi Altunay Electrical–Electronics Engineering · RF / SDR / Signal Processing
If this project is useful to you, a ⭐ on the repository is appreciated.
{ "timestamp_iso": "2025-11-28T13:48:46.139Z", "schema_version": 2, "config_version": "...", "config_hash": "...", // reproducibility "label": "Bluetooth", "center_freq_hz": 2446000000, "detection": true, "detected_peaks": [ { "type": "BLE", // proto_class "observed_freq_hz": 2419999511.7, "snr_db": 37.34, "estimated_bw_hz": 9765.6, "ble_grid_match": true, "scf_strength": 0.36, // cyclostationary evidence "votes_ble": 3.0, "votes_classic": 3.0, // Bayesian fusion votes "classification_confidence": 0.75 // explainable confidence // + fingerprint / SEI fields for device identity } ] }