SD libary - Zeichen löschen

Hallo zusammen,

Ich bin Johann und programmiere schon etwas länger mit dem Arduino. Zurzeit möchte ich mit einem Datenloggermodul Daten speichern und wenn sie gebraucht und verwertet werden diese Einträge wieder löschen. Meine Datenstruktur in der CSV Datei sieht wie folgt aus:

20210528,1159,580,3
20210528,1200,640,4
20210528,1201,200,2
.
.
.

Jetzt will ich z.B. die oberste Zeile zuerst einlesen, was ich schon mit der SD-libary geschafft habe, und anschließend die Zeile löschen, sodass alle weiteren Zeilen einen hoch rutschen. Das wiederholt sich dann solange bis die Datenbank leer ist.

Hier mein bisheriger Versuch:

void rm_logData() {
File latest_file = SD.open(file, O_RDWR);
if (latest_file) {
for (int i=0; i <= log_payload.length() + 4; i++) {
latest_file.seek (i);
latest_file.print(" ");
}
latest_file.close();
Serial.println("rm " + log_payload);
}
else {
Serial.println("Fehler beim öffnen");
}
}

An anderer Stelle lese ich die erste Zeile der Datei aus und Speichere ihn als String in log_payload. In der for Schleife habe ich dann herausgefunden, wenn ich dessen Länge mit vier addiere die ganze Zeile anspreche, da die weiteren vier Zeichen \n oder andere Merkmale sind. Ich kann das nun wie im Beispiel mit einem Leerzeichen überschreiben aber dann steht die überschriebene Zeile halt immer noch da, halt nur mit Leerzeichen. Ersetze ich latest_file.print(" "); mit latest_file.print(""); dann passiert gar nichts...

Vielen Dank im Vorraus

Gruß Johann

datei0 öffnen
neue/leere datei1 zum anfügen öffnen
erste Zeile aus datei 0 lesen (und ignorieren)
zweite Zeile aus datei 0 lesen und als erste zeile in die datei1 schreiben
die weiteren Zeilen aus datei0 in die datei1 "kopieren"
datei0 schließen,
datei1 schließen
datei0 löschen
datei1 auf datei0 umbennen

wenn du Code postest dann bitte in Code tags.
Wenn du nicht weist was Code tags sind - lies in der Erklärung vom Forum nach, wie man die setzt.

Idealerweise zeigst du ein vollständiges Beispiel - so klein wie möglich.
Dann können die Leute das in ihrer IDE nachzubauen und du brauchst dich nicht mit PseudoCode auseinandersetzen und bekommst vieleicht fast fertige Lösungen zurück.
Mit Codefetzen bekommst eben nur Hinweise wie man es machen kann.

Vielen Dank noiasca,

das mit den Code tags werde ich zukünftig berücksichtigen.

spreichere ich alle Zeilen bis auf die erste aus der ersten zeile in einer Variable zwischen und wenn ja wie oder kann man zwei Dateien parallel öffnen bearbeiten?

Gruß Johann

zum Zwischenspeichern im SRAM wirst zu wenig haben, hingegen zwei Dateien sollten öffenbar sein.

https://www.google.com/search?client=firefox-b-d&q=arduino+sd+card+open+multiple+files

ok danke,

ich probiere das dann erstmal aus

Zwei Dateien gleichzeitig öffnen kostet auch RAM. Und Dateien sind nun mal keine Datenbank, sondern werden sequentiell gelesen.

Warum können nicht einfach alle Sätze deiner csv - Datei "verwertet" werden?
Und diese danach komplett löschen?

So verhält sich eine Datei leider nicht. Daher der vorgeschlagene Umweg über die zweite Datei als Kopie der ersten ab Zeile 2. Besser du startest woanders bei der Überlegung, was du eigentlich willst.

das Szenario ist eigentlich nicht ungewöhnlich.
Angenommen du willst in der Datei die "letzten" 10.000 Einträge haben, dann fällt "am Anfang" der älteste Eintrag raus und am "unteren" Ende kommt der neueste Eintrag hinzu.

Das kann man doch viel eleganter mit einer Art Ringpuffer lösen

Für solche Aufgaben wurden Ringpuffer erfunden.
Speziell um zu vermeiden, dass jedesmal alles umkopiert werden muss.

Oft ist es effektiver, sich zu merken, was/wieweit bereits gelesen wurde, statt es zu löschen oder mit Leerzeichen zu überschreiben.

Ich erzähl euch mal von meinem Projekt, sodass wir dann besser über die Umsetzung urteilen können.
Ich habe ein Windrad was produzierten Strom und Umdrehungen für je eine Minute misst. Das wird dann zu einem Datensatz zusammengefasst und mit einem Funkmodul an einen Raspi geschickt, der das dann in einer Datenbank speichert und auf einer Webseite graphisch darstellt. Der Arduino erwartet immer eine Bestätigung des Raspis ob der Datensatz überhaupt angekommen ist und die Verbindung steht. Bekommt er die Bestätigung nicht wird der Datensatz auf dem Datenlogger gespeichert (Datenlogger mit sieben Dateien für die vergangene Woche, Daten für einen Tag werden in der selben Datei gespeichert). Sofern Datensätze auf dem Logger sind, also ältere Datensätze, die noch nicht verschickt wurden, priorisiert er die und speichert alle neuen Datensätze auch auf dem Logger bis er alles verschicken konnte.

Ich dachte, dass ich am einfachsten immer nur die nicht verschickten Daten auf der Datenbank habe um von oben weg zu lesen.

Gruß Johann und Danke für die vielen Antworten

Das verstehe ich jetzt nicht. Das Funkmodul schickt an den Raspi. Woher weiß der Arduino dann die Daten?
Falls der die Sendung mit hört, hast Du mal getestet, ob der Fall, dass der Raspi nichts empfängt überhaupt auftritt?

Gruß Tommy

Das Funkmodul ist ein RF24 und praktisch eine Ergänzung zum Arduino von dem aus der Arduino die Daten schickt. dann gebe ich ihm ein paar millisec auf Antwort zu warten und wenn nichts kommt wird geloggt.
Der Fall tritt auf wenn die Verbindung mal nicht stabil ist aber auch wenn ich das Windrad mal unabhängig vom Raspi betreiben will und anschließen die Daten transferierenlasse.
Aber das ist ein anderes Thema und soll hier nicht besprochen werden.

LG Johann

Habe ich volles Verständnis für!
Ändert aber nichts daran, dass man am Anfang von Dateien nix raus schneiden kann.

Du wirst das akzeptieren müssen und einen anderen Weg finden dürfen.
z.B. den Index der zuletzt gesendeten Zeile merken.

Die eierlegende Wollmilchsau geht meistens daneben.
Nimm ein klar definiertes Szenario. Die lokale Verbindung funktioniert in der Regel problemlos. Wenn Du doch mal 1 Satz pro Jahr verlierst, ist das auch kein Problem. Mit dem Rest holst Du Dir mehr Probleme rein, als Lösungen oder Du musst einen völlig anderen Ansatz, z.B. Ringpuffer im FRAM anpeilen. Ohne Raspi wird aber trotzdem nichts, weil keiner die Daten speichert.

Gruß Tommy

Ich versteht das als "Store And Forward" Zwischenspeicher. Schau dir an, ob du jeden nicht übertragenen Satz als separate Datei ablegen kannst. Das könnte die Sache noch einfacher machen.

Das geht nicht.

  • öffne Datei
  • Lese Zeile1
  • lösche Zeile1
    --> Und jetzt:
    Wenn Du die Zeile1 löscht, dann möchtest Du im nächsten Durchlauf, das die (vor dem löschen!) Zeile2 zur Zeile1 wird.
    Den Inhalt der Datei müsstes also temporär umkopieren.

Das führt unweigerlich dazu:
-Datei öffnen
-Zeile1 lesen und vergleichen
-Datei ab Zeile2 neu schreiben.
-Alte Datei löschen - temporaere Datei umbenennen
-beginne von Vorn