Dekodieren von TiNo Funksignalen mit SDR-RTL und rtl_433

Im Beitrag „Dekodieren von TiNo Funksignalen mit SDR-RTL und GNURadio“ hatte ich berichtet wie ich stundenlang am GNURadio gedreht hatte um TiNo Signale zu empfangen, zu triggern und zu dekodieren. In diesem Beitrag geht es um das weit verbreitete Tool „rtl_433“ welches hier auf Github zu finden ist.

In letzter Zeit hat sich das Tool enorm weiterentwickelt, unter anderem kam die Fähigkeit dazu, FSK Signale zu dekodieren. Ich muss gestehen dass ich auf meinem PC eine uralte Version hatte und das Tool nur sehr selten benutzte. Um so mehr freute mich die Entdeckung, dass TiNo Datenpakete mit neueren Versionen relativ einfach empfangen werden können:

rtl_433 -R 0 -X "n=TiNo,m=FSK_PCM,s=52,l=52,r=2500,preamble={16}2dd2" -f 866M -s 230400 -vvv

Nehmen wir das Kommando auseinander

-R 0 entferne alle vordefinierten Geräte. Andernfalls würde rtl_433 versuchen alle möglichen, hier nicht verwendeten Geräte zu dekodieren.
-X <Definition> dekodiere ein nutzerdefiniertes Gerät. <Definition> wird weiter unten erklärt.
-f 866M stelle die Frequenz auf 866.000 MHz ein, die Standard Frequenz des TiNo.
-s 230400 optionale Abtastfrequenz. Um es dem Demodulator zu erleichtern, sind das genau 12 Samples pro Bit.
-vvv „verbose“ Modus, gebe so viele Daten aus wie möglich.

Die -X Option ist weniger kompliziert als es aussieht:
n=TiNo Name des Geräts
m=FSK_PCM Art der Modulation (hier klassische FSK)
s=52,l=52 Dauer eines Bits in Mikrosekunden. Das ist ungefähr 1 / 19200Bd, was der Bit Rate des TiNo Protokolls entspricht.
r=2500 Abbruch Kriterium in Microsekunden. Nach dieser Zeit ohne Modulation betrachtet rtl_433 die Übertragung als beendet. Es entspricht 50 Bits. Das kann man auch kürzer machen.
preamble={16}2dd2 Dies weist an, sich auf die Bitfolge 0x2DD2 zu synchronisieren. Das ist die Bitfolge der Synchronisation des TiNo. Achtung, die zweiten 8 Bit sind vom Benutzer im TiNo selbst konfigurierbar, müssen bei Bedarf also angepasst werden.

Was man im Bild oben sieht sind die Rohdaten. Das erste Byte zeigt die Länge der Bitsequenz an: 10 in HEX Code ist also 16 Bytes oder 128 Bits. Die folgenden 16 Bytes sind die eigentliche Nachricht.

Dekodierung der Nachricht – Das Prinzip

Zunächst werden alle Bits in einem „Deinterleaver“ so umsortiert, dass später selbst der Verlust von 8 aufeinanderfolgenden Bits in den Rohdaten korrigiert werden kann. Die 16 Bytes lange Nachricht ist mit FEC (Forward Error Correction) kodiert. Damit kann in einer Bitfolge von 8 Bits ein Bitfehler korrigiert werden, und zwei Bitfehler werden erkannt (können dann aber nicht korrigiert werden).

Der Preis für die Codierung ist Redundanz – Um eine Nachricht mit 8 Bytes zu übertragen, braucht die Kodierung 16 Bytes. Verglichen mit anderen kommerziellen Produkten ist das allerdings nichts: Manchmal wird die unkodierte Nachricht einfach acht bis sechzehnmal wiederholt, in der Hoffnung dass wenigstens ein einziges Paket heil ankommt. Das ist aus Sicht der Nachrichtentechnik aber redundant und ineffizient! Wir wollen im TiNo schließlich Strom sparen.
Ein freundlicher User der TiNo’s hat mir Python Skripte zur Verfügung gestellt, mit denen sich die TiNo-Kodierung und Dekodierung einschließlich der Verschlüsselung einfach bewerkstelligen lässt. Jetzt muss man „nur noch“ die Messwerte aus den Rohdaten extrahieren. Das Schema dafür ist im „Tino Radio Data Protocol“ dokumentiert.

Dekodierung des Datenblocks mit Python

Da ich im Moment nicht in die Software des rtl_433 Tools eingreifen möchte, leite ich die von rtl_433 erhaltenen Daten in eine csv-Datei um: das gelingt mit der Option
-F csv:log.csv -M time
Von dort holt ein parallel laufendes Python Skript immer die letzte Zeile der Datei ab, sobald eine TiNo Nachricht reinkommt. Die dekodierten Messdaten kann man dann selbst in seine Datenbank schreiben. Das Ganze ist natürlich nicht als ein seriöses System gedacht, es dient lediglich zur Veranschaulichung. Zum einen wächst die von rtl_433 generierte csv-Datei bei mir relativ schnell, zum anderen ist das Python Skript primitiv und lädt immer die gesamte Datei um die letzte Zeile zu dekodieren. Das führt früher oder später mit Sicherheit zum Systemcrash. Im Prinzip brauche ich ja immer nur die letzte Zeile der Datei. Leider hält rtl_433 aber die Datei immer offen, man kann den nicht mehr benötigten Datenmüll deshalb nicht löschen solange rtl_433 läuft. Die Python Skripte zum Dekodieren und Entschlüsseln lege ich dennoch auf Github ab, falls jemand Interesse hat.

Ausblick

TiNo Dekodierung in rtl_433 integrieren

Geschickt wäre es wenn rtl_433 selbst die Dekodierung vornehmen könnte. Dazu definiere ich ein neues „Device“ in der rtl_433 Software. An der Implementierung eines Decoders arbeite ich, wenn nichts dazwischen kommt (Weltreise, 3. Weltkrieg, Pandemie II, Klima, etc). Übrigens, den Source Code von rtl_433 zu kompilieren ist ein Abenteuer, aber nach zwei (!) Tagen hats dann tatsächlich geklappt. Das wird ein extra Blog Beitrag.

Der Source Code von rtl_433 ist in sehr gut strukturiertem C geschrieben. Da C sozusagen meine Muttersprache ist war es leicht möglich den TiNo zu den Geräten hinzuzufügen.

Daten abspeichern

Angenommen man hat einen TiNo Dekodierer in rtl_433 eingebaut und man will den RTL-SDR ernsthaft als Empfänger für TiNo Nachrichten einrichten, dann hat man mehrere Möglichkeiten:

  1. Mit der ursprünglichen Idee die Daten mittels Python Skript abzugreifen, müsste rtl_433 die csv Datei immer überschreiben, so dass diese immer nur eine Zeile hat. Diese kann dann vom Python Skript aufgegriffen und weiterverarbeitet werden. So wird ein Systemcrash aufgrund zu großer Dateien verhindert. Dies erfordert allerdings einen Eingriff in Systemfunktionen von rtl_433.
  2. Speichern der Daten, z.B in einer csv Datei. Das ist geht sehr einfach , jedoch wächst die Datei nach kurzer Zeit enorm an. Da rtL_433 die Datei immer offen hält, kann man sie auch nicht von außen löschen. Die Strategie um einen System Crash zu vermeiden wäre hier, z.B. jede Woche rtl_433 einfach neu zu starten. Dazu benötigt man ein Skript (bash oder Python) welches das bewerkstelligt. Das Python Skript muss auch rtl_433 neu starten, falls es einmal abstürzt.
Praktischer Nutzen??

Die Empfangsempfindlichkeit des RTL-SDR scheint nicht besonders zu sein. Ab ca. -80dBm geht bei mir gar nichts mehr. Warum das so ist, und ob man Abhilfe schaffen kann? Insofern ist derzeit der praktische Nutzen eher gering. Aber die Untersuchung war’s wert!

Hinterlasse einen Kommentar