Liebe Forenleser
Ich habe mir ein RFM12 Pärchen gebaut und versende Messdaten in diesem
Format:
1
structrfdata_s{
2
uint16_tmoduleid;// Absender ID
3
uint16_ttimestamp;// Sekunden
4
uint16_tpacketid;// wird fortlaufend inkrementiert
5
uint16_tsensor[4];// Sensordaten
6
#ifdef USE_MD5_HMAC
7
md5_hash_thmac;// Authentisierung
8
#endif // USE_MD5_HMAC
9
};
Wenn ich nun ein weiteres Modul hinzufüge, oder einen weiteren Sensor,
mal auf MD5-HMAC verzichten möchte usw. muss ich den struct ergänzen,
alle Software neu übersetzen und flashen etc.
Ich könnte ein weiteres Attribut in den struct aufnehmen, welches mit
das Paketformat anzeigt; dann halte ich alle verwendeten Varianten nur
im Empfänger vor, den ich aufm Tisch habe und leicht updaten kann.
Geht das nicht eleganter? Hab kurz was über XML gelesen, aber ein Parser
scheint mir für einen MC zu heftig. DTD sieht etwas leichtgewichtiger
aus, könnte eine Option sein.
Wie macht ihr das denn in euren Hobbyprojekten? struct und gut ist, oder
eine Abstraktion? key-value Pärchen, binär oder ASCIIfiziert?
DTD dateien beschreiben die Struktur von XML Dateien. Sehr rudimentär
und meist unzureichend. Beides kannst Du auf Mikrocontroller vergessen,
ist viel zu SPeicher- und Rechenaufwändig.
Auch wenn ich das Problem gerade nicht wirklich verstehe, so werfe ich
mal JSON in den Raum. Einen Haufen C-Implementierungen gibts z. B. unter
www.json.org.
Wenn Du structs verschickst, dann doch wahrscheinlich als binär-daten.
Irgendwie verpackt in Pakete, damit Du zumindest den Anfang von einem
Datensatz erkennst.
Wie schon gesagt wurde ist es ne schlechte Idee XML zu verschicken. XML
heißt üblicherweise du verschickst die Daten als Text und hast jede
Menge overhead für die XML-Struktur. XML wirklich parsen (damit es auch
wie gewünscht resistent gegen zukünftige Änderungen ist) willst Du mit
nem uC nicht wirklich machen.
Der Overhead von Text-Übertragung zu XML ist schon groß genug! Von RAW
nach XML ist es dann noch mehr.
Aber du kannst ja key-value paare verschicken. Die keys legst Du fest
und die sind in all deinen Programmen gleich. Die Programme reagieren
auf/versenden nur die keys, die sie benötigen/kennen. D.H. ein Sensor
verschickt vielleicht nur ein Paket mit moduleid, packetid und einem
sensor-val-1.
Ein Empfänger, der den sensor-Wert loggen soll, liest moduleid, packetid
und sensor-val-1 aus. Erkennt z.B., dass der timestamp fehlt und ergänzt
den.
Ein anderer Empfänger findet keine relevanten daten und ignoriert das
paket komplett ...
Eine Möglichkeit für den key wäre die keys in einer zentralen
Header-Datei zu pflegen. Wenn Du als key dann ein word hernimmst, hast
Du 64k verschiedene Daten, die verschickt werden können. Solltest Du
abschätzen können, ob das reicht.
Eine andere Möglichkeit wäre eine einfache Hash-Funktion dafür zu nehmen
und dann mit den Namen zu arbeiten: hash( "moduleid" ), hash(
"sensor-val-1" )
Musst natürlich aufpassen, daß dir die Hash-Funktion für 2 verschiedene
Namen nicht den gleichen Hash-Wert liefert.
Das Paket hätte dann eine variable Größe.
Für die Menge an Daten, die zu übertragen sind bedeuted das natürlich
erst mal, daß es mehr werden, da nicht nur die Daten, sondern auch die
keys übertragen werden müssen. Aber netto kann es dann sogar weniger
sein, nämlich dann, wenn viele devices die meisten Teile des structs eh
leer lassen.
Stefan Frings schrieb:> DTD dateien beschreiben die Struktur von XML Dateien. Sehr rudimentär> und meist unzureichend. Beides kannst Du auf Mikrocontroller vergessen,> ist viel zu SPeicher- und Rechenaufwändig.MagIO schrieb:> XML wirklich parsen (damit es auch> wie gewünscht resistent gegen zukünftige Änderungen ist) willst Du mit> nem uC nicht wirklich machen.
Ah so, ich kenn mich in der Materie noch wenig aus. Dass ich keinen XML
Parser auf einem kleinen 8bit uC laufen lassen will ist klar. :)
Patrick schrieb:> Auch wenn ich das Problem gerade nicht wirklich verstehe, so werfe ich> mal JSON in den Raum.
Danke für den Tip. Wie ich sehe ist JSON viel schlanker als XML und
unterstützt sogar verschachtelte Strukturen. Nicht schlecht.
MagIO schrieb:> ... key-value paare ...
Ich hab auch den Eindruck, dass das der eleganteste Weg ist. Werd mir
dazu mal ein Konzept überlegen und etwas Code dazu schreiben. :)
Danke euch!
Stefan Frings schrieb:> DTD dateien beschreiben die Struktur von XML Dateien.
Ist allerdings ein veraltetes Prinzip, mittlerweile beschreibt man
besser als XSD.
Tom M. schrieb:> Dass ich keinen XML> Parser auf einem kleinen 8bit uC laufen lassen will ist klar. :)
Kann durchaus funktionieren. Du kannst ja die Validierung jemandem
anders überlassen und einfach validen Input voraussetzen.
Aber viel Overhead wäre es natürlich.
XML ist dann das Mittel der Wahl wenn man komplexere Zusammenhänge
übertragen muss. z.B. wenn hierarchische Daten eine variable Anzahl von
Subdatensätze haben.
Solange man nur Datensätze mit eine Anzahl verschiedener (erweiterbarer)
Werte hat ist Schlüssel-Wert der wohl effizienteste Weg.
Ob man jetzt Klartextschlüssel nimmt, oder einen 8 oder 16 Bit Wert als
Schlüssel hängt vom persönlichen Geschmack und davon ab wie ausgelastet
die Kommunikation ist. Waum sollte ich kryptische Schlüsselworte
benutzen wenn die Übertragungsstrecke zu 95% unbenutzt ist?
"Ob man jetzt Klartextschlüssel nimmt, oder einen 8 oder 16 Bit Wert als
Schlüssel hängt vom persönlichen Geschmack und davon ab wie ausgelastet
die Kommunikation ist. Waum sollte ich kryptische Schlüsselworte
benutzen wenn die Übertragungsstrecke zu 95% unbenutzt ist?"
Höchstens noch um sich die Konvertierung zu sparen:
Beim Sender von uint16_t nach String
Beim Empfänger von String nach uint16_t
Die Message muss dann zuerst in einem Buffer erstellt werden, damit der
Paket-Header die Länge kennt...
Aber an sich ist JSON genau das: ein protokoll um KEY/VALUE zu
übermitteln.
Also direkt uint16_t zu übertragen ist dann sowas wie JSON_RAW ;o)
Aber mit Funk-Übertragung ist es doch ein leichtes einen Empfänger zu
bauen, der für's debugging alles liest und konvertiert auf einem
Terminal rausdumpt. Also ist die Frage "Warum NICHT kryptisch!" genauso
berechtigt. Zumal die 95% idle time ja vielleicht nur am Anfang
zutrifft. Hier noch ein Sensor, da noch einer und schon ist so viel los,
daß man sich wünscht es doch gleich effizient gemacht zu haben.
MagIO schrieb:> Aber an sich ist JSON genau das: ein protokoll um KEY/VALUE zu> übermitteln.> Also direkt uint16_t zu übertragen ist dann sowas wie JSON_RAW ;o)
Ich hab mich gestern noch ein bisschen auf dem Web umgesehen und dabei
die "Universal Binary JSON Specification" entdeckt (http://ubjson.org).
Dabei werden keys als ASCII übertragen, zusammen mit einem Typenfeld und
binären Datentypen. Das ganze ist als hex/ascii Dump einigermassen
lesbar. Werde mich mal an einer Implementation versuchen.
Marwin schrieb:> nicht hip genug...
IFF scheint mir ein Containerformat zu sein, in welches sich dann Daten
wie Bitmaps reinpacken lassen. Für meinen Anwendungsfall (Messdaten
übertragen) möchte ich das "Reinpacken" elegant lösen, siehe
Eröffnungsbeitrag.
Die IFF Spezifikation hilft mir dabei nicht - oder welches Format
scheint dir geeignet?