Hi! Meine Schaltung schreibt alle 4 Minuten Sensorwerte auf eine SD-Karte. Die Daten sollen nun von einem PC abgerufen werden, wobei die ältesten Messwerte, die am Anfang der Datei stehen, zu erst kommen sollen. Meine Idee ist, dass der PC die Daten anfordert und pro Anforderung eine Zeile aus der Logdatei übermittelt bekommt, die der PC dann bestätigt. Der Mikrocontroller soll nach der Bestätigung die Zeile löschen. Problem ist nun: Um am Anfang der Datei eine Zeile zu löschen, müsste ich die Datei ja jedes mal komplett neu schreiben, oder? Gruß, Chris
Hm, das ist schlecht. Welche Alternativen gibt es denn? Eventuell könnte ich in einer Variable speichern lassen, welche Zeile als letztes ausgelesen wurde und die komplette Datei löschen / leeren, sobald alle Zeilen übertragen wurden. Das würde zumindest die Schreibzugriffe reduzieren. In der Regel wird beim Abruf durch den PC die ganze Datei gelesen. Im Fehlerfall (Verbindung weg, PC abgestürzt usw.) würde der "Zeilenzeiger" halt stehen bleiben, so dass beim nächsten Abruf einfach fortgesetzt werden würde. Nur, wenn der Mikrocontroller resettet würde, wäre der Zeilenzeiger verloren und beim nächsten Lesen würde erneut die ganze Datei gelesen werden. Das ist aber auch kein Beinbruch. => Lösung gefunden:) Oder hat noch jemand eine bessere Idee?
Chris schrieb: > Hm, das ist schlecht. Welche Alternativen gibt es denn? Du könntest zb am Anfang jeder Zeile ein Sonderzeichen vorsehen, welches den Status der Zeile darstellt. '+' bedeutet: Zeile wurde noch nicht abgeholt '#' bedeutet: Zeile wurde bereits abgeholt und ist als gelöscht zu betrachten. Ab und an wird dann die Datei reorganisiert, indem bereits gelöschte Datensätze beim Umkopieren in ein neues File nicht mitgenommen werden. Ein bereits in einer Datei vorhandenes Zeichen durch ein anderes zu ersetzen, stellt auch in Textdateien kein Problem dar.
Du könntest auch z.B. - ohne Dateisystem anstatt einer Zeile jeweils einen Block schreiben - den Blöcken "Seriennummern" geben und laufend hochzählen - wenn die karte voll ist vorne wieder anfangen - den PC eine Startseriennumer beim Anfordern senden lassen - oder eine "Sammelquittung" für mehrere Datensätze schicken lassen und im EEprom speichern ... Bei jeder Zeile wieder auf die Karte zu schreiben halte ich für überflüssig.
Jede Messwertezeile als eigene Datei speichern? Die kann dann individuell gelöscht werden.
Was spricht dagegen, jedemal die ganze Datei an den PC zu übertragen und dann nach Quittierung die ganze Datei zu löschen? So ein "Einzelgefrickel" würde ich prinzipiell meiden. Das verursacht nur Overhead und macht die Sache unnötig kompliziert! Wie groß kann die Datei maximal werden? (Die soll hoffentlich nicht die ganze SD-Karte ausfüllen ;-) ) Wird während des Übertragens zum PC was in die Datei geschrieben?
Hi! Danke für die vielen Antworten! Im Moment landen in 4-Minuten-Intervallen rund 500 Bytes (!) in der Datei, + Zeilenumbruch). Das lässt sich aber sehr stark reduzieren da die Ausgabe im Moment Klartext ist und für die Ausgabe mit Excel gedacht ist. Am Ende werden es nur noch 150 Bytes sein, und selbst das kann reduziert werden wenn man nicht alles in Zahlen wandelt sondern das Byte direkt schreibt. Problem ist, dass das Auslesen der Karte recht lange dauern kann wenn sich dort z.B. ein halbes Jahr lang was angesammelt hat. Daher die Überlegung mit der häufigen Bestätigung. Dass das natürlich auch wieder stark bremst, ist klar. Die Datei kann "unendlich" groß werden, die SD-Karte hat aber nur 32MB, was reichen sollte. Eine Abfrage, ob der Speicher voll ist, steht auf der Todo-Liste. Während des Lesens muss außer ein paar ISRs nichts anders gemacht werden, es wird definitiv nicht auf die Karte geschrieben.
Schreib' dir doch einfach mehrere Dateien mit bspw. je 10 Zeilen. Dann kannst du jeweils eine der 10 Zeilen übertragen und als übertragen markieren und dann, wenn du alle zehn einer Datei übertragen hast, löschst du die Datei.
Wenn die Datei nur beim PC Absturz nicht vollständig gelesen wird und während dieser Zeit kein Schreiben vom MC erfolgt, dann würde ich dem PC beim Lesen ein Timout verpassen. Ist das Timeout überschritten wird die Datei reorganisiert = gelesenes gelöscht. Sonst wird die Datei nach dem vollständigen Lesen gelöscht. Wenn auch der MC Absturz abgefangen werden soll wirst du um ein Timestamp für jeden Datensatz im File und Überprüfung auf doppel Übertragung durch den PC nicht herum kommen. HG
Eine Datei und laufend anhängen, damit verbunden auch die FAT laufend aktualisieren und beim auslesen noch vorne abschneiden wollen ist definitiv Käse. Eine einzelne Datei, alle 4 Minuten erweitert und das ganze über ein halbes Jahr sind schon mal ca. 65.000 Schreibzugriffe auf den FAT-Eintrag. Das würd ich so niemals machen. Wear-Leveling hat auch irgendwann Grenzen. Mindestens jeden Tag/Woche gesondert, bringt aber Verwaltungsaufwand mit sich. Wie schon geschrieben: Geh auf die rohen Blocks. Je Datensatz ein Block mit laufender Seriennummer. Und dann quasi als Ringpuffer. Die Karte einmalig mit genullten Blocks initialisieren. Bei jedem Reset der Schaltung die letzte Seriennummer mittels "Halbierungstaktik" ermitteln (der letzte geschriebene Block ist der mit einer höheren Seriennummer als der darauffolgende). Den Startdatensatz fürs Auslesen je nach Gusto im EEprom speichern oder durch die Anwendung verwalten. Quittierung nicht nach jedem Datensatz, sondern vielleicht alle 500 (Schreibzugriffe EEprom). Das wird hinsichtlich Speicherbedarf und Datensicherheit das einfachste werden und es hat immer noch fast ein halbes Jahr auf den 32MB Platz.
Chris schrieb: > Im Moment landen in 4-Minuten-Intervallen rund 500 Bytes (!) in der > Datei, + Zeilenumbruch). Mir schwebt für die nächste Zukunft in einem Projekt etwas ähnliches vor. Da werde ich es wohl so machen, das die Datei einmal mit fester Größe erstellt (genullt?) wird, die dann als Ringpuffer mit 2 Zeigern (für lesen und schreiben) genutzt wird. Dann wird außer den Datensektoren nichts mehr beschrieben. Bei 500 Bytes würde ich sogar immer ganze Sektoren nutzen, das vereinfacht die Verwaltung noch einmal und hat noch den Vorteil, das bei einem Überlauf, die ältesten Daten überschrieben werden. Einen Zeitstempel sollten sie ohnehin haben. Einzige Frage wäre jetzt, wo die beiden Zeiger (persistent gegen Ausfälle) liegen, auf einem Sektor der Karte wäre ja auch tödlich. In meinem Prj werde ich evtl eine batteriegepufferte RTC haben, die dort befindlichen RAM-Zellen sind der fast ideale Platz dafür. Wenn normaler RAM genutzt wird, der beim Init genullt wird, würde dann immer mit leerem Puffer begonnen werden. mfG ingo
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.