SNR (signaal-ruisverhouding): hoe ver je signaal boven de ruisvloer uitsteekt β dΓ‘t bepaalt of je kunt decoderen
ποΈ Speel: signaal vs. ruis
SNR25 dB
Schuif de signaalsterkte omlaag en zie wanneer decoderen onmogelijk wordt. Elke modulatie heeft een eigen minimum-SNR β daarom hoor je FM nog prima waar digitale TV al lang is weggevallen.
WiFi/5G gebruiken adaptief t/m 1024-QAM β alleen bij hoge SNR
In GQRX/SDR++ of GNU Radio zie je deze plots live van echte signalen
ποΈ Draai aan de ruis
SNR18 dB
QPSK live: elk puntje is een ontvangen symbool. Wordt een punt rood, dan belandde hij in het verkeerde kwadrant = bitfout. DΓt is waarom je modem terugschakelt bij slecht signaal.
Nyquist & samplerate gevorderd
Nyquist: om een signaal te reconstrueren moet je β₯ 2Γ de hoogste frequentie samplen
Met complexe IQ-samples: bandbreedte = samplerate
RTL-SDR @ 2.4 MS/s β 2.4 MHz spectrum in beeld
HackRF @ 20 MS/s β 20 MHz spectrum
Te weinig samplerate β aliasing: signalen "vouwen" terug en verschijnen op de verkeerde plek
Praktijk: 8-bit samples @ 2.4 MS/s = ~4.8 MB/s aan data. IQ-opnames worden snel groot!
Blauw = het echte signaal (10 cycli) Β· stippen = jouw samples Β· oranje = wat jouw SDR ervan reconstrueert. Zak onder 2Γ de signaalfrequentie en er verschijnt een spook-signaal op de verkeerde frequentie.
β Even checken #2
Je RTL-SDR staat afgestemd op 100 MHz met samplerate 2.4 MS/s.
Welk stuk spectrum zie je in je waterfall? 98.8 β 101.2 MHz (bandbreedte = samplerate)
Er zendt iets op 101.5 MHz. Zie je dat? Nee β valt buiten de band. Hertunen dus!
Een uur IQ opnemen kost ~17 GB (4.8 MB/s Γ 3600 s) β daarom neem je kort en gericht op
π¬ Lab 2 β Voorspel het spook
Opdracht (Β±10 min): word aliasing-meester met de demo van zonet (2 slides terug).
β οΈ Zenden zonder vergunning is in NL illegaal β ook heel kort, ook op laag vermogen. Gebruik een dummy load of kabel voor experimenten. Meer hierover bij wetgeving.
Antennes: de helft van je succes
Een slechte antenne met dure SDR < goede antenne met goedkope SDR
Vuistregel: antenne resoneert bij Ξ»/4 of Ξ»/2 van je doelfrequentie
Je ziet signalen voordat je ze hoort: elke modulatie heeft een eigen "vingerafdruk"
β² live gesimuleerde waterfall: smalle FM-draaggolf Β· breedband FM Β· pager-bursts Β· frequency hopper
Een echte 2.4 MHz opname
Gegenereerd uit IQ-samples met NumPy β exact dezelfde FFT-pipeline als SDR++ gebruikt.
Hoe klinkt het spectrum? π§
Elke modulatie heeft ook een eigen geluid β na een tijdje herken je ze op het gehoor (allemaal hier gesynthetiseerd met NumPy):
π‘ Morse (CW) β "CQ CQ DE PA0SDR K", 600 Hz
π POCSAG pager-bursts β FSK, let op de preamble
π°οΈ NOAA APT β het "tik-tok" van een weersatelliet
π» FM afstemmen β ruis β zender β ruis
Meer echte voorbeelden: sigidwiki.com heeft opnames van honderden signaalsoorten.
ποΈ Draai zelf aan de knop
88.0 MHz
Sleep de schuif over de band: vind de morse-baken, de FM-muziekzender en de pager. Net naast de zender? Dan hoor je hem vervormd door de ruis β precies zoals in het echt.
Het tool-landschap
Tool
Platform
Waarvoor
SDR++
Win/Linux/Mac
Moderne allround ontvanger, plugins
SDRSharp (SDR#)
Windows
Klassieker, veel plugins
GQRX
Linux/Mac
Eenvoudige ontvanger op GNU Radio-basis
GNU Radio
alle
Visueel DSP-bouwpakket β zie volgende slides
SigDigger / inspectrum
Linux
Signaalinspectie & reverse engineering
Universal Radio Hacker
alle
Protocol reverse engineering (GUI)
rtl_433
alle (CLI)
200+ sensoren/weerstations decoderen
dump1090 / readsb
alle (CLI)
ADS-B vliegtuigtracking
SatDump
alle
Weersatellieten (NOAA, Meteor, GOESβ¦)
multimon-ng
alle (CLI)
POCSAG, AFSK, DTMF, β¦
GNU Radio: DSP als blokkendoos
Open-source framework: bouw je radio als flowgraph van blokken
GNU Radio Companion (GRC): visuele editor β genereert Python
Elk blok bewerkt een stroom samples: filter, mixer, demodulator, decoderβ¦
GNU Radio in de praktijk gevorderd
GRC genereert Python β je kunt alles ook scripten:
Links: vliegtuigen die jouw antenne hoort (ring = 100/200 km). Rechts: de ruwe Mode-S berichten zoals dump1090 ze decodeert β elk vliegtuig zendt er ~2 per seconde.
POCSAG: pagers leven nog π
Pager-protocol uit 1982, nog volop in gebruik (ziekenhuizen, brandweer)
In NL: P2000 op 169.65 MHz β alarmeringen van hulpdiensten (FLEX-protocol)
FSK, 512/1200/2400 baud β triviaal te decoderen:
# POCSAG decoderen met rtl_fm + multimon-ng
rtl_fm -f 169.65M -s 22050 | \
multimon-ng -t raw -a POCSAG512 -a POCSAG1200 -a FLEX -
Polaire baan: 2β4 passes per dag, Β±12 min zichtbaar
Workflow
Pass voorspellen (gpredict, n2yo.com)
V-dipool of QFH-antenne richting hemel
Opnemen + decoderen met SatDump
β eigen satellietfoto van Europa!
π Gevorderd: GOES/EUMETSAT geostationair met schotel + LNA, ISS SSTV-events, amateursatellieten (FM-repeaters in de ruimte).
Hoe werkt zo'n pass? π°οΈ
De satelliet vliegt in ~100 minuten rond de aarde; jij hoort hem alleen als hij boven jouw horizon komt (groene boog). De elevatiecurve rechts bepaalt je plan: hoe hoger de piek, hoe beter het beeld.
Echt ontvangen: NOAA 19 π°οΈ
NOAA 19, 18 juni 2021, APT op 137.100 MHz β public domain (NOAA), via Wikimedia Commons
Links: zichtbaar licht, rechts: infrarood
De verticale streeppatronen = sync-pulsen, zo lijnt de decoder elke beeldlijn uit
Dit ontvang je al met een RTL-SDR + zelfgebouwde V-dipool van ~β¬5 aan draad
Decodeer: schrijf een parser, of check of rtl_433 het al kent
π‘ Veel 433 MHz-apparaten gebruiken simpele OOK + vaste codes β daarom zijn replay-attacks op oude autosleutels mogelijk (en daarom hebben moderne rolling codes).
β Even checken #3 β jij bent de detective
In je waterfall op 433.92 MHz zie je elke ~30 seconden een korte, smalle burst. Wat is het β en hoe kom je erachter?
Korte periodieke bursts in de ISM-band β vrijwel zeker een sensor (weerstation, deurbel, TPMSβ¦)
SigMF: standaard om IQ-opnames + metadata (freq, rate, tijd) te delen
Scheiding opname β analyse: je kunt een signaal eindeloos opnieuw bekijken
IQ-data in Python gevorderd
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
fs = 2.4e6 # samplerate
raw = np.fromfile("opname.cs8", dtype=np.int8) # RTL-SDR: 8-bit
iq = (raw[0::2] + 1j*raw[1::2]) / 127.5 - (1+1j) # -> complex
# Spectrogram (waterfall)
f, t, Sxx = signal.spectrogram(iq, fs=fs, nperseg=4096,
return_onesided=False)
plt.pcolormesh(np.fft.fftshift(f), t,
10*np.log10(np.fft.fftshift(Sxx, axes=1)).T)
plt.xlabel("Frequentie-offset (Hz)"); plt.ylabel("Tijd (s)")
# FM-demodulatie in 1 regel: fase-verschil tussen samples
audio = np.angle(iq[1:] * np.conj(iq[:-1]))
NumPy + SciPy = je eigen SDR-lab. Aanrader: PySDR (pysdr.org), gratis online boek.
Van IQ naar audio β in beeld
Die ene regel np.angle(iq[1:] * conj(iq[:-1])) doet dit:
Berichten-data analyseren
Decoders leveren gestructureerde data (JSON) β klassieke data-analyse:
import pandas as pd
df = pd.read_json("adsb_log.jsonl", lines=True)
df["hour"] = df.time.dt.hour
df.groupby("hour").flight.nunique().plot(kind="bar") # drukte per uur
# verste ontvangst per richting -> antennediagram van je eigen setup
df.groupby(df.bearing.round(-1)).distance_km.max().plot(kind="polar")
Leuke vragen voor ADS-B:
Hoe ver reikt mijn antenne, en waarom niet rond?
Effect van weer/seizoen op bereik?
Voor rtl_433-sensoren:
Temperatuurtrends van de buurt
Hoe vaak zendt elk apparaat? Batterijstatus?
β¦en dit komt eruit π
Je antennebereik-plot verraadt precies welk gebouw in de weg staat β en de buurt-sensoren loggen 24/7 gratis mee.
Dashboards & langetermijn-monitoring
Raspberry Pi + RTL-SDR = 24/7 ontvangststation (< 5 W)
SatNOGS β open netwerk van satellietgrondstations
WebSDR / KiwiSDR β jouw ontvanger online delen
Van hobby naar citizen science: jouw antenne wordt onderdeel van een wereldwijd meetnetwerk.
Breedband discone + weerstation op het dak β mr_t_77, CC BY-SA 2.0, Wikimedia Commons
Machine learning op RF gevorderd
Automatische modulatieherkenning: CNN's op IQ-data of spectrogrammen (RadioML-datasets)
RF fingerprinting: zenders herkennen aan minieme hardware-imperfecties
Anomaliedetectie: afwijkende signalen in het spectrum spotten (spectrum monitoring)
Spectrogram = plaatje β alle computer vision-technieken zijn toepasbaar
Tooling: GNU Radio + PyTorch, torchsig, DeepSig datasets
Onderzoeksveld in opkomst β laagdrempelig om zelf mee te experimenteren omdat je je eigen trainingsdata kunt opnemen.
π¬ Lab 6 β Van JSON naar inzicht
Opdracht (Β±20 min): analyseer sensorlogs met pandas. Geen eigen data? De cursus-repo bevat een oefenset: assets/sample_rtl433.jsonl (24 uur, 3 sensoren).
import pandas as pd
df = pd.read_json("assets/sample_rtl433.jsonl", lines=True)
# 1. hoeveel berichten per sensor?
print(df.model.value_counts())
# 2. temperatuurverloop per sensor
df.pivot_table(index="time", columns="model",
values="temperature_C").plot()
# 3. jouw beurt: wanneer was de koudste 5-minuten? welke sensor
# hangt binnen? en wie heeft een zwakke batterij?
β Klaar als je plot 3 lijnen toont en je vraag 3 kunt beantwoorden met code.
Les 7
Wetgeving in Nederland βοΈ
β± 15 minπ niets β wel je geweten
π― Na deze les: je weet wat mag, wat niet, en hoe je legaal gaat zenden (N-licentie).