Guten Tag Ich suche nach einer Möglichkeit kurze Datenpakete zu komprimieren. Im konkreten Fall ist es eine Übertragung von 10Byte Binärdaten. (4x 2Byte und 2x 1Byte große Variabeln) Die Komprimierverfahren, die ich bis jetzt gefunden habe, sind nur für größere Datenmengen. Kennt jemand ein Komprimier-Verfahren, dass man auch auf einem AVR verwenden kann?
es kommt auf die Daten an, wenn sie wirklich zufällig sind, dann kann man nichts komprimieren.
Die ersten 8 Byte sind Sensordaten, die über ADC eingelesen werden. Die letzten beiden Byte sind Daten von einer Schalter-/Taster-Matrix. Die ersten 8 Byte ändern sich also nicht sprunghaft, sondern folgen einer (vorher unbekannten) Kurve.
Barny schrieb: > Die ersten 8 Byte ändern sich also nicht sprunghaft, sondern folgen > einer (vorher unbekannten) Kurve. Da bietet sich eine Huffman-Codierung mit fest definierter Wahrscheinlichkeitsverteilung und Codierung an. Kleine Differenzen in wenig Bits, grosse Differenzen in viel Bits codieren. Naturgemäss wird die Länge der entstehenden Messages variabel, häufige sind kürzer, seltene länger. Allerdings musst du vmtl. damit rechnen, das auch mal eine Message über die Wupper geht, und dass der Empfänger irgenwann mal einen Anfang braucht. > letzten beiden Byte sind Daten von einer Schalter-/Taster-Matrix. Und da wird wohl der Normalzustand der Matrix "inaktiv" sein, was sich ggf. in nur einem Bit codieren lässt.
Bei 10 Byte Daten kannst du die Daten selber so gut wie nicht mehr kompremieren. Im Einzelfall mag das gehen (wenn die aktuellen Datenwerte günstig sind), aber meistens ist das "Kompremierte" danach länger als die Urdaten. Aber eines der üblichen Kompremiervorgänge wirst du da knicken können, da geht nicht viel. Was ich an deiner Stelle versuchen würde: Nur die Veränderungen übertragen. Da sich deine ADC Werte nicht sprunghaft ändern, würde es unter Umständen genügen, nur die Änderung (+-127) in nur 1 Byte zu übertragen. Der Empfänger rechnet den Wert zu seinem letzten bekannten Wert hinzu und hat so wieder seinen aktuellen Wert. Das wären dann 4 Byte Einsparung. Der Grund warum ich oben nur +-127 genannt habe und nicht die Asymetrie -128/+127 ausgenutzt habe, liegt darin, dass ich mir den Wert 0x81 als Sonderfall reservieren würde. Ist das erste Byte der Nachricht 0x81 dann handelt es sich nicht um Differenzwerte, sondern die übertragenen Sensordaten sind die Absolutwerte (also 4 mal 2 Byte). Die würde ich ab und zu einstreuen, damit der Empfänger mit Sicherheit wieder einen aktuellen Stand hat. Das könnte man überhaupt für alle 4 Sensorwerte einzeln vereinbaren: grundsätzlich wird nur die Differenz übertragen, es sei denn diese Differenz sei -128 (also 0x81). Dann folgt auf diese 0x81 noch 2 Bytes mit dem absoluten Messer in 2 Bytes. Damit bist du dann in der Lage, dass der Sender dann auch tatsächliche Sprünge in den Messdaten übertrageb kann. (denn einer Aussage "Das kommt in meinen Messwerten nicht vor" traue ich grundsätzlich nicht über den Weg) Bei den Schaltern kannst du nicht mehr viel machen. 2 Byte, da lässt sich nichts mehr kompremieren. Ausser vielleicht ein spezieller erster Bytewert (welcher in den Schalterstellungen nicht vorkommen kann), der aussagt: keine Veränderung. Wenn du aber alle 16 Bits für Schalter brauchst, dann geht da nichts mehr.
Man kann da zig Varianten vorschlagen, aber alles hängt davon ab, wie häufig/schnell sich die Daten ändern. Wenn sich die ADC-Daten alle ungefähr mit der gleichen Frequenz/Amplitude ändern ist eine andere Codierung sinnvoller, als wenn sich nur einer davon häufig ändert, die anderen selten oder nur sehr gering (Rauschen ggf. vorher ausfiltern). Wenn sich i.d.R. nur einer davon häufiger ändert, dann kann man den als Differenz mit Tag übertragen, d.h. die Message heisst sinngemäss "ADC#0 +15" und überträgt bei den anderen Kanälen schlicht garnichts. Diesem Schema folgend muss man bei den Schaltern/Tastern normalerweise nichts übertragen, weil sich da in den meisten Messages gegenüber der vorherigen nichts geändert hat. Man muss nur einen Code, ein Tag oder ein Bit reservieren, um im Fall einer Änderung ebendiese übertragen zu können. Mit solchen Methoden kommt man je nach Daten u.U. auf eine mittlere Länge von 2-3 Bytes pro Sample.
Danke für eure Tipps Noch ein paar Details mehr. Normalerweise werden die Daten im Sekundentakt übertragen. Es ist ein hochauflösender Modus geplant, bei dem zwischen 5 und 50 mal in der Sekunde die Daten übertragen werden. Genau desswegen möchte ich die Daten komprimieren. Da sich die Daten innerhalb dieses Zeitraums nur sehr wenig ändern, wird die Methode nur die Änderungen zu übertragen sicher die Besste sein. Außer euch fällt etwas besseres ein.
Nur mal so ne Frage, wo ist das Problem mit 50-500Byte pro Sekunde, da ist doch fast alles schnell genug.
Nicht die Geschwindigkeit, sondern die Datenmenge ist das Problem. Ich sende mit 868MHz Bei nur 6 Minuten Sendezeit wird es etwas eng.
Barny schrieb: > Nicht die Geschwindigkeit, sondern die Datenmenge ist das Problem. > Ich sende mit 868MHz > Bei nur 6 Minuten Sendezeit wird es etwas eng. Ich würde mal sage die Baudrate ist dein Problem. Und im Moment sehe ich noch nicht, warum du die nicht soweit hochsetzen kannst, dass du 500 Bytes in der Sekunde rüberblasen kannst. 500 Bytes / Sekunde sind nicht allzuviel. Kurzer check mit Google ergibt, dass da Baudraten bis rauf zu knapp 40kBit/s möglich sind. Das sind über den Daumen gerechnet 40000 / 10 = 4000 Bytes pro Sekunde. Da bist du mit 500 Bytes noch weit weg.
Bei Funk wäre zudem zu bedenken, dass Differenzcodierung bei verlorenen Daten ein Problem kriegt und man bei Funk damit rechnen muss.
A. K. schrieb: > Bei Funk wäre zudem zu bedenken, dass Differenzcodierung bei verlorenen > Daten ein Problem kriegt und man bei Funk damit rechnen muss. Aus dem gleichen Grund ist es auch dringend angeraten, sich bei Funk ein anderes Protokoll als "Alle Datenbytes einfach so rüberblasen und darauf hoffen, dass der Empfänger synchron die Bytes wieder richtig auseinanderpfriemelt" sich auszudenken. Bei Funk MUSST du damit rechnen, dass Bytes verloren gehen. Mit allen Konsequenzen.
Karl heinz Buchegger schrieb: > Bei Funk MUSST du damit rechnen, dass Bytes verloren gehen. Mit allen > Konsequenzen. Also mindestens noch einen CRC16 dazu. Dann fehlt aber immer noch eine Mimik daß der Empfänger verlorene (kaputte) Pakete noch mal nachfordern kann.
muss es denn sofort gesendet werden? Wenn nicht kann man auch sammeln und dann komprimieren, das ganze das als ein etas größere Packet abschicken.
Wenn die Daten im Absender nicht leidlich tief gepuffert und anschliessend gebündelt übertragen werden, dann sollte man überlegen, ob man nicht eher mit teilweise verlorenen Daten leben will, als sich bei teilweise gestörtem Funk die Leitung und das Übertragungsprotokoll noch mit Retries zuzustopfen und so ggf. ganz zu blockieren. Wenn das nicht in Frage kommt, dann ist eine ausreichend tiefe Speicherung im Absendersystem unbedingt ratsam.
Also Es muss sofort gesendet werden, ich brauche die Daten live. Aktuell verwende ich eigentlich kein Protokoll. Ich sende die Daten einfach so und hänge einen Kontrollwert hinten dran. (8 Bit Checksumme -> Dass eine Byte, dass ich vorher versehentlich zu den Schaltern gezählt habe.) Bei fehlerhaften Daten wird dass Datenpaket verworfen und auf dass Nächste gewartet. Da die Sensordaten immer wieder neu kommen, macht es nichts aus wenn dass ein oder andere Paket verlohren geht. Bezüglich Datenrate. Das X-Bee schafft wenn ich mich richtig erinnere eine Datenrate von 24kBit/s. Beim Übertragen genemigt sich das X-Bee im günstigsten Fall ca. 2/3 des möglichen Datenvolumens als Overhead. Wenn man noch zusätzliche Dinge wie mehrfachsenden der Daten, Adressen,... verwendet, schaut das Ganze noch schlimmer aus. Dass bedeutet ich habe 2400 Byte/s 60s 6min = 864000Byte an Rohdaten. 864000 / 3 = 288000 Byte an Nutzdaten Und bei 500 Byte die Sekunde brauche ich 30000 Byte. Dass bedeutet dass sich das Ganze mit den Modulen, die ich verwende nicht ganz ausgeht.
Barny schrieb: > Aktuell verwende ich eigentlich kein Protokoll. > Ich sende die Daten einfach so und hänge einen Kontrollwert hinten dran. > (8 Bit Checksumme -> Dass eine Byte, dass ich vorher versehentlich zu > den Schaltern gezählt habe.) > Bei fehlerhaften Daten wird dass Datenpaket verworfen und auf dass > Nächste gewartet. > Da die Sensordaten immer wieder neu kommen, macht es nichts aus wenn > dass ein oder andere Paket verlohren geht. Dann ist eine Differenzkodierung aber schlecht, denn die funktioniert ja nur, wenn die vorangegangenen Pakete auch angekommen sind. > Beim Übertragen genemigt sich das X-Bee im günstigsten Fall ca. 2/3 des > möglichen Datenvolumens als Overhead. Wenn man noch zusätzliche Dinge > wie mehrfachsenden der Daten, Adressen,... verwendet, schaut das Ganze > noch schlimmer aus. > > Dass bedeutet ich habe 2400 Byte/s 60s 6min = 864000Byte an Rohdaten. > 864000 / 3 = 288000 Byte an Nutzdaten > > Und bei 500 Byte die Sekunde brauche ich 30000 Byte. Wie kommst du auf diesen Wert? Und warum rechnest du es auf 6 Minuten hoch und dann wieder zurück? Du hast 2400 Byte/s an Rohdaten. Ein Drittel davon sind 800 Byte/s. Du brauchst aber nur 500 Byte/s.
Rolf Magnus schrieb: > Wie kommst du auf diesen Wert? Und warum rechnest du es auf 6 Minuten > hoch und dann wieder zurück? Ich rechne auf 6Minuten auf weil nur 6 Minuten in einer Stunde gesendet werden darf. -> 10% dudy cycle Runter rechne ich nicht mehr. Dass mit den 6 Minuten ist eine gesetzliche Angelegenheit. Dass bedeutet ich habe 2400 Byte/s * 60s = 144000 Bytes/min 144000 Bytes/min * 6min/h = 864000Byte an Rohdaten. 864000Byte / 3 = 288000 Byte an Nutzdaten Dass ist leider eine Tatsache.
> Ich rechne auf 6Minuten auf weil nur 6 Minuten in einer Stunde gesendet > werden darf. Jetzt wird vieles klarer. Müssen das 6 zusammenhängende Minuten sein und dann darfst du wieder 54min nichts senden? Dann musst du ja sowieso viel speichern und hast viele Daten zu komprimieren.
Die 6 Minuten kann ich aufteilen wie ich will. Und da ich nicht so lange auf die Daten warten will und kann, möchte ich die Daten nicht bündeln, sondern live senden. Rolf Magnus schrieb: > Dann ist eine Differenzkodierung aber schlecht, denn die funktioniert ja > nur, wenn die vorangegangenen Pakete auch angekommen sind. Da hast du recht, da werde ich mir etwas überlegen.
...bei mir sind jetzt folgende Vorgaben des TE hängen geblieben: - 288000 Bytes pro Stunde zur Datenübertragung nutzbar - 10 Bytes pro Sample - 8 Bytes des Samples folgen einer unbekannten Kurve - gewünschte Samplerate: 5 bis 50 Samples pro Sekunde - Daten sollen ungepuffert (Live) zur Verfügung stehen - Der Verlust einzelner Datenpakete (Samples) ist unkritisch ...für mich hieße das jetzt im einfachsten Fall 7 Samples pro Sekunde unkomprimiert zu senden. Erweitern wäre bei 7 Samples/s noch auf 11 Bytes möglich um mit einer Checksumme korrupte Datenpakete zu verwerfen. Für jegliche Gedanken bzgl. Komprimierung müsste näheres zur Kurvenform der 8 Datenpakete bekannt sein. Da könnte sich vielleicht etwas in Richtung ADPCM eignen.
Tom schrieb: > Für jegliche Gedanken bzgl. Komprimierung müsste näheres zur Kurvenform > der 8 Datenpakete bekannt sein. Da könnte sich vielleicht etwas in > Richtung ADPCM eignen. Nachtrag: Ich meinte natürlich nicht 8 Datenpakete, sondern 8 Bytes. Habe jetzt auch im nachhinein erst gesehen, dass es eigentlich nicht 8 Bytes sondern 4x2Bytes sind, also vermutlich 4 voneinander unabhängige Sensoren. Sprich, auch 4 voneinander unabhängige Kurven. Das schränkt das Potenzial zum Komprimieren schon verdammt ein. Die Anzahl der Samples pro Sekunde zu verdoppeln halte ich selbst mit geeigneter Komprimierung schon für unrealistisch. Es wird vermutlich für die Anwendung auch keinen großen Unterschied machen ob 7 Samples pro Sekunde oder (geschätzt komprimiert) 10 Samples pro Sekunde übertragen werden können. Mein Fazit: Unkomprimiert 7 Samples (10 bytes + 1byte) pro Sekunde mit einer Checksumme übertragen um die Integrität der Daten sicherzustellen. Jeglicher sonstiger Aufwand erscheint mir bei unveränderten technischen Vorgaben für nicht sinnvoll.
Tom schrieb: > Habe jetzt auch im nachhinein erst gesehen, dass es eigentlich nicht 8 > Bytes sondern 4x2Bytes sind, also vermutlich 4 voneinander unabhängige > Sensoren. Sprich, auch 4 voneinander unabhängige Kurven. Es sind 4 Sensoren. Nach einwenig Nachdenken sind mir noch weitere Einspahrungsmöglichkeiten eingefallen. Bei den 2 x 1 Byte für die Schalter kann ich auf 1 Byte verzichten, wenn ich anstatt jedesmal alle Zustände zu übertragen sondern nur den Taster, der sich geändert hat sende. -> 7Bit Adresse + 1 Bit für Zustand ein/aus Da die Sensoren über einen 10Bit ADC eingelesen werden, sind 6 Bit pro Wert ungenutzt. Man kann also schachteln. Dass bedeutet ich kann 4 Sensoren und ein Byte für Schalter/Taster in 6Byte unterbringen. Dass macht 7 Byte mit Konntrollwert. Dass bedeutet, dass ich 11Pakete/s senden kann. Wenn ich bedenke, dass das 1. Bit der Sensordaten meißtens sowiso nur wild herumläuft, kann man da auch noch weiter einsparen. Aber solange keiner eine geniale Lösung hat wie man die Daten komprimieren kann, mussich einsehen, dass nicht mehr Pakete / s gesendet werden können.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.