Mit 20-Euro-Hardware und freier Software-Defined-Radio-Software beginnt für Konstantin Agouros die Jagd auf die per Funk übertragenen Daten einer Wetterstation.
Wetterstationen mit Außensender (Abbildung 1) sind heute in vielen Haushalten im Einsatz – so auch in meinem. Der kleine Sender liegt in diesem Fall auf dem Fensterbrett, misst Wetterdaten wie Temperatur, Luftdruck oder Luftfeuchtigkeit und übermittelt diese digital an eine Basisstation, die sie dann anzeigt. Doch eine Basisstation zum Empfang der Daten ist nicht einmal unbedingt notwendig. Mit etwas Bastelleidenschaft und der Hilfe von Software Defined Radio (siehe Kasten “SDR”) kann ich solche Funkdaten auch mit dem Rechner empfangen, auslesen und sogar erzeugen.

Abbildung 1: Die Kommunikation zwischen einer handelsüblichen Wetterstation (links) und dem zugehörigen Sensor (rechts) lässt sich mit SDR auswerten.
SDR
Software Defined Radio greift die elektromagnetische Wellen quasi direkt an der Antenne ab und bearbeitet sie mit Hilfe von Software. Im einfachsten Fall besteht ein SDR-Empfänger aus einer Antenne und einem Analog-Digital-Wandler plus Software. Abhängig vom Gerät lässt sich damit ein recht großer Frequenzbereich scannen. Anwendungen, mit deren Hilfe sich SDR umsetzen lässt, heißen Gnu Radio, Gnu Radio Companion oder Gqrx.
Weil dabei die Software den Großteil der Arbeit erledigt, darf mein Lötkolben getrost im Schrank liegen bleiben. Lediglich die entsprechende Hardware, die nur ein paar Euro kostet, muss her sowie ein Editor, um die digitalisierten Funkdaten am Rechner zu verarbeiten.
Die Hardware
Vor der Analyse der digitalen Daten musste ich zunächst die passende Hardware für den Empfang finden. Während speziell dafür entwickelte Hardware recht kostspielig ist, bieten DVB-T-Sticks für rund 20 Euro eine sehr günstige Einstiegsmöglichkeit in SDR, sofern sie bestimmte Realtek-Chipsätze (RTL2832U) mitbringen. Das Ganze firmiert unter dem Stichwort “RTL-SDR” und benötigt die Bibliothek Librtlsdr.
Ein Blick auf meine Wetterstation zeigt, dass sie Daten auf der 868-MHz-Frequenz empfängt. Die Webseiten unter [1] und [2] listen diverse Chipsätze sowie die von ihnen abgedeckten Frequenzbereiche auf. Hier findet sich auch gleich eine Liste von Produkten, die diese Chips enthalten. Auf Empfehlung eines Kollegen erwarb ich einen Terratec Cinergy T Stick RC mit Elonics-Chipsatz, der von den aufgelisteten DVB-T-Empfängern den größten Frequenzbereich abdeckt – so auch den des Wettersensors. Der Kostenpunkt der Hardware liegt bei 23 Euro, praktischerweise ist im Lieferumfang eine Stabantenne enthalten.
Die Software
Als Installationsbasis diente mir ein Netbook mit Mint 15, bei der Analyse der per Funk empfangenen Signale half das Gnu-Radio-Framework [3]. Das ist eine Art Baukasten, der sogar einen grafischen Editor enthält und die Signalverarbeitung von Rohdaten (gegebenenfalls auch in Echtzeit) mit Hilfe diverser Filter bis hin zu einem Zielformat ermöglicht. Die Software erzeugt dabei automatisch Python-Code, der die Daten verarbeitet.
Um den DVB-T-Stick als Empfänger einzusetzen, benötige ich zunächst das RTL-SDR-Paket, das
git clone git://git.osmocom.org/rtl-sdr.git
auf den Rechner holt. Gentoo und Arch Linux bringen bereits fertige Pakete mit, unter Ubuntu lässt sich die Software über ein PPA installieren (siehe Kasten “Gnu Radio aus dem PPA”).
Gnu Radio aus dem PPA
Vor dem Anstecken der Hardware muss der Ubuntu-Nutzer eine Udev-Datei anlegen. Dazu liest er per »lsusb« die Vendor- und die Product-ID seines DVB-T-Sticks aus und setzt als Root den folgenden Befehl ab:
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="Vendor ID", ATTRS{idProduct}=="Product ID", GROUP="adm", MODE="0666",SYMLINK+="rtl_sdr"' > /etc/udev/rules.d/20.rtlsdr.rules
Der Befehl schreibt eine neue Regel für Udev, die sich auf den DVB-T-Stick bezieht. Vor dem Anstecken des Sticks muss Root Udev zudem neu starten:
service udev restart
Die Debian-Pakete von Gnu Radio und Gqrx installieren Ubuntu-Nutzer aus einem PPA:
sudo add-apt-repository ppa:gqrx/snapshotssudo apt-get update sudo apt-get install gqrx gnuradio
Über den Aufruf von »gqrx« lässt sich das SDR-GUI anschließend starten.
Das Bauen der Software aus den Quellen funktioniert über Cmake, aber es gibt einen Haken: RTL-SDR verwendet die Bibliothek Libusb, um mit dem Stick zu kommunizieren. Werden jedoch bestimmte Treiber geladen, kann die Software nicht mehr korrekt mit dem Stick reden. Mein Mint-System hat die Module aus Listing 1 geladen. Listing 2 zeigt eine Anleitung von der Webseite [1] für das Bauen der Software aus den Quellen.
Listing 1
lsmod | head 7
01 e4000 12862 1 02 rtl2832 13312 1 03 dvb_usb_rtl28xxu 18737 0 04 rtl2830 13511 1 dvb_usb_rtl28xxu 05 dvb_usb_v2 22916 1 dvb_usb_rtl28xxu 06 dvb_core 90402 3 rtl2830,rtl2832,dvb_usb_v2 07 rc_core 21266 3 dvb_usb_rtl28xxu,dvb_usb_v2
Listing 2
rtl-sdr kompilieren
01 cd rtl-sdr/ 02 mkdir build 03 cd build 04 cmake ../ 05 make 06 sudo make install 07 sudo ldconfig
Test, Test!
Um das Laden der Module zu unterbinden, ist eine Modifikation der Udev-Regeln notwendig. Dazu musste ich den Cmake-Aufruf um den Parameter »-DINSTALL_UDEV_RULES=ON« erweitern und anschließend noch das Kommando
sudo make install-udev-rules
hinterherschicken. Nun ließen sich die Funktionen der Hardware über
rtl_test -t
auslesen, um etwa herauszufinden, welchen Frequenzbereich der DVB-T-Stick abdeckt. Ein handfester Test ist auch der Empfang eines örtlichen Radiosenders:
rtl_fm -f 98.5M -W -s 200000 -r 48000 - | aplay -r 48k -f S16_LE
Der Demodulator »rtl_fm« nimmt 200 000 Samples pro Sekunde auf der Frequenz 98,5 MHz (die Frequenz eines Radiosenders) auf. Aplay spielt den Datenstrom mit einer Rate von 48 kHz auf Stdout ab. Da die Roh-Audiodatei keine Header-Informationen enthält, liest Aplay die Daten mit dieser Rate ein und kodiert sie mit 16 Bit im Little-Endian-Format.
Die Analyse
Um interessante Signale im Äther zu finden, ist Zuhören angesagt. Das Kommando, das ich oben zum Radiohören verwendet habe, liefert auf anderen Frequenzen Rauschen, wenn auf ihnen nichts sendet. Digitale Signale hören sich anders an als Rauschen und geben so – unter Berücksichtigung der Rechtslage (siehe Kasten “Rechtslage um SDR”) – Futter für weitere Analysen.
Rechtslage um SDR
Christian Solmecke [4] ist Anwalt in der Kanzlei Wilde Beuger Solmecke und erklärt, was SDR-Nutzer beim Abhören der Frequenzen beachten sollten.
Linux-Magazin: Welche Gesetzestexte sollten SDR-Nutzer genauer in Augenschein nehmen?
Christian Solmecke: Die wichtigsten Regelungen finden sich im Telekommunikationsgesetz. Insbesondere die Paragrafen 89 und 148 sind hier entscheidend.
Linux-Magazin: Wie sieht es mit dem absichtlichen oder unabsichtlichen Empfang von unverschlüsselter Kommunikation zwischen Personen aus, zu denen etwa der Polizei- und Rettungsfunk, aber auch der Amateurfunk gehören?
Christian Solmecke: Der absichtliche Empfang unverschlüsselter Kommunikation ist nur in vier Konstellationen erlaubt. Das regelt Paragraf 89 des Telekommunikationsgesetzes “Abhörverbot, Geheimhaltungspflicht der Betreiber von Empfangsanlagen”.
1. Konstellation: Die Nachricht ist für den Funkbetreiber bestimmt: Nachrichten, die nur für den Empfänger bestimmt sind, darf auch nur dieser abhören – das ist zum Beispiel der Fall bei Handys oder privaten WLAN-Netzen.
2. Konstellation: Der Empfang ist für die Allgemeinheit bestimmt (TV, Radio).
3. Konstellation: Der Empfang ist für Funkamateure bestimmt.
4. Konstellation: Der Empfang ist für einen unbestimmten Personenkreis bestimmt, was der Fall ist bei Wetterinformationen für die See- und Luftfahrt.
Außerhalb dieser vier Konstellationen bleibt der Empfang der Funkkommunikation verboten. Das Abhören des Polizei- und Rettungsfunks ist somit nicht erlaubt. Für den unabsichtlichen Empfang der Funkkommunikation gilt nichts anderes: Wer aus Versehen auf eine der Frequenzen des Polizeifunks kommt und diese nach dem Erkennen weiterhört oder das dort Gehörte verbreitet, macht sich genauso strafbar, wie derjenige, der mit Absicht diese Frequenzen abgehört hat. Die Strafbarkeit ist in Paragraf 148 des TKG geregelt, bis zu zwei Jahren Freiheitsstrafe sind möglich.
Linux-Magazin: Darf man, wie es einige Webseiten tun, die unverschlüsselten Positionssignale von Flugzeugen (ADS-B) oder Schiffen (AIS) empfangen und online grafisch aufbereiten?
Christian Solmecke: Bei der grafischen Aufbereitung der Daten kommt es auf die Darstellung im konkreten Fall an. Entscheidend ist, ob diese Daten eine Identifizierung ermöglichen. Dies kann datenschutzrechtlich problematisch sein – etwa bei Privatflugzeugen. Bei der Veröffentlichung personenbezogener Daten kann zudem eine Persönlichkeitsrechtsverletzung vorliegen.
Um größere Frequenzbereiche abzusuchen, bietet sich Software wie Gqrx [5] an, ein praktisches Frontend, das die Daten in Kurven und einer Wasserfallgrafik optisch aufbereitet (Abbildung 2).
Das Wetter
Da auf meiner Wetterstation glücklicherweise die richtige Frequenz aufgedruckt ist, ließ sich eine Suche vermeiden. Als ich die Frequenz auf 868 MHz einstellte, ertönten alle paar Sekunden Knackgeräusche, die ich aufzeichnete und mit dem Audio-Editor Audacity analysierte. Nach dem Import der Daten ergab sich im Test das Bild aus Abbildung 3.

Abbildung 4
.” width=”300″ height=”105″ /> Abbildung 3: Beim Hineinzoomen in die Daten mit Audacity in eine der Spitzen ergibt sich Abbildung 4.Tatsächlich ließ die vergrößerte Ansicht ein Muster erkennen. Jetzt musste ich dieses Signal dekodieren, um die Daten (Temperatur und Luftfeuchtigkeit) auszulesen. Eine Internetrecherche zeigte, dass sich jemand diese Arbeit bereits gemacht hat. Unter [6] und [7] finden sich Analysen der Wettersensoren.
Christophe Jacquets Pydemod-Paket geht von einer 16-Bit-Präambel aus, bestehend aus 1010101010101010. Ihr folgend sendet sein Sensor wie der in [8] mit 17200 Baud ein Signal, das On-off-Keying verwendet: Verläuft die Kurve von Abbildung 5 nach oben, wird eine 1 übertragen, fällt sie nach unten, eine 0. Ob sie nach oben läuft, lässt sich über das Verhältnis der numerischen Werte der Samples zur Baudrate herausfinden.
Aber die ersten Tests, die Daten aus »rtl_fm« mit Hilfe von »decode_tfa.py« [9] auszuwerten, blieben ergebnislos. Leider fehlte in den Aufzeichnungen von Christophe eine Angabe darüber, wie er »rtl_fm« aufgerufen hat, um die Rohdaten für die Analyse zu bekommen. Auch der Screenshot der empfangenen Daten sah in seinem Blog ganz anders aus als bei mir.
Glücklicherweise half Christophe und erweiterte sein Skript so, dass es auch mit den Daten des Wettersensors arbeitet. Wie sich zeigte, bestanden die Probleme in den folgenden Punkten:
- Meine Samples waren mit der falschen Modulationsmethode entstanden. Der Sender moduliert mit der Amplitude, nicht mit der Frequenz. Daher muss »rtl_fm« den Parameter »-M« mit auf den Weg bekommen.
- Mein Sender schickte die Daten mit 9600 statt mit 17200 Baud.
- Die Datenpräambel lautete zudem nicht 1010101010101010, sondern 101010101010101010101010, es waren also tatsächlich 24 statt 16 Bit.
Es gab noch einen weiteren Unterschied zwischen meinem Testsystem und den Daten von Christophe: Sein Radio-Empfangssystem, ein Funcube-Dongle, lieferte die Daten im Big-Endian-Format, der im Test eingesetzte DVB-T-Stick verwendete hingegen das Little-Endian-Format. Dies musste Christophe im Code an der Stelle anpassen, welche die Rohformat-Samples in Zahlen zum Weiterverarbeiten verwandelt.
Die Kodierung der Temperatur blieb in beiden Szenarien identisch. Drei Nibbles (4 Bit), die eine Stelle der Temperatur in BCD (Binary Coded Decimal) kodierten, wobei die dritte Stelle die Zehntel-Grad anzeigt. Darauf addiert mein Temperatursensor 40, vermutlich um Minusgrade abzubilden. Die nächsten 8 Bit kodieren dann die Luftfeuchtigkeit.
Die erste Version des Skripts ging außerdem davon aus, dass sie eine WAV-Datei vorgesetzt bekommt, die genau die Bits mit den Informationen und keinerlei Rauschen enthält. Das nun von Christophe maßgeblich überarbeitete und auf andere Fälle erweiterte Skript bringt einige neue Eigenschaften mit, die unter anderem Folgendes ermöglichen:
- Es erkennt die Spitze der Daten daran, dass der numerische Wert des Sample einen Grenzwert überschreitet. Der liegt bei 4000, lässt sich aber – je nach Sendeleistung – ändern.
- Die Daten können auch im Rohmodus vorliegen, also ohne WAV-Header, aber im Moment muss dies mit einer Rate von 160 000 pro Sekunde geschehen.
- Die Länge der Präambel regelt ein eigener Parameter.
- Die Baudrate der Datenübertragung lässt sich variabel einstellen.
Daher erzeugt nun folgender Aufruf einen Strom von Temperaturmessungen:
rtl_fm -M -f 868.4M -s 160k - | python decode_tfa.py --raw - --bitrate 9600 --synclen 24
Die Ausgabe des Befehls zeigt Listing 3. Ab und zu sind die Messdaten fehlerhaft. Dies lässt sich an zwei Dingen erkennen: Zum einen ist eine Checksumme enthalten, deren erwarteter und ermittelter Wert ausgegeben wird. Weichen diese voneinander ab, liegt ein Messfehler vor. Auch sind extreme Temperatursprünge eigentlich unmöglich, dennoch weichen zwei Messungen um mehr als 1 Grad Celsius voneinander ab.
Listing 3
Ausgabe von rtl_fm
01 Found 1 device(s): 02 0: Realtek, RTL2838UHIDIR, SN: 00000001 03 04 Using device 0: Terratec Cinergy T Stick RC (Rev.3) 05 Found Elonics E4000 tuner 06 Bitrate: 9600, synclen: 24, framelen: 80 07 Using frame duration 1600.0 samples 08 Squelch at 2200, should be slightly greater than usual max; use --squelch to change 09 Oversampling input by: 7x. 10 Oversampling output by: 1x. 11 Buffer size: 7.31ms 12 Tuned to 868679999 Hz. 13 Sampling at 1120000 Hz. 14 Output at 160000 Hz. 15 Exact sample rate is: 1120000.035604 Hz 16 Tuner gain set to automatic. 17 Min: 0 - Mean: 273.97845 - Max: 1224 18 --------------------------------------- 19 Frame: size 98 bits, contents 10101010101010101010101000111101110101000000000000000000000000000000000000000000000000000000000000, framelen=80 20 Frame hex contents: AA AA AA 3D D4 00 00 00 00 00 21 CRC: calculated=00, received=00 22 Temperature: -40.0 C -- Humidity: 0 % 23 --------------------------------------- 24 Min: 0 - Mean: 270.3753 - Max: 1260 25 --------------------------------------- 26 Frame: size 96 bits, contents 101010101010101010101010001011011101010010010001110001000110001001001001011001010000000000000000, framelen=80 27 Frame hex contents: AA AA AA 2D D4 91 C4 62 49 65 28 CRC: calculated=65, received=65 29 Temperature: 6.2 C -- Humidity: 73 % 30 ---------------------------------------
In der Praxis zeigte sich, dass die Antenne nicht zu weit vom Empfänger entfernt sein sollte. Schon bei 5 Metern Entfernung sank bei mir der Wert der Spitze deutlich ab. Liegt der Wert zu nahe am Rauschen, kann das Skript den Anfang der Daten nicht mehr erkennen.
Das Python-Skript gibt während des Durchlaufs Minimal-, Maximal- und Durchschnittswerte aus. Im Praxistest kam es jedoch immer wieder vor, dass der Ausschlag des Sticks zu schwach war. Das kann an der automatischen Verstärkung des Signals liegen. Entweder nagelt der SDR-Nutzer den Wert mit dem Parameter »-g Wert« fest oder zieht den Stick und steckt ihn erneut an der Rechner.
Eitel Sonnenschein
Mit wenig finanziellem Aufwand und am Ende auch sehr wenig Software lässt sich die Aufgabe lösen, die Daten der Wetterstation auszulesen und in eine digital auswertbare Form zu bekommen. Die Basisstation des Testgeräts empfängt auch Daten mit Wetter- sowie Pollenflug-Vorhersagen. Diese kommen nicht vom Außensensor, sondern über das alte Pager-Netz. Auch dessen Daten lassen sich empfangen und mit dem Tool »multimode-ng« dekodieren. Die Pager-Daten gehen im Klartext über den Äther, aber die Kodierung im String ist noch undokumentiert. Ein großes Dankeschön geht an Christophe Jacquet für die Anpassungen seines Skripts, die Echtzeit-Streaming ermöglichten.
Infos
- RTL-SDR-Projekt: http://sdr.osmocom.org/trac/wiki/rtl-sdr
- Reddit-Thread mit SDR-Hardware-Empfehlungen: http://www.reddit.com/r/RTLSDR/comments/s6ddo/rtlsdr_compatibility_list_v2_work_in_progress/
- Gnu Radio: http://gnuradio.org
- RA Christian Solmecke: http://www.wbs-law.de/anwalt/christian-solmecke/
- Gqrx-GUI zur Spektrumanalyse: http://sourceforge.net/projects/gqrx/
- Blog von Christophe Jacquet mit der Protokollanalyse (französisch): http://www.jacquet80.eu/blog/post/2011/10/Decodage-capteur-thermo-hygro-TFA
- Erste Analyse des Protokolls von Fred Bossard: http://fredboboss.free.fr/tx29/
- Pydemod-Paket: http://code.google.com/p/pydemod/
- Code von »decode_tfa.py« : http://code.google.com/p/pydemod/source/browse/trunk/src/decode_tfa.py









