Forum: Mikrocontroller und Digitale Elektronik Messwert+Zeitpunkt komprimieren


von Michael S. (rbs_phoenix)


Lesenswert?

Hallo zusammen,
ich habe vor eine Langzeitmessung zu machen. Dort wird ein, vielleicht 
auch 2 16bit Messwerte erfasst und soll zusammen mit Datum und Zeit in 
ein externen Flash-Speicher (mit 16bit breiten Zellen) gespeichert 
werden. Es soll jederzeit möglich sein, die Daten via USB auszulesen. 
Das alles ist ja kein Problem. Um nun aber möglichst viel Datenpakete im 
Flash speichern zu können, würde ich die Daten gerne komprimieren. 
Ansich ist mir egal wie es gespeichert wird, beim Auslesen würde ich 
jedes Paket dekomprimieren und zum PC schicken. Je nachdem würde ich 
also den Unix-Zeitstempel oder einen String komprimieren. Eben das, was 
weniger Platz braucht bzw sich besser komprimieren lässt. Bei den 
Messwerten weiß ich aber nicht, wie man sie komprimieren könnte, da sie 
ja jeden beliebigen Wert annehmen können.
Meine praktische Erfahrung ist allerdings nur das packen und entpacken 
von zip, rar oder 7zip Dateien.

Realisiert wird das Projekt mit einem PIC18F oder einem dsPIC und der 
Sprache C. Da die Messwertaufnahme allerhöchstens 4 mal die Minute ist, 
ist die Geschwindigkeit relativ unkritisch, ebenso wie die Code-Größe. 
Es sollte primär eine möglichst hohe Komprimierungsrate haben. Also ist 
die eigentliche Frage: Womit mache ich das am besten? Ich habe schon 
öfter was von zlib und LZO gelesen, es war aber immer in einem anderen 
Zusammenhang. Macht es einen Unterschied, ob ich immer nur ein Paket 
(also Zeit/Datum und 2 16bit Zahlen) komprimiere oder ob ich immer 
mehrere Pakete sammle und diese dann auf einmal komprimiere? Ich denke 
da z.B. an das selbe Datum, was ja ggf. dann besser komprimiert werden 
kann, wenn es bei allen Paketen das selbe ist. Bei einzelner 
Paketkomprimierung kann man darüber ja keine Aussage machen.

Ich wäre für jeden Rat/Hinweis dankbar.

PS: Ist das Unterforum "Projekte und Code" nur zum veröffentlichen 
besagter Dinge oder ist dort auch eine Code-Anfrage gewünscht? Dann wäre 
da vielleicht der bessere Ort für meine Frage.

von Karl H. (kbuchegg)


Lesenswert?

Michael Skropski schrieb:

> Je nachdem würde ich
> also den Unix-Zeitstempel oder einen String komprimieren.

Ich würde mal in die Richtung überlegen, nicht die Werte selber zu 
speichern, sondern immer nur die Veränderung.

> Messwerten weiß ich aber nicht, wie man sie komprimieren könnte, da sie
> ja jeden beliebigen Wert annehmen können.

Die sich aber bei realen Messwerten meistens nicht sprunghaft von einem 
Ende der Messskala zum anderen ändern. Zudem sind oft viele Wert 
hintereinander identisch, müssen daher auch nicht einzeln gespeichert 
werden.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Michael Skropski schrieb:

> PS: Ist das Unterforum "Projekte und Code" nur zum veröffentlichen
> besagter Dinge

genau dafür ist es gedacht.

von Wolfgang A. (Gast)


Lesenswert?

Michael Skropski schrieb:
> Ich wäre für jeden Rat/Hinweis dankbar.

Das hört sich so an, als ob das meiste, was du speichern möchtest, 
Datums- und Zeitwerte sind. Wenn du ein festes Abtastintervall hättest, 
ergäbe sich dort kräftiges Sparpotential.

Die andere Frage ist natürlich, warum du überhaupt Speicherplatz sparen 
willst. Auf einer simplen SD-Card mit 4GB könntest du bei deiner 
Datenrate wesentlich länger als hundert Jahre aufzeichnen.

von Michael H. (dowjones)


Lesenswert?

Pauschal koennte man wohl sagen, das (erfolgreiche) Datenkompression 
darauf beruht, das man Strukturen in den Daten erkennt und sie entfernt 
(bzw. nur einmalig speichert, bzw dem Entpacker von vornherein bekannt 
sind). Die Folgerung daraus ist, das sich Daten umso schlechter 
komprimieren lassen, je weniger Strukturen sie aufweisen, also je 
"zufaelliger" sie sind.

Fuer eine Empfehlung ergibt sich daraus direkt die Frage: Kann man 
annehmen das deine Messwerte irgendwelche (hinreichend haeufig 
auftretenden) Strukturen aufweisen? Und wenn ja - welche?
Wenn beispielsweise ein Messwert mehrmals hintereinander auftritt dann 
koennte man mit einem einfachen RLE schon was reissen. Wenn sich ganze 
Sequenzen von Messwerten ab und an mal wiederholen, dann waere ein LZ 
angebracht. Wenn manche Messwerte deutlich haeufiger vorkommen als 
andere, dann duerfte ein Rangecoder gute Arbeit leisten. Oder wenn die 
beiden Messwerte eine Korrelation aufweisen (ggf. auch mit dem 
Zeitstempel), dann kann man sicherlich auch daraus Kapital schlagen. 
Oder wenn die Messwerte grob betrachtet einen sinusfoermigen Verlauf 
haben. Oder oder oder...
Generell gilt: Je mehr man ueber die Daten weiss (bzw. annehmen kann), 
desto weniger muss man abspeichern. Gegebenenfalls kann man sich auch 
ueberlegen, ob man die Daten vor der Kompression transformieren kann, so 
dass Strukturen deutlicher hervortreten (die oben erwaehnte Differenz 
zwischen zwei Werten waere ein einfaches Beispiel dafuer).

Eine weitere Frage ist: Wieviel RAM steht zur Verfuegung? Viele 
Kompressionsverfahren (insbesondere solche, die versuchen selbststaendig 
Strukturen zu erkennen) legen waehrend des packens umfangreiche 
Datenstrukturen an. Je weniger RAM man nutzen kann, desto schlechter 
sind bei vielen Algorithmen die Kompressionsraten (bis hin zur 
Nutzlosigkeit).

Michael Skropski schrieb:
> Macht es einen Unterschied, ob ich immer nur ein Paket
> (also Zeit/Datum und 2 16bit Zahlen) komprimiere oder ob ich immer
> mehrere Pakete sammle und diese dann auf einmal komprimiere?
Das haengt vom konkreten Kompressionsverfahren ab. Manche sind fuer den 
online-Betrieb gedacht, andere arbeiten auf "gesammelten Daten". 
Pauschal kann man auch hier nur wenig Hilfreiches sagen.

von M.O. (Gast)


Lesenswert?

Michael H. schrieb:
> Fuer eine Empfehlung ergibt sich daraus direkt die Frage: Kann man
> annehmen das deine Messwerte irgendwelche (hinreichend haeufig
> auftretenden) Strukturen aufweisen? Und wenn ja - welche?

Mindestens über die Zeitmesswerte ist schon einiges bekannt. Es soll das 
komplette Datum/Zeit festgehalten werden und der Unterschied zwischen 
zwei Werten beträgt mindestens 15 Sekunden.

von Ulrich H. (lurchi)


Lesenswert?

Sofern die Zeitlichen Abstände konstant sind (kann man oft so 
einrichten) kann man auf das Speichern der Zeit verzichten. Sonst reicht 
es wohl aus nur die Zeitdifferenz zu speichern - ggf. auch so das die 
Rundung / Addition in der Summe hin kommt. Den Tag oder die Stunde muss 
man nur einmal am Anfang speichern - später sollten die Sekunden 
reichen.

Bei den Daten ist die Speicherung nur der Veränderungen schon mal eine 
gute Idee. Dann wohl auch binär, und ohne Trennzeichen.

 Wenn man dann noch komprimieren will, dann halt ein klassischer 
Algorithmus. Je nach Version brauchen die aber relativ viel RAM (viele 
kBytes-MByte) - das was im PC gut geht, passt also nicht unbedingt am 
µC.

von Werner M. (Gast)


Lesenswert?

Michael Skropski schrieb:
> Es sollte primär eine möglichst hohe Komprimierungsrate haben.

Selbst bei einem optimalen Kompressionsprogramm ist die Kompressions um 
so kleiner, je höher der Informationsgehalt der Daten ist.

Die andere Frage ist natürlich, ob die Krompression Verluste haben darf.

von Falk B. (falk)


Lesenswert?

@ M.O. (Gast)

>Mindestens über die Zeitmesswerte ist schon einiges bekannt. Es soll das
>komplette Datum/Zeit festgehalten werden und der Unterschied zwischen
>zwei Werten beträgt mindestens 15 Sekunden.

Damit könnte man schon mal die Einheit des Zeitstempels auf 15s 
festlegen. Mit 32 bit kommt man da ~ 1e9 min bzw. ~1900 Jahre. Sollte 
reichen.

von Michael S. (rbs_phoenix)


Lesenswert?

Karl Heinz schrieb:
> Michael Skropski schrieb:
>
>> Je nachdem würde ich
>> also den Unix-Zeitstempel oder einen String komprimieren.
>
> Ich würde mal in die Richtung überlegen, nicht die Werte selber zu
> speichern, sondern immer nur die Veränderung.

Das ist keine schlechte Idee.


Wolfgang A. schrieb:
> Michael Skropski schrieb:
>> Ich wäre für jeden Rat/Hinweis dankbar.
>
> Das hört sich so an, als ob das meiste, was du speichern möchtest,
> Datums- und Zeitwerte sind. Wenn du ein festes Abtastintervall hättest,
> ergäbe sich dort kräftiges Sparpotential.

Das gibt es leider nicht.


> Die andere Frage ist natürlich, warum du überhaupt Speicherplatz sparen
> willst. Auf einer simplen SD-Card mit 4GB könntest du bei deiner
> Datenrate wesentlich länger als hundert Jahre aufzeichnen.

Es soll möglichst klein werden. Ich dachte an nen Flash-Speicher in BGA9 
oder DFN8.


RAM habe ich 32kB zur Verfügung.

Zur Zeitdifferenz. Ich möchte 2 Sensoren abfragen, maximal 4 mal pro 
Minute. Die Zeit zwischen 2 Werten ist abhängig von dem Unterschied der 
Vorherigen Messwerte. Sprich, je größer der Unterschied ist, desto mehr 
Messwerte will ich haben. Ich werde warscheinlich weder sehr kleine noch 
sehr große Werte haben. Es geht also eher um die Auflösung/Genauigkeit. 
Da kam der Tipp, nur den Unterschied zu speichern, genau richtig.
Verlustbehaftet sollte die Kompression nicht sein. Es gibt kein Muster, 
wie z.B. ein Sinusähnlicher Verlauf.

von Oldie (Gast)


Lesenswert?

Erster Ansatz:
3 Bytes pro Messung: Zeitabstand  Änderung A  Änderung B

Verfeinerung:
Wenn du 4 Messungen/Minute machst, steht im ersten Byte
eine 15, für 15 Sekunden. Ist der größte Messabstand 60 s,
steht dort eine 60. Man kann sich bei anderen Messabständen
auch was anderes überlegen, was aber nur 6 Bit brauchen sollte.

Zeitabstands-Byte:
15 = 0b00001111
60 = 0b00111100
- Bleiben die 2 oberen Byte für die Situation, wenn die
Messwertänderungen nicht in ein Byte passen:

Zeitabstands-Byte = 10xxxxxx, wenn Änderung A 2 Byte belegt,
Zeitabstands-Byte = 01xxxxxx, wenn Änderung B 2 Byte belegt,
Zeitabstands-Byte = 11xxxxxx, wenn Änderung A und B 2 Byte belegen.
Es ergibt sich eine variable Länge der Aufzeichnung bei
großen Änderungen.

Vorteil:   Komprimiert die Daten
Nachteil: Der Datensatz ist nur von Anfang an lesbar.

Zu Beginn des Datensatzes müssen die Startzeit (32 Bit) und
die Startwerte von A und B (je 16 Bit) eingetragen werden.

von Horst (Gast)


Lesenswert?

Michael Skropski schrieb:
> Zur Zeitdifferenz. Ich möchte 2 Sensoren abfragen, maximal 4 mal pro
> Minute. Die Zeit zwischen 2 Werten ist abhängig von dem Unterschied der
> Vorherigen Messwerte.

Wenn der Abstand zwischen den Messwerten immer aus den vorherigen 
Messergebnissen berechnet wird, dann solltest du die Zeitstempel später 
am Computer mit einem Programm berechnen können. Das würde bedeuten, 
dass gar kein Zeitstempel gespeichert werden muss. (Höchstens den 
Zeitpunkt der ersten Messung.)

von S. K. (hauspapa)


Lesenswert?

EEProm  M95M01-DFCS6TP/K
1MBit, 8Ball BGA, 2.6X1.7mm, 1.8-5.5V, bei Digikey ab Lager für 2.5 EUR
Da würde ich über komprimieren garnicht erst nachdenken.

viel Erfolg
Hauspapa

von S. K. (hauspapa)


Lesenswert?

Micron hat auch noch ein 16Mb Flash im 2x2.8mm 8 Ball BGA. Kostet 1EUR.
Das sollte mindestens 2 Monate reichen.

Spansion bietet Dir ein 256Mb Flasch im besser lötbaren WDFN Gehäuse mit 
5x6mm. Das reicht für 3Euro mehrere Jahre.

Sprich: Der Speicher wird gemessen an der nötigen Energieversorgung 
nicht platzbestimmend.

Nur mal so auf die schnelle was Digikey gerade an Lager hat und in 
Einzelstückzahlen liefert.

fröhliches basteln
Hauspapa

von Kaj (Gast)


Lesenswert?

Michael Skropski schrieb:
> Je nachdem würde ich
> also den Unix-Zeitstempel oder einen String komprimieren. Eben das, was
> weniger Platz braucht bzw sich besser komprimieren lässt.

Zeitstempel kannst du in 4Byte stecken.
Beim Jahr kannst du die ersten zwei ziffer weglassen. Die Ziffern fuer 
Jahrtausend und Jahrhundert aender sich in absehbarer zeit nicht ;)
1
struct TIMESTAMP
2
{
3
  uint32_t Jahr    : 6; // nur die letzten 2 ziffern des Jahres speichern,
4
                        // reicht also bis zum Jahr (20)63
5
  uint32_t Monat   : 4;
6
  uint32_t Tag     : 5;
7
  uint32_t Stunde  : 5;
8
  uint32_t Minute  : 6;
9
  uint32_t Sekunde : 6;
10
}

gruesse

von Purzel H. (hacky)


Lesenswert?

Einen Zeitstempel braucht man nicht, denn wenn der Zeitabstand strikt 
mit der Steigung zusammenhaengt kann man den ja zurueckrechnen.

von Steffen R. (steffen_rose)


Lesenswert?

Ich denke, für die vielen Tipps fehlen noch Antworten/Randbedingungen 
aus den früheren Posts.

z.B. bleibt der Messwert lange Zeit stabil wurde vorgeschlagen, ihn 
nicht ständig zu speichern. Bedeutet aber auch, dass ein 
Zeitstempel/Zeitdifferenz gespeichert werden muss.

Oben wurde angemerkt, dass sich selten der Messwert sprunghaft ändert. 
Ist dies hier der Fall?

Wenn man Differenzen speichert, benötigt man eine Basis. Hier müßte man 
sich Gedanken machen, falls man mit wenig Flash auskommen will und 
plant, regelmäßig alte Daten zu überschreiben.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Michael Skropski schrieb:
> weniger Platz braucht bzw sich besser komprimieren lässt. Bei den
> Messwerten weiß ich aber nicht, wie man sie komprimieren könnte, da sie
> ja jeden beliebigen Wert annehmen können.
 Und da sich 2 Byte schlecht komprimieren lassen ist Vorschlag von
 Karl Heinz die beste Lösung.

Oldie schrieb:
> Erster Ansatz:
> 3 Bytes pro Messung: Zeitabstand  Änderung A  Änderung B
 Wir haben mal bei GPS-Aufzeichnungen sowas ähnliches gemacht, auch da
 ging zuerst KontrollByte, weil es natürlich Unsinn wäre, irgendwelche
 Daten aufzuschreiben, wenn Fahrzeug geparkt war.

Oldie schrieb:
> Zeitabstands-Byte:
> 15 = 0b00001111
> 60 = 0b00111100
 Und auch hier kann man mit Zeitabstand rechnen, 60 Sekunden werden
 wohl nicht gebraucht.

Oldie schrieb:
> - Bleiben die 2 oberen Byte für die Situation, wenn die
> Messwertänderungen nicht in ein Byte passen:
> Zeitabstands-Byte = 10xxxxxx, wenn Änderung A 2 Byte belegt,
> Zeitabstands-Byte = 01xxxxxx, wenn Änderung B 2 Byte belegt,
> Zeitabstands-Byte = 11xxxxxx, wenn Änderung A und B 2 Byte belegen.
> Es ergibt sich eine variable Länge der Aufzeichnung bei
> großen Änderungen.
>
> Vorteil:   Komprimiert die Daten
> Nachteil: Der Datensatz ist nur von Anfang an lesbar.
 Nichts zu verbessern an seinem Vorschlag, nur halt ein Bit mehr
 nehmen, Zeitabstand geht auf 5bit, also von 1 bis 31 Sekunden, Bit7
 für Zeitstempel nehmen.
 Also, wenn Bit7==0, Daten wie oben, wenn Bit7==1, handelt es sich um
 Zeitstempel, wenn Bits6-0==0, folgen 2Bytes mit Offset oder Datum,
 wenn Bits6-0 <> 0, stellt dieser Wert nur den Zeitabstand.
 So kann man die Messung laufen lassen und auf Veränderungen warten,
 wenn Zeitabstand größer 31Sec, kommt Zeitstempel, wenn nicht, kommt
 normale Aufzeichnung.

: Bearbeitet durch User
von Michael S. (rbs_phoenix)


Lesenswert?

Oldie schrieb:
> Erster Ansatz:
> 3 Bytes pro Messung: Zeitabstand  Änderung A  Änderung B
>
> Verfeinerung:
> Wenn du 4 Messungen/Minute machst, steht im ersten Byte
> eine 15, für 15 Sekunden. Ist der größte Messabstand 60 s,
> steht dort eine 60. Man kann sich bei anderen Messabständen
> auch was anderes überlegen, was aber nur 6 Bit brauchen sollte.
>
> Zeitabstands-Byte:
> 15 = 0b00001111
> 60 = 0b00111100
> - Bleiben die 2 oberen Byte für die Situation, wenn die
> Messwertänderungen nicht in ein Byte passen:
>
> Zeitabstands-Byte = 10xxxxxx, wenn Änderung A 2 Byte belegt,
> Zeitabstands-Byte = 01xxxxxx, wenn Änderung B 2 Byte belegt,
> Zeitabstands-Byte = 11xxxxxx, wenn Änderung A und B 2 Byte belegen.
> Es ergibt sich eine variable Länge der Aufzeichnung bei
> großen Änderungen.
>
> Vorteil:   Komprimiert die Daten
> Nachteil: Der Datensatz ist nur von Anfang an lesbar.
>
> Zu Beginn des Datensatzes müssen die Startzeit (32 Bit) und
> die Startwerte von A und B (je 16 Bit) eingetragen werden.

Der Nachteil stört mich nicht. Ist eine gute Idee, danke.


Horst schrieb:
> Michael Skropski schrieb:
>> Zur Zeitdifferenz. Ich möchte 2 Sensoren abfragen, maximal 4 mal pro
>> Minute. Die Zeit zwischen 2 Werten ist abhängig von dem Unterschied der
>> Vorherigen Messwerte.
>
> Wenn der Abstand zwischen den Messwerten immer aus den vorherigen
> Messergebnissen berechnet wird, dann solltest du die Zeitstempel später
> am Computer mit einem Programm berechnen können. Das würde bedeuten,
> dass gar kein Zeitstempel gespeichert werden muss. (Höchstens den
> Zeitpunkt der ersten Messung.)

Das ist auch wieder wahr. Doch dann kann ich ja nicht ins dt-Byte 
speichern, wieviele Byte das dx belegt. Diese Info könnte ich ja aber in 
das MSB vom Messwertbyte eintragen. Wenn 1, dann folgt noch ein Byte, 
wenn 0, dann nicht. Es wird keinen so großen Sprung geben, dass die 14 
bit nicht ausreichen würden... Ich denke, die Idee ist ganz gut, quasi 
ein Mix aus 1,2 Beiträgen.


S. K. schrieb:
> Micron hat auch noch ein 16Mb Flash im 2x2.8mm 8 Ball BGA. Kostet
> 1EUR.
> Das sollte mindestens 2 Monate reichen.
>
> Spansion bietet Dir ein 256Mb Flasch im besser lötbaren WDFN Gehäuse mit
> 5x6mm. Das reicht für 3Euro mehrere Jahre.
>
> Sprich: Der Speicher wird gemessen an der nötigen Energieversorgung
> nicht platzbestimmend.
>
> Nur mal so auf die schnelle was Digikey gerade an Lager hat und in
> Einzelstückzahlen liefert.
>
> fröhliches basteln
> Hauspapa

Der im BGA Gehäuse sieht echt interessant aus. Leider gibts den nicht 
bei Mouser. Ich hol mir kein 1€ Teil mit 18€ Versand. Aber einen 
DFN/WSON/... in 5x6mm gibts auch bei Mouser, der wirds dann denke ich 
werden. Es sei denn, jemand hier im Forum bietet so wie David für Mouser 
eine Dauer-Sammelbestellung mit Digikey an. Hab ich bisher aber noch 
nicht gesehen.


Siebzehn Zu Fuenfzehn schrieb:
> Einen Zeitstempel braucht man nicht, denn wenn der Zeitabstand
> strikt
> mit der Steigung zusammenhaengt kann man den ja zurueckrechnen.

Ja, das ist richtig. Daher: in den ersten x Bytes ist die Startzeit. 
Danach kommen ausschließlich Datenbytes, wo wie oben erklärt. Nach dem 
Auslesen werden alle Daten sowieso gelöscht.

Dankr für eure Hilfe. Ich bin davon ausgegangen, dass es da irgendeine 
Zauber-Lib gibt, wo ich die Daten einfach nur durchjagen muss, dass ich 
mir über sowas ansich krine Gedanken gemacht habe.

von S. K. (hauspapa)


Lesenswert?

>Der im BGA Gehäuse sieht echt interessant aus. Leider gibts den nicht
>bei Mouser.

Mouser Nr. 511-M95M01-DFCS6TP/K

und wenn man ein bischen sucht findet man in der EEProm und Flash Ecke 
noch mehr.

von gvs (Gast)


Lesenswert?

Das Problem würde bereits gelöst von verilog, nur der "Standard" ist 
leider auch von denen.
Das Nennt sich dann

Value Change Dump (VCD)

und wird auch im Zusammenhang mit VHDL und FPGA usw. verwendet. Daher 
gibt es auch Auswerteprogramme dafür (wenn es als Datei vorliegt).

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
Noch kein Account? Hier anmelden.