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.
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
Michael Skropski schrieb: > PS: Ist das Unterforum "Projekte und Code" nur zum veröffentlichen > besagter Dinge genau dafür ist es gedacht.
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.
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.
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.
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.
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.
@ 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.
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.
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.
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.)
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
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
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
Einen Zeitstempel braucht man nicht, denn wenn der Zeitabstand strikt mit der Steigung zusammenhaengt kann man den ja zurueckrechnen.
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.
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
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.
>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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.