ESP - Struct Array in Spiffs speichern und laden

Trotz sehr langer Suche habe ich (auch aufgrund mangelnden Hintergrundwissens) keine Lösung für meine Fragestellung gefunden:

Ich habe in einem Sketch folgendes struct definiert:

struct Tabelle {
  char *         buch;      
  uint16_t      speed;     
  uint16_t      pause;
  };


Tabelle  catalog[] =  { 
{"abcd", 1 , 2},
{"efgh", 3 , 4},
{"ijkl", 5 , 6}
};

Nun möchte ich nichts anderes tun, als dieses struct in eine txt Datei im SPIFFSbereich des ESP8266 zu kopieren und auch umgekehrt - also den (richtig strukturierten) Inhalt einer txt Datei auf den SPIFFS in mein struct zu kopieren.

Hintergrund: Der Ablauf meines Programms wird durch die Parameter in der Tabelle bestimmt. Ich möchte diesen Ablauf recht simpel ändern können, indem ich einfach einen neue TXT-Datei in die SPIFFS hochlade und deren Inhalt in meine ursprüngliche Tabelle lade.

Prinzipiell ist mir die Sache mit den SPIFFS klar; ich habe auch schon eine SPIFFSverwaltung am Laufen; ebenfalls sollte es mir möglich sein, eine HTML-Seite via Webeserver aufzusetzen, mit der ich das Laden aus der txt Datei dann anstoßen könnte.

Für die eigentliche Funktion, das Laden und Speichern aus bzw. in die Datei auf den SPIFFS, fehlt mir aber leider das Wissen und ich habe auch nichts für mich hinreichend Verständliches gefunden.

Ich würde mich freuen, wenn Ihr mir weiterhelfen könntet.

Ich würde mich freuen, wenn Ihr mir weiterhelfen könntet.

Wills wohl versuchen...

Eigentlich kein Problem Strukturen zu speichern....

Aber im Moment frage ich mich, was wohl mit dem Zeiger passieren soll?
Tücken drohen.

char[] und char* sind sehr eng verwandt, aber wenn du Strings so abspeichern willst, brauchst du ersteres. Ansonsten hast du nur einen Zeiger, aber keinen Text

ich würde das interne struct von der externen Darstellung in einem .txt trennen.

z.B. im .txt zeilenorganisiert speichern

abcd, 1 , 2
efgh, 3 , 4
ijkl, 5 , 6

Zeilenweise einlesen,
bei Komma teilen (strtok) (evtl. ein anderes Trennzeichen verwenden, wenn Komma im buch vorkommen darf,
die Werte beim einlesen in den jeweiligen Variablen lesen

Danke für Eure Antworten!

Ja, ich kann natürlich char[] statt char* verwenden. Ich habe, ehrlich gesagt, den Unterschied jetzt erst verstanden. (Btw: Wenn ich es richtig verstanden habe, sind für ein char[] array mindestens 8 bit Speicher reserviert, oder?)

Auch der Vorschlag, einfach die Inhalte zeilenweise einzulesen, wäre machbar, wenn es gar nicht anders ginge, würde mich aber der Flexibiltät der berauben, die Anzahl der Elemente zu verändern. Das wäre also eher eine Notlösung.

Wäre meine Idee dann also mit char[] machbar und wie würde so eine Funktion aussehen?

(Btw: Wenn ich es richtig verstanden habe, sind für ein char[] array mindestens 8 bit Speicher reserviert, oder?)

Du bist der Programmierer, du musst die Größe bestimmen.

Das wäre:
Maximale Buchstabenanzahl, plus 1 für das Stringende/Nullbyte

Amiga:
Auch der Vorschlag, einfach die Inhalte zeilenweise einzulesen, wäre machbar, wenn es gar nicht anders ginge, würde mich aber der Flexibiltät der berauben, die Anzahl der Elemente zu verändern. Das wäre also eher eine Notlösung.

Wenn Du die Anzahl der Elemente nur durch editieren der Datei verändern willst, musst Du die Elemente dynamisch erzeugen, weil sie sonst nicht in eine feste Struktur passen.
Das wäre nochmal eine Schwierigkeitsstufe höher. Überlege sehr genau, ob Du das wirklich brauchst oder nur für alle Fälle gern hättest. Machbar wäre es.

Gruß Tommy

musst Du die Elemente dynamisch erzeugen,

machbar bestimmt. Würde ich mir aber auch nicht antun wollen.

aber wenn ich noch mal das lese:

Ich möchte diesen Ablauf recht simpel ändern können

Warum dann den Umweg mit einer extern editierbaren Datei?
Da mach ich doch eine HTML Seite zum konfigurieren.
Von mir aus inkl. Import aus einer Textdatei und einen Export in eine Textdatei wenn man ein "Backup" seiner Einstellungen will...

Da mach ich doch eine HTML Seite zum konfigurieren.
Von mir aus inkl. Import aus einer Textdatei und einen Export in eine Textdatei wenn man ein "Backup" seiner Einstellungen will...

Klar, das ist natürlich eine Option. Es muss nicht zwangslaüfig eine txt-Datei sein.

Tommy56:
Wenn Du die Anzahl der Elemente nur durch editieren der Datei verändern willst, musst Du die Elemente dynamisch erzeugen, weil sie sonst nicht in eine feste Struktur passen.
Das wäre nochmal eine Schwierigkeitsstufe höher. Überlege sehr genau, ob Du das wirklich brauchst oder nur für alle Fälle gern hättest. Machbar wäre es.

@Tommy56
Dynamisch, muss es nicht unbedingt sein.
Ich habe mir mal genauer Dein Weihnachsstern-Programm angeschaut, wo Du ja auch das config struct via SPIFFS verändern kannst. Ich habe auch versucht, daraus etwas für meinen Zweck zu basteln, bin mangels tieferer Kenntnis der Materie aber nicht weitergekommen.

Folgende, jetzt angepassete Definiton:

struct Tabelle {
  char[200]    buch;     
  uint16_t      speed;     
  uint16_t      pause;
  };


Tabelle  catalog[] =  {
{"abcd", 1 , 2},
{"efgh", 3 , 4},
{"ijkl", 5 , 6}
};

Mal angenommen, ich will den struct inhalt von "Tabelle catalog[]" , also in ein HTML-Formular laden, so dass im Formular auf der HTML-Seite steht:

{"abcd", 1 , 2}, 
{"efgh", 3 , 4}, 
{"ijkl", 5 , 6}

Danach möchte ich die geänderten Werte in "Tabelle catalog[] zurückschreiben. Wie müssen dann die Funktionen f.read() und f.write() lauten - oder brauche ich eine Copy-Funktion? Wie gesagt, den HTML-Teil traue ich mir zu; was ich bräuchte sind die Schreib- und Lesefunktionen für die SPIFFS.

Beim Weihnachtsstern ist die Länge des Arrays aber konstant. Wenn da ein Satz hinzu kommt, muss das erst im Code geändert werden, dann die neue Struktur gespeichert und dann kann man damit arbeiten.
Zum Speichern und Einlesen brauchst Du doch nur die Funktionen aus der _config.ino. Dabei ist die printConfig eigentlich nur zum Debuggen.

Zum Schreiben der Website handleRoot() und zum Lesen handleSetProg(), natürlich incl. der Javascript-Teile. Die Bezeichnungen (Texte) sind bei mir in der Website nicht änderbar. Wenn das bei Dir sein soll, brauchst Du noch ein zusätzliches ID-Feld, das konstant bleibt, um den Satz wieder zu finden.

Der Weg über die einzelnen Buttons wurde gewählt, da das hauptsächlich zum Tuning der Animationen dient. Man kann natürlich auch mit einem Buttom immer alles senden.

Gruß Tommy

Wie müssen dann die Funktionen f.read() und f.write() lauten

write und read!

size_t write(const uint8_t *buf, size_t size) override;
 size_t read(uint8_t* buf, size_t size);

aus Quellle