Empfang von Wettersensordaten mit RTL-SDR

Martin Kompf

DVB-T USB-Stick mit RTL2832U Chip und Rafael Micro R820T tuner

Viele Wetterstationen für den Hobbyanwender enthalten einen Außensensor, der seine Daten per Funk zur Basisstation überträgt. Auf der anderen Seite ist es mittlerweile möglich, auf Basis bestimmter USB-Sticks für den DVB-T Empfang ein kostengünstiges Software Defined Radio (SDR) zu realisieren. Mit der richtigen Software und etwas Geduld gelingt damit auch der Empfang der Messwerte vom Wettersensor.

Software Defined Radio

Außen-Kombisensor KS 300 von ELV

Normalerweise ist die Speicherung und Auswertung der Wetterdaten auf dem PC nur dann möglich, wenn die Wetterstation eine entsprechende (USB-)Schnittstelle besitzt oder der Hersteller Speziallösungen wie den WDE-1 anbietet. Fehlt diese Möglichkeit, dann ist eine Alternative das Abgreifen der zwischen Außensensor und Basisstation übertragenen Funksignale. Dazu benötigt man einen Empfänger für die verwendete Frequenz. Diese liegt in der Regel in einem der beiden Kurzstreckenfunkbereiche bei 433 MHz oder 868 MHz.

So einen Funkempfänger kann man sich natürlich mit entsprechenden Elektronikkenntnissen selbst bauen. Eine einfachere (und mittlerweile sogar kostengünstigere) Alternative besteht in der Verwendung eines USB-Sticks für den DVB-T oder DAB Empfang, der den Realtek RTL2832U Chip enthält. Damit lässt sich auf einfache Art und Weise ein Software Defined Radio (SDR) realisieren. Der DVB-T Stick nimmt dabei nur den Empfang und die Digitalisierung der Funksignale vor. Die restliche Signalverarbeitung erfolgt in einer auf dem PC laufenden Software, wie GNU Radio, rtl-sdr oder gqrx. Weitere Informationen, insbesondere eine Liste unterstützter USB-Sticks, liefert das Projekt Osmocom rtl-sdr. Passende Sticks gibt es bei den einschlägigen Händlern bereits für unter 20 €. Entsprechende Angebote findet man dort am besten durch Suche nach RTL2832U.

Start mit gqrx

Für die ersten Gehversuche unter Linux eignen sich gqrx mit einer grafisches Benutzeroberfläche sowie die Kommandozeilentools aus dem Paket rtl-sdr. Sie stehen für Ubuntu als fertig kompilierte Pakete mit allen Abhängigkeiten zur Verfügung. Ab Ubuntu 14.04 LTS Trusty sind gqrx-sdr und rtl-sdr Bestandteil der Distribution; für ältere Versionen wie Precise muss man zunächst ein PPA zum System hinzufügen:

# Precise:
sudo add-apt-repository ppa:gqrx/releases
sudo apt-get update
sudo apt-get install gqrx

# Trusty:
sudo apt-get install gqrx-sdr rtl-sdr

Nach dem Anstecken des DVB-T Sticks informiert rtl_test darüber, ob er funktioniert und mit der Software kompatibel ist. Falls nicht, könnte eine Ursache darin liegen, dass sich ein DVB-T Treibermodul des Kernels bereits des USB-Sticks bemächtigt hat. In diesem Fall muss man die entsprechenden Module in die Blacklist eintragen. In Ubuntu legt man dazu die neue Datei /etc/modprobe.d/blacklist-dvb_usb.conf mit folgendem Inhalt an:

blacklist dvb_usb_rtl28xxu
blacklist rtl2830
blacklist rtl2832

Dann sollte auch gqrx den Stick erkennen (Bild unten). Nach dem Klick auf den Startbutton oben links beginnt das Programm sofort mit dem Empfang und der Demodulation. Im oberen Teil des Fensters sieht man das abgetastete Band in Echtzeit. Das Wasserfalldiagramm im unteren Bereich liefert eine kurze Historie der Signalintensitäten über das Frequenzspektrum. Nach dem Positionieren des Mauszeigers auf die Frequenzanzeige lässt sich die Frequenz per Tastatur oder Mausrad verstellen. Für den Empfang von Wettersensoren sollte der Mode AM (Amplitudenmodulation) eingestellt sein.
gqrx empfängt ein Signal vom Wettersensor

Wettersensoren von ELV

In meiner Wetterstation laufen die Sensoren KS 300-2 (Kombisensor, Bild oben rechts) und S 300 TH (Thermo/Hygro) von ELV rund um die Uhr. Somit bieten sie sich für erste Experimente an. Laut Typenschild senden sie auf 868,3 beziehungsweise 868,35 MHz. Die Abstimmung von gqrx auf eine dieser Frequenzen zeigt dann tatsächlich in regelmäßigen Abständen eine Aktivität (siehe Abbildung oben). Im Lautsprecher hört man gleichzeitig einen kurzen Ton:

Für eine genauere Untersuchung empfiehlt sich die Aufnahme des Signals in eine Datei über längere Zeit und eine anschließende Offline-Auswertung. Dazu kann man das Programm rtl_fm verwenden. Die Aufzeichnung erfolgt damit per:

rtl_fm -M am -f 868.3M -s 30k > rtl.dat

Das Ergebnis kann man zum Beispiel im Audioeditor audacity inspizieren, der Bestandteil der meisten Linux-Distributionen ist. Dazu importiert man die von rtl_fm erzeugte Datei per Import - Raw Data und wählt die Parameter Signed 16 bit PCM, Little-endian und Mono aus. Obwohl sich die Sensoren weit verteilt über mehrere Stockwerke und sogar außerhalb des Gebäudes befinden, sind ihre Signale in Form von kurzen Paketen deutlich zu erkennen. Kommt es dabei zu Übersteuerungen, dann hat die automatische Regelung der Verstärkung versagt und man muss sie manuell per Parameter -g setzen. Zum Beispiel:

rtl_fm -M am -f 868.3M -g 50 -s 30k > rtl.dat

Das stellt die Verstärkung fest auf etwa 50 dB ein. Eventuell muss man eine Zeitlang probieren, um den optimalen Verstärkungsfaktor zu finden.

Für eine nähere Betrachtung und Auswertung zoomt man in ein Paket hinein:
Sensordaten und Dekodierung des S 300 von ELV
Das Datenübertragungsformat für Sensoren von ELV ist bereits sehr gut dokumentiert. Es handelt sich um ein einfaches On-off keying Protokoll. Jedes Datenbit hat eine feste Länge von 1220 s, das Verhältnis von eingeschaltetem (on) zu ausgeschaltetem (off) Signal bestimmt den Wert des Bits (0 oder 1). Ein einzelnes Datenpaket beginnt immer mit zehnmal 0 zur Synchronisation und einem Startbit 1. Dann folgen der Sensortyp und die davon abhängigen Messwerte. Die Daten sind BCD-kodiert in Nibbles zu 4 bit gruppiert, wobei das niederwertigste Bit zuerst gesendet wird. Nach jedem Nibble folgt eine 1. Den Abschluss bildet eine Prüfsumme zur Validierung der Daten. Das oben dargestellte Datenpaket stammt von einem Thermo/Hygro-Sensor (Typ 1) mit der Adresse 4, der gerade eine Temperatur von 21.2 °C und eine relative Luftfeuchte von 68.8 % misst.

Zur Dekodierung des von ELV-Sensoren stammenden Datenstroms habe ich das Pythonscript decode_elv_wde1.py geschrieben, welches auf Github zur Verfügung steht. Am einfachsten legt man sich einen Klon des Projektes an:

git clone https://github.com/skaringa/weather-sdr-decode.git
cd weather-sdr-decode
./decode_elv_wde1.py --help

Zunächst testet man die Funktion des Programms mit der von rtl_fm aufgenommen Datei:

./decode_elv_wde1.py rtl.dat

sensor type: Thermo/Hygro
address: 4
temperature: 21.2
humidity: 68.8

Das Programm geht von einer festen Samplerate von 30 kHz aus. Damit entfallen auf jedes Bit etwa 36 Samples. Die Samplerate für rtl_fm stellt man per Parameter -s 30k ein.

Hat der Test funktioniert, dann lassen sich die Wetterdaten in Echtzeit empfangen und dekodieren:

rtl_fm -M am -f 868.35M -s 30k | ./decode_elv_wde1.py -

Raspberry Pi und PyPy

Die Echtzeitdekodierung funktioniert problemlos auf PCs mit einem nicht zu alten Intel Desktop Prozessor. Erste Versuche auf dem Raspberry Pi schlugen jedoch fehl, die Performance des Standard Python Interpreters ist viel zu schlecht.

Eine Abhilfe war relativ einfach möglich: Die Verwendung des alternativen Python Interpreters PyPy, der einen Just-In-Time (JIT) Compiler beinhaltet. PyPy ist unter Raspbian standardmäßig installiert (Paket pypy-upstream). Das Umschalten auf PyPy erfolgt durch Austausch der ersten Zeile von decode_elv_wde1.py. Statt

#!/usr/bin/env python

schreibt man

#!/usr/bin/env pypy

Durch den Einsatz von PyPy ließ sich auf einem Raspberry Pi 1 B die Laufzeit der Dekodierung einer 30 Sekunden langen Aufzeichnung um den Faktor 4 verringern! Damit gelingt eine Dekodierung in Echtzeit auch auf dem RasPi, sie lastet allerdings auf einem Modell der ersten Generation die CPU zu 90 Prozent aus.

Außensensor von Mebus

Außensensor von Mebus

In einer Bastelkiste fand sich ein alter Außensensor einer Wetterstation von Mebus. Die Suche nach der Beschreibung des Datenübertragungsformats war erfolglos. Ein Reverse-Engineering des Protokolls ist also angesagt.

Wenigstens war der noch vorhandenen Beschreibung der Wetterstation die Sendefrequenz von 434 MHz zu entnehmen. Ein erster Scan mit gqrx zeigte dann, dass die Frequenz tatsächlich 433.844 MHz beträgt. Die Aufzeichnung mittels

rtl_fm -f 433.844M -M am -s 30k > sensor.dat

liefert eine Reihe verwertbarer Datenpakete, das Bild unten zeigt ein Beispiel.

Schon das Modulationsverfahren unterscheidet sich von dem der ELV-Sensoren. Es handelt sich hierbei um eine Puls-Pausen-Modulation. Die Information ist in der Länge der Pausen zwischen den gleichlangen (450 s) Pulsen kodiert. Im Unterschied zum On-Off-Keying variiert damit die Länge eines Datenpaketes in Abhängigkeit von den übertragenen Daten. Ein Paket beginnt immer mit einer Sequenz von drei Pulsen und extrakurzen Pausen (450 s) zur Synchronisation zwischen Sender und Empfänger. Die nachfolgenden Pausen lassen sich alle in zwei Gruppen einteilen. Als Arbeitshypothese dient zunächst die Festlegung:

Kurze Pause (2430 s) == 0
Lange Pause (4380 s) == 1

Damit ist schon einmal die Dekodierung auf Bitebene möglich, wie sie in der ersten Zeile unter der Abbildung zu sehen ist:
Sensordaten und Dekodierung des Sensors von Mebus
Die Interpretation der Daten erfordert etwas Spürsinn. Dafür empfiehlt sich eine gezielte Veränderung der Eingangsdaten. So kann man den eingestellten Kanal umschalten und den Sensor in die Tiefkühltruhe packen. Durch Vergleich der Veränderungen am Bitmuster mit den angezeigten Messwerten findet man so relativ schnell das Datenübertragungsprotokoll:

1 Startbit == 1
11 Bit ID (Wert ändert sich bei jedem Batteriewechsel)?
1 Bit Taste Set gedrückt
2 Bit Kanalnummer - 1
12 Bit Temperatur in °C * 10
8 Bit Luftfeuchte in %

Alle Werte sind binär kodiert, das höherwertigste Bit wird zuerst gesendet.
Negative Wert sind im Zweierkomplement dargestellt.

Es gibt keine Prüfsumme, stattdessen überträgt der Sensor das Paket mehrmals hintereinander unverändert ab dem Startbit. Mit dieser Information dekodiert man das Beispielpaket zu:

id: 0x347 = 839 
setkey: 0
channel: 0 ≙ 1
temperature: 0xE5 = 229 ≙ 22.9 °C
humidity: 0x18 = 24

Das bereits erwähnte Github Repository enthält ebenfalls das Pythonscript decode_mebus.py zur Dekodierung dieses Datenformats. Die Benutzung erfolgt analog zum obigen Beispiel:

rtl_fm -M am -f 433.84M -s 30k | ./decode_mebus.py -

Falls das Programm Clipped signal detected meldet, dann hat die automatische Verstärkungsregelung nicht funktioniert und man muss wie oben beschrieben die Verstärkung per Parameter -g auf einen festen Wert setzen.

Außensensor der Sempre Wetterstation

Außensensor der Sempre Wetterstation

Im Herbst 2015 hat Aldi eine Wetterstation von Sempre verkauft. Robert hat - angeregt durch diesen Artikel - das Übertragungsprotokoll analysiert: Der Sender sendet etwa alle 80 Sekunden auf 434,030 MHz ein Signal, welches aus 12 Wiederholungen eines Datenblocks in Puls-Pausen-Modulation besteht. Es ähnelt damit dem oben beschriebenen Protokoll des Sensors von Mebus:


Sensordaten und Dekodierung des Sensors von Sempre

Fazit

Mit relativ wenig Aufwand an Material und Zeit war es möglich, die Daten der im Haushalt vorhandenen Funkwettersensoren mit einem RTL-SDR zu empfangen und zu dekodieren. Neben den beschriebenen Übertragungsprotokollen gibt es eine Vielzahl weiterer, die folgende Linkliste enthält einige Verweise darauf. Vielleicht motiviert Sie der vorliegende Beitrag aber auch dazu, bislang undokumentierte Datenformate durch Reverse-Engineering zu erschließen!