Sd auslesen, letzte xx Zeilen (Datenlogger)

Hallo zusammen,
Ich habe einen Datenlogger geschrieben der mir ca alle 15 min die Zeit in sec. + 4 sensorwerte (analog in) mit "," getrennt jeweils zusammen in eine Zeile schreibt. Jetzt würde ich die Daten gerne Zeilenweise wieder auslesen, aber immer nur die aktuellsten (letzten) 10 Stück. Vorwärts oder rückwärts ist egal.
Ist das machbar?

Genutzt wird der Arduino Mega mit spi.h und sd.h

Vielen Dank & Grüße,
Matthias

Meine Idee: gibt den Daten noch einen aufsteigenden Index mit, dann bestimmst Du den größten und kannst bequem die letzten 10 dann identifizieren.
Letztlich ist natürlich der Timestamp auch sowas wie ein eindeutiger Index, aber damit würde ich mich schwerer tun (bin halt auch Amateur).

Danke, einen Index oder Timestamp zu nutzen hab ich gar nicht auf dem Schirm gehabt.
Alternativ ist mir auch noch eingefallen könnte ich die Daten parallel in ein 2D Arry schreiben und mit schleifen immer eine Zeile weiter schieben bevor der nächste Satz Daten kommt.
Dann wird's weiterverarbeiten auch einfacher

red81:
Jetzt würde ich die Daten gerne Zeilenweise wieder auslesen, aber immer nur die aktuellsten (letzten) 10 Stück. Vorwärts oder rückwärts ist egal.
Ist das machbar?

Warum sollte das nicht machbar sein?

Am einfachsten wäre es machbar, wenn alle Zeilen der LOG-Datei immer gleich lang wären.
Also z.B. jede Log-Zeile immer 78 Zeichen + CR + LF als Zeilenendezeichen, macht 80 Zeichen pro Zeile.

Dann würdest Du die Dateigröße auslesen, mit SD - Arduino Reference auf Dateigröße minus 800 positionieren und anfangen zu lesen.

file.seek(file.size()-800); // oder so ähnlich

Wenn alle Zeilen in der Logdatei unterschiedlich lang sind, wird das komplizierter. Dann würdest Du einen Zeilenpuffer benötigen, der größer ist als die längste Logzeile und könntest dann nach dieser Logik vorgehen:

file.seek(file.size()-sizeof(linebuf));

dann den Puffer einlesen und durchzählen, wieviele Zeilenende-Zeichen enthalten sind.
Falls weniger als 10:

file.seek(file.size()-2*sizeof(linebuf));

dann den Puffer einlesen und weiter durchzählen, wieviele Zeilenende-Zeichen enthalten sind.
etc. bis mindestens 10 Zeilenendezeichen am Dateiende erkannt wurden.
Falls mehr als 10 gelesen wurden, nun im Puffer so weit vorgehen, bis exakt das 10. Zeilenende Zeichen erreicht ist. Ab dem nächsten Zeichen beginnt dann die zehntletzte Zeile.

Andere Programmlogik, die aber meistens viel länger dauern dürfte:

  • Datei öffnen, alle Zeilen durchzählen, Datei schließen
  • Datei öffnen und bis Anzahl Zeilen minus 10 durchlesen
  • auch dann ist man bei der zehntletzten Zeile

Viele Wege führen nach Rom.

Man auch zwei Durchläufe machen. Erst mal die Anzahl der Zeilen bestimmen. Und dann ab einer bestimmten Zeile lesen.

Oder die Anzahl der Zeilen in die erste Zeile schreiben. Dazu kann man eine Zahl auf konstant z.B. 4 Ziffern breite formatieren.

Ich habe dazu folgende Ideen, ohne das jetzt aber direkt programmieren zu können.

  1. Du merkst Dir die letzten zehn Sensor-Werte. Ggf. über ein zweidimensionales Array, bei dem die erste Stelle 0-9 der Index ist, die zweite Stelle dann das Set mit den Sensordaten
  2. Du produzierst einfach eine zweite Datei, in der immer nur die letzten 10 Zeilen gespeichert werden. Dann brauchst Du diese eigentlich immer nur vollständig auszulesen, wohingegen die eigentliche Logdatei wachsen kann. Auf einer SD sollte ja genug Platz sein :slight_smile:

LG TConnect

Vielen Dank für eure Ansätze!
Ich hab mich jetzt fürs 2D Arry entschieden,
Erst werden die Werte mit 2 for Schleifen jeweils eine Zeile nach unten geschoben und dann die neuen Werte in die erste Zeile geschoben.
So kann ich die Daten als Pixelpositionen direkt auf TFT zeigen und erhalte ein schönes Verlaufsdiagramm.
Danke Euch!

... Mal sehen ob das Arry vielleicht auf die SD ausgelagert werden kann. :slight_smile: