ich werfe hier mal eine eher algorithmische Frage in die Runde:
Ich habe mir mit einem ESP32, L76X, ePaper und einem SD card Modul einen GPS-Tracker gebastelt bzw. ich bin dabei.
Ist alles noch early stage, PCB ist auch noch in Arbeit, aber soweit funktioniert er erstmal grundsätzlich und speichert brav die gewünschten GPS-Daten auf der SD Karte als CSV.
So weit so gut. Nun würde ich die Daten aber gerne auch als GPX-Datei speichern um sie - später auf dem Rechner - direkt in einer Karte zu zeigen. Für die die GPX nicht kennen, das Dateiformat ist im Prinzip wie eine XML-Datei gestrickt.
Ein vereinfachtes Beispiel mit 2 Trackpoints:
1
<gpx>
2
<trk>
3
<trkpt lat=\"0.0000"\" lon=\"0.00000\">" </trkpt>
4
<trkpt lat=\"1.0000"\" lon=\"2.00000\">" </trkpt>
5
</trk>
6
</gpx>
Nun ist es so, dass der Tracker einfach logged sobald er Strom bekommt (USB-Powerbank). Es gibt keinen Schalter oder Knopf zum Starten und/oder Stoppen. Keep it simple eben.
Das Problem ist nun, dass die Datei - um gültig zu sein - immer die entsprechenden "Closing-Tags" braucht, also im o.g. Beispiel die letzten 2 Zeilen. Die muss man aber erst anhängen, wenn der letzte Trackpoint eingefügt und die Datei 'fertig' ist.
Das Ende einer Datei wird aber nie geschrieben, wenn man einfach den Stecker zieht. Die trkpt-Zeilen werden einfach in unendlichen Loop zeileweise angehängt.
Das Problem sollte eigentlich nicht neu sein. Insbesondere da es auf alle XLM-strukturierten Dateiformate zutrifft. Daher hoffe ich, dass ich einfach noch etwas übersehe und hier vielleicht jemand eine Idee hat.
Bisherige Möglichkeiten die ich sehe:
CSV auf dem Tracker und GPX später daraus mit einem Script erstellen (mit Python simple) => Doof, weil ich auf der SDcard direkt GPX zum anschauen haben will.
Bei jedem Loop, die existierende Datei ohne die Closing-Tags in eine Temp-Datei kopieren, den nächsten trkpt anhängen, und mit Closing-Tag versehen wieder zurück kopieren. => Wird mühsam wenn die Datei grösser wird (zB mehrere Monate in einer Datei), auch eine Speicherfrage irgendwann. Zudem viel Geschreibe auf der SD im Hinblick auf die Lebensdauer. ABER, damit könnte man jeder Zeit den Stecker ziehen und die Datei sollte i.O, sein.
Immer nur den den Header und die trkpt schreiben, ohne Closing-Tag, und dann bei jedem Boot bei der "vorherigen" oder "letzten GPX-Datei" die Closing-Tags anhängen. => Minimaler Aufwand da man einfach wie bei CSV immer die Zeile anhängt, aber die letzte Datei auf der SDcard wäre immer "korrupt" - bis zum nächsten Boot. Irgendwie auch doof.
Oder eben einen Knopf dran und damit "Close-File" signalisieren bevor man den Stecker zieht. => Rettet einen Fall von Powerloss auch nicht. Sehe ich eher als Wörkaround.
Ich habe nun schon eine Weile rumgeschaut, aber so die "beste Lösung" suche ich noch. Fallen noch jemandem andere denkbare Optionen ein?
Bin für jeden Input dankbar. Wie löst man sowas???
Nach dem jeweils ersten Anlegen der Datei am Ende etliche kByte Spaces anhängen, gefolgt vom XML-Dateiende.
Dann werden die folgenden Zeilen immer auf die Spaces geschrieben, wenn die letzte Zeile dann keinen Platz mehr hätte, wird diese dennoch geschrieben und wieder etliche kB Spaces angehangen und ein neuer Schluß.
Sinnvoll ist hierbei auf die Blockgröße des Dateisystems zu achten. Weiterhin sinnvoll wäre es, nicht jede Zeile gleich zu schreiben, sondern 10 oder 20 Zeilen in einem Rutsch, weniger Zeilen nur, wenn seit einer gewissen Zeit keine neuen Zeilen dazukommen. Klar steigt hierbei das Risiko, die letzten Zeilen u.U. zu verlieren, die Lebensdauer eine Speicherkarte dankt es aber.
Wenn ich dich richtig verstehe, dann meinst Du man soll zum Beispiel sowas hier machen:
1
<gpx>
2
<trk>
3
<trkpt lat=\"0.0000"\" lon=\"0.00000\">" </trkpt>
4
5
... hier ganz viele Leerzeilen ...
6
7
</trk>
8
</gpx>
und dann die nächsten trkpt-Zeilen in die "Leerzeilen schreiben",...
Von der Logik bin ich bei Dir, aber das funktioniert mMn nicht mit einem SD card Modul. Da fehlen die Datei-Informationen zu. Sprich, man kann nicht ohne eine Komplettkopie der Datei etwas an Zeile X einfügen.
Und mit einer Kopie wären wir wieder bei o.g. Option 2.
Zumindest ist das soweit mein Verständnis der Problematik.
Lasse mich aber natürlich gerne eines Besseren belehren.
Brownout-Detection und ausreichend großen Pufferelko, um beim Stromausfall die Datei in einem sauberen Zustand zu hinterlassen.
Wenn beim ESP32 das WLAN nicht aktiv ist (wozu sollte das bei einem GPS-Tracker auch gut sein?), sollte man den Stromverbrauch davon ja irgendwie in Grenzen halten können. Dazu kommt der Strombedarf der SD-Karte.
Die ESP32 gibt es auch mit Batterie Lade und Überwachungchip, z.B.
LilyGo t-Beam.
Danke Rüdiger.
Ich weiss. Habe sogar USB-Lademodule und kleine LiPos hier, aber das ist nicht die Idee.
PowerOn => Tracken/Loggen
PowerOff => Aus
Aber ich gebe zu, Dein Vorschlag würde es immerhin ermöglichen die Spannung zu monitoren und dann "kurz vor Ende" die Closing-Tags zu schreiben. Andererseits, dann braucht es auch einen Knopf, denn mit einer internen Batterie logged der ja weiter bis die Leer ist, auch wenn ich die Powerbank abziehe.
Ich sehe das mal als eine "extended Version" von o.g. Option 4 mit dem Knopf. ;)
Es gibt noch die Strategie "Safe-on-powerloss". Elko einbauen der so groß ist, dass er so viel Zeit überbrücken kann, wie der Controller braucht, den gezogenen Stecker zu detektieren und die Abschlusszeile zu schreiben.
Du darfst einer SD Karte eh nicht einfach die Stromversorgung kappen, während sie aktiv ist. Das Risiko für Datenverlust wäre enorm hoch. Du brauchst einen Pufferakku, so eine Art USV, um kontrolliert runter fahren zu können.
Brownout-Detection und ausreichend großen Pufferelko, um beim
Stromausfall die Datei in einem sauberen Zustand zu hinterlassen.
Wenn beim ESP32 das WLAN nicht aktiv ist (wozu sollte das bei einem
GPS-Tracker auch gut sein?), sollte man den Stromverbrauch davon ja
irgendwie in Grenzen halten können. Dazu kommt der Strombedarf der
SD-Karte.
Harald, Danke! Das klingt nach einer Idee.
Eine Art mini-USV nur zum Dateiabschluss wenn Strom weg.
Momentan benutze ich weder Bluetooth not Wifi (aber wer weiss).
Ich vermute momentan wird das GPS-Modul wohl am meisten weglutschen.
Generell finde ich Deinen Vorschlag - zumindest ist der Theorie - nicht uninteressant. Schauen ob Spannungsversorgung weg ist, und dann zusehen, dass man in dem Fall noch genug Energie (=Zeit) hat die Datei zu schliessen. Genau das ist ja alles was es braucht.
Ist "Brownout-Detection" einen Fachbegriff dafür?? Noch nie gehört. Ich schau mal...
Es gibt noch die Strategie "Safe-on-powerloss". Elko einbauen der so
groß ist, dass er so viel Zeit überbrücken kann, wie der Controller
braucht, den gezogenen Stecker zu detektieren und die Abschlusszeile zu
schreiben.
Hey Uwe, Danke.
Damit bist Du auf der selben Spur wie Harald. ;)
Wenn das schon von 2 Quellen kommt, dann muss ich mir das wohl man genauer anschauen. Die Idee an sich finde ich in der Theorie jedenfalls überzeugend.
Irgendwelche lesenswerte Empfehlungen zu so einer Schaltung? Hier oder im Netz?
Du darfst einer SD Karte eh nicht einfach die Stromversorgung kappen,
während sie aktiv ist. Das Risiko für Datenverlust wäre enorm hoch. Du
brauchst einen Pufferakku, so eine Art USV, um kontrolliert runter
fahren zu können.
Ja, da gebe ich Dir Recht. In der Theorie hat man das Risiko.
Aber ich logge alle 15 Sekunden, und bisher habe ich noch nie (wirklich noch NIE) den kurzen Moment getroffen wo gerade die eine Zeile angehängt wird. Habs noch nicht gemessen, aber ich vermute das Fenster wird im Bereich von ms sein.
Läufst du bei rot über die Ampel, so lange du Glück hast?
Geräte die nur mit Glück funktionieren, machen irgendwann übel Ärger.
Ja, ich gebe zu: Robustiness habe ich bisher noch nicht berücksichtigt.
Hatte offensichtlich die letzten Jahre dann immer sehr viel Glück. Bisher ist mein Tracker immer gut über die rote Ampel gekommen. ;)
Habe bis vor einigen Monaten noch meine erste Version auf Basis eines RPi Zero genutzt um beim Segeln zu tracken. Ja, mit Linux ist nochmal was anderes, aber auch da war es so eingerichtet, dass man einfach Strom dran macht, Linux bootet und anfängt zu loggen. Und aus ging einfach mit "Strom weg". Mag Linux auch nicht unbedingt, aber das OS hat das immer gut weggesteckt.
Anyway. Du hast schon Recht. Und ich finde die Idee mit der Elko-USV zum sauberen Shutdown durchaus sympathisch. Ich hoffe ich finde da was für den Anfang.
Die löst einen Reset aus, wenn die Stromversorgung zu niedrig ist
Das ist eine Möglichkeit davon, aber es gibt auch die Möglichkeit, einen Interrupt auszulösen. Der ESP32 kann das. Bei dem kann auch der Spannungspegel konfiguriert werden.
Die löst einen Reset aus, wenn die Stromversorgung zu niedrig ist
Das ist eine Möglichkeit davon, aber es gibt auch die Möglichkeit, einen
Interrupt auszulösen. Der ESP32 kann das. Bei dem kann auch der
Spannungspegel konfiguriert werden.
Ja, einen IRQ zum Spannungsüberwachung nutzen klingt logisch. Irgendwas muss man ja eh zum Triggern des "sauberen Shutdown" nutzen.
Ich muss mir generell erstmal einen überblick verschaffen wie der Elko dimensioniert sein muss. Ich hab hier noch ein paar Monster-Elkos, aber die sind eher aus dem Bereich >50V, also eher ungeeignet.
Ich schlage Soft-Power On und Off vor, wie beim Telefon. Also ein Taster, der das Gerät ein- und ausschaltet. Beim Ausschalten alles abschliessen, SD-Karte abmelden und dann in den Powerdown gehen.
Wie wichtig sind die GPX Datensätze, ist es verschmerzbar, wenn z.B. immer die letzten 5 Datensätze nicht aufgezeichnet sind aber trotzdem die Datei richtig abgeschlossen ist?
Mein Gesanke (noch nicht vollständig durchdacht) :
Du schreibst mit jedem Datensatz auch das Dateiende. Mit dem nächsten Datensatz überschreibst du das Dateiende und hängst es neu an. Ich hoffe das ist verständlich wie ich das meine. Oder dieses Vorgehen erweitern, so dass immer ein ganzer Sektor / Cluster auf die SD-Karte geschrieben wird. Es wird aber immer das Dateiende geschrieben und mit dem nächsten Schreibvorgang überschrieben und neu angehängt. Der Spannungswegfall müsste trotzdem dedektiert werden und ein gerade laufender Schreibvorgang beendet werden.
Ich schlage Soft-Power On und Off vor, wie beim Telefon. Also ein
Taster, der das Gerät ein- und ausschaltet. Beim Ausschalten alles
abschliessen, SD-Karte abmelden und dann in den Powerdown gehen.
Hallo Matthias,
stimmt. Das wäre noch eine Variante mit dem Knopf.
Das liesse sich auch relativ einfach umsetzen ohne Elko-USV. Dann würde es wirklich nur noch im Falle einen "unerwarteten Powerloss" (i.e. Powerbank leer) zu korrupten Dateien kommen.
Also die Garmins von vor 20 Jahren konnten sowas schon problemlos. Denen konnte man im laufenden Betrieb die Batterien rausziehen, trotzdem war der GPX-Track intakt.
Meine Vermutung: sie haben immer eine syntaktisch korrekte XML-Datei geschrieben auf die Karte. Wenn ein Datensatz angehängt werden sollte, sind sie die paar Bytes der letzten schließenden Klammern zurück gegangen und haben ab dort neu geschrieben, dann aber wieder mit dem kompletten Ende der Datei.
Das Problem sollte eigentlich nicht neu sein. Insbesondere da es auf
alle XLM-strukturierten Dateiformate zutrifft. Daher hoffe ich, dass ich
einfach noch etwas übersehe und hier vielleicht jemand eine Idee hat.
Ist es auch nicht.
Schreibe hinter einen trkpt-Record immer den Abschluss für trk und gpx.
Bevor du den nächsten trkpt-Record schreibt, positionierst du den Schreib-Pointer vor das Closing-Tag "</trk>".
Wie wichtig sind die GPX Datensätze, ist es verschmerzbar, wenn z.B.
immer die letzten 5 Datensätze nicht aufgezeichnet sind aber trotzdem
die Datei richtig abgeschlossen ist?
Das Problem sollte eigentlich nicht neu sein. Insbesondere da es auf
alle XLM-strukturierten Dateiformate zutrifft. Daher hoffe ich, dass ich
einfach noch etwas übersehe und hier vielleicht jemand eine Idee hat.
Ist es auch nicht.
Schreibe hinter einen trkpt-Record immer den Abschluss für trk und gpx.
Bevor du den nächsten trkpt-Record schreibt, positionierst du den
Schreib-Pointer vor das Closing-Tag "</trk>".
Unter Linux, mit den entsprechenden Tools ist das klar.
Aber mit nem ESP32 auf ner SD card geht "Einfügen in/nach Zeile X" mMn nur indem man die bestehende Datei kopiert. Siehe oben Option 2.
Also die Garmins von vor 20 Jahren konnten sowas schon problemlos. Denen
konnte man im laufenden Betrieb die Batterien rausziehen, trotzdem war
der GPX-Track intakt.
Meine Vermutung: sie haben immer eine syntaktisch korrekte XML-Datei
geschrieben auf die Karte. Wenn ein Datensatz angehängt werden sollte,
sind sie die paar Bytes der letzten schließenden Klammern zurück
gegangen und haben ab dort neu geschrieben, dann aber wieder mit dem
kompletten Ende der Datei.
Ja, logisch ist das einfach zu realisieren in dem man die Datei beim "anhängen" eines neuen Datenpunktes stets kopiert. Rein logisch lässt sich das lösen. Aber eben zu Lasten der Schreibzyklen der SD card.
Den Elko-Mini-USV-Ansatz finde ich schon attraktiv. Aber ist auch deutlich mehr Aufwand. Ähnliches liesse sich sicherlich auch mit nem LiPo realisieren...
Eventuell sollte ich auch einfach mal überschlagen wie lange man eine SD card so malträtieren muss, dass sie die Grätsche macht. Alle paar Jahre mal ne neue SD Card wäre dann auch nicht so tragisch.
Aber mit nem ESP32 auf ner SD card geht "Einfügen in/nach Zeile X"
Welches Betriebssystem verwaltet Dateien nach Zeilennummer?
Schreibpointer zeigen auf Byte Positionen. Die Datei muss dazu gewöhnlich als Binärdatei mit random Zugriff geöffnet sein.
Beziehungsweise nach dem Schreiben der letzten "richtigen" Daten ein ftell(), dann die schließenden Klammern schreiben, und bei den nächsten Daten wieder zum vorigen Punkt zurück.
Ja, logisch ist das einfach zu realisieren in dem man die Datei beim
"anhängen" eines neuen Datenpunktes stets kopiert.
Das werden die Garmins ganz gewiss nicht gemacht haben. Schon deshalb, weil dann ja bei einem langen Track die SD-Karte riskiert hätte voll zu sein. Damals zählten SD-Karten noch nach 1 oder 2 GB – für die 4er Karten brauchte man schon einen Firmwareupgrade.
Wieviel RAM hast du denn?
Hier die nächste Idee: Im RAM eine komplette Kopie der GPX Datei halten und per Blockwrite die aktuelle Kopie auf die Karte schreiben.
Damals zählten SD-Karten noch nach 1 oder 2 GB – für die 4er
Karten brauchte man schon einen Firmwareupgrade.
Bist du sicher, dass sie nicht nach 128ern MB gezählt wurden?
Ja, denn schließlich war ja das Kartenmaterial mit drauf. Die 2 GB wurden dann schon ziemlich schnell zu knapp, sodass man die Firmwareerweiterung benötigte für 4 GB (eigentlich ein Bugfix, weil davor offenbar beim Einlegen einer 4er Karte eine negative Zahl als Größe ermittelt worden ist). Ziemlich schnell wuchsen die OSM-Daten dann volumenmäßig so weit an, dass man für diese älteren Garmins abgespeckte OSM-Daten produziert hat, die noch in 4 GB passten.
Trotzdem hätte sich in dieser Zeit natürlich keiner erlaubt, ganze Dateien auf einer SD-Karte umzukopieren, nur um einen Datensatz anzuhängen.
ESP32-C6FH4 as the main chip, with RISC-V 32-bit single-core processor,
support up to 160 MHz, and built-in 320KB ROM, 512KB HP SRAM
Wenn wirklich nur alle 15 Sekunden ein Wegpunkt geschrieben wird, passen die Daten¹ von knapp 3 Tagen bis 1 Woche ins RAM. Da müsste es doch möglich sein, die komplette Datei in einem Stück zu schreiben. Oder wie lange muss man ununterbrochen loggen? Die Lebensdauer der SD-Karte würde sich vervielfachen.
Oder kann man GPX-Dateien nachträglich aneinander hängen? Dann könnte man mehrere kleinere Dateien jeweils am Stück schreiben.
Länge und Breite passen sehr gut in 32 Bit, dazu evt. ein 32-Bit Zeitstempel plus ganz vielleicht noch Statusbits, Akkuspannung usw.
Ja, sowas hatte ich auch gehofft, aber bisher hat meine Recherche
ergeben, dass man immer Kopieren muss.
ftell() und fseek() gibt es schon seit Äonen in C. Wo hast du denn recherchiert? Relative Suche zum Dateiende kann auf manchen Plattformen ggf. nicht funktionieren (wenn die Plattform nämlich im Textmode aus jedem "\n" noch ein CR-LF machen möchte), aber absolute Suche (also SEEK_SET zum Dateianfang) sollte überall machbar sein. Daher der Hinweis, sich die Position, bei der man im nächsten Schritt weiterschreiben möchte, mit ftell() zu merken.
Danke für den Schubs! Da haben wir das nötige Buzzword!
Correct me if I'm wrong:
fseek() ist scheinbar was ich suche, allerdings für plain C.
Ich benutze die Arduino IDE für die ESP-Programmierung, daher habe ich die entsprechenden libs SD.h und SPI.h eingebunden.
Momentan ist mein Denkansatz folgender (PseudoCode):
1
#define CLOSING_TAG_BYTES 15
2
3
File file = fs.open(gpxDateiName, FILE_APPEND);
4
file.seek(file.size()-CLOSING_TAG_BYTES);
5
file.print(trackpointDatenMitClosingTags);
Also, CLOSING_TAG_BYTES muss der Anzahl Bytes entsprechen die die Closing-Tags verbrauchen (15 ist hier nur als Beispiel zu verstehen). Dann mit file.seek() vom Ende zurück zählen um den Pointer an die richtige Stelle zu brinegn, und dann an der Stelle den nächsten Trackpoint samt ALLER Closing-Tags schreiben. Man überschreibt dann jedes mal einfach die Closing-Tags.
Ich muss das jetzt mal ausprobieren ob das auch in der Praxis so hinhaut wie ich das im Kopf hab.
ESP32-C6FH4 as the main chip, with RISC-V 32-bit single-core processor,
support up to 160 MHz, and built-in 320KB ROM, 512KB HP SRAM
Wenn wirklich nur alle 15 Sekunden ein Wegpunkt geschrieben wird, passen
die Daten¹ von knapp 3 Tagen bis 1 Woche ins RAM. Da müsste es doch
möglich sein, die komplette Datei in einem Stück zu schreiben. Oder wie
lange muss man ununterbrochen loggen? Die Lebensdauer der SD-Karte würde
sich vervielfachen.
Oder kann man GPX-Dateien nachträglich aneinander hängen? Dann könnte
man mehrere kleinere Dateien jeweils am Stück schreiben.
Länge und Breite passen sehr gut in 32 Bit, dazu evt. ein 32-Bit
Zeitstempel plus ganz vielleicht noch Statusbits, Akkuspannung usw.
Danke für den Denkanstoss. Unter der Annahme, es gäbe keinen unerwarteten Powerloss wäre das definitiv der beste Weg. Insbesondere wenn man auf die SD Karte achten will.
Bei Powerloss hat man dann aber eben auch maximalen Datenverlust wenn noch alles im RAM war.
Dateien stückeln hatte ich ehrlicherweise auch schon dran gedacht. Geht auch tatsächlich problemlos was das Loggen angeht. Aber dann hab ich eben keine GPX-Datei mit dem ganzen Track auf der SD card liegen.
(Soll später entweder einfach in ein Tablet oder PC, oder sogar Cloud mit GPX-Viewer.)
Sprich, da wäre auch wieder nachträgliches Skripten nötig.
Ja, sowas hatte ich auch gehofft, aber bisher hat meine Recherche
ergeben, dass man immer Kopieren muss.
ftell() und fseek() gibt es schon seit Äonen in C. Wo hast du denn
recherchiert? Relative Suche zum Dateiende kann auf manchen Plattformen
ggf. nicht funktionieren (wenn die Plattform nämlich im Textmode aus
jedem "\n" noch ein CR-LF machen möchte), aber absolute Suche (also
SEEK_SET zum Dateianfang) sollte überall machbar sein. Daher der
Hinweis, sich die Position, bei der man im nächsten Schritt
weiterschreiben möchte, mit ftell() zu merken.
Bin scheinbar in den falschen Ecken des Interwebs gelandet. Zugegeben, hatte immer nach einem ESP- oder Arduino IDE/lib-Zusammenhang geschaut.
Ist schon über ne Dekade her, dass ich mal was seriös mit C/C++ gemacht habe. (Arduino zähle ich da unfairerweise nicht wirklich dazu.) Aber als ich fseek() las da hat was geklingelt. Muss jetzt nur mal zusehen wie das in der entsprechenden SD-library implementiert ist, die ist wohl nicht ganz so mächtig wie das was man auf anderen Plattformen zur Verfügung hat. Ich nehme an ftell() ist dann ein INT, da wo der Pointer grade steht, richtig? Wäre vielleicht sogar besser als mein "Bytes zurück zählen"...
Ich nehme an ftell() ist dann ein INT, da wo der Pointer grade steht,
richtig?
Offiziell ist es (aus eher historischen Gründen) ein long, denn auch fseek() nimmt einen long für den Offset – in der Zeit, in der C entstanden ist, konnte man mit einem long halt mehr an Dateigröße abdecken als mit einem int, und vorzeichenbehaftet muss es sein, weil fseek() ja auch vom Dateiende mit negativen Werten hantieren kann.
Klasse! Ich liebe dieses Forum!
Danke für die Denkanstösse, Unterstützung und so weiter. Auf dieses Forum ist Verlass. :)
Ich mach mich dann mal ran zu schauen wie weit ich damit komme.
EDIT/UPDATE:
So, an der Stelle noch eine kurze aber essentielle Info, da ich daran gerade fast verzweifelt bin:
Beispiel: Datei wird mit 5 Zeichen (ABCDE) initialisiert.
Dann:
1
File file = fs.open(gpxDateiName, FILE_APPEND);
2
file.seek(2);
3
file.print("X");
aber das X wird immer am Ende angehängt. Nach file.seek(2) kann man sogar file.position() aufrufen und via Serial ausgeben (ist auch 2). Aber, file.print() schreibt immer ans Ende. Man bekommt: ABCDEX
Nun, Lösung ist statt FILE_APPEND, die Datei mit FILE_WRITE öffnen.
Also:
1
File file = fs.open(gpxDateiName, FILE_WRITE);
2
file.seek(2);
3
file.print("X");
Dann bekommt man: ABX
Das Ende wird also scheinbar gestripped, aber so kann man scheinbar an einer definierten Position schreiben. Was ja gewünscht war.
Wollte dieses wichtige Detail, FILE_WRITE statt FILE_APPEND mit seek() verwenden, nicht unterschlagen, falls nochmal jemand hier reinschaut.
Bei Powerloss hat man dann aber eben auch maximalen Datenverlust wenn
noch alles im RAM war.
Wieso denn? Die Datei im RAM zu haben bedeutet ja nicht, das du sie nicht regelmässig (z.B. jede Minute) als Block auf die SD Karte schreiben kannst. Die Datei auf der Karte ist dann auf jeden Fall valide.
Das kann ein Timer zünden. Wenn du eine Woche oder so voll hast, startest du dann eine neue Datei, ehe der RAM knapp wird. So sparst du dir auch die aufwendigen File Operationen mit ihren Eigenarten.
Ich habe das nun, wie oben vorgeschlagen, via seek() auf die Datei gelöst.
Für ESP32 in der Arduino IDE die FS.h, SD.h und SPI.h includen, und dann mit
1
file.seek(POINTER);
2
file.print("Text der an dieser Stelle eingefügt wird.")
den Zeiger zum schreiben an die richtige Stelle (POINTER ist dann eine Zahl, zB 12) bringen um dann dorthin zu schreiben.
Ferner kann man mit
1
file.position();
an der richtigen Stelle die Pointerposition wegschreiben um dort später wieder zu schreiben.
Ich muss damit zwar jedes Mal die Closing-Tags mitschreiben, aber das nehme ich hin.
ERGO: Problem ist damit für mich gelöst. VIELEN DANK!
PS: Die Idee mit der Mini-ELKO-USV habe ich aber noch im Hinterkopf. Falls ich jemals einen Powerloss in den paar ms habe wo ich grade ein Log geschrieben habe, dann bau ich das ein. Lernen durch Schmerz (=Datenverlust).
Bis dahin, viel Spass.
Ich muss damit zwar jedes Mal die Closing-Tags mitschreiben, aber das
nehme ich hin.
Klaro, das ist das Prinzip dabei.
Ich habe mich damals auch gefragt, wie sie das bei dem Garmin geschafft haben, wird aber das gleiche Prinzip gewesen sein. Ich habe jedenfalls bei dem Teil nie eine korrupte GPX-Datei erlebt.
So groß sind die 1-F-Elkos aus einem alten Fahrrad-Rücklicht nun auch
wieder nicht.
Was mich auf den Gedanken bringt, dass man bei diesen hoch-kapazitiven Elkos auf die Stromstärke achten muss. Manche liefern und laden nur einstellige mA. Die anderen will man wahrscheinlich mit einer Strombegrenzung laden.