habe gerade folgendes Problem:
Ich möchte ins EEprom die Konfiguration einer kleinen Steuerung schreiben.
Darin befindet sich auch ein StringObject mit max 32 Zeichen, den ich über HTML einlese.
Ich habe jetzt gesehen, dass es da die EEpromAnything Routine gibt:
#include <EEPROM.h>
#include "EEPROMAnything.h"
struct config_t
{
long alarm;
int mode;
} configuration;
void setup()
{
EEPROM_readAnything(0, configuration);
// ...
}
void loop()
{
// let the user adjust their alarm settings
// let the user adjust their mode settings
// ...
// if they push the "Save" button, save their configuration
if (digitalRead(13) == HIGH)
EEPROM_writeAnything(0, configuration);
}
Das mit der Struktur und dem Lesen und Schreiben derselben in einem Rutsch wäre genau das was ich suche.
Allerdings ..... kann ich in der struct auch einen String definieren?
Woher weiss ich beim lesen, wie lang der beim Schreiben war?
Wenn du maximal 32 Zeichen hast kannst du auch ein char Array der Länge 33 nehmen. Dann kann es natürlich vorkommen dass bei kurzen Strings mehr geschrieben wird, aber String Objekte haben auch 6 Bytes Overhead (1 Zeiger und jeweils ein Integer für Länge und Größe)
Woher weiss ich beim lesen, wie lang der beim Schreiben war?
length(). Es wird das gesamte Objekt im EEPROM gespeichert. Also auch die Länge des Strings
OK,
das Schreiben/Lesen des charArrays soll mit einer Schleife 1-32 byteweise kein Problem sein.
Oder soll ich das Terminierungszeichen auch noch ins EEprom schreiben?
In diesem Fall mal ja. Das macht nämlich intern auch nur strncpy(). Ansonsten müsstest du selbst c_str() (für Lese-Zugriff auf das interne Array) und strncpy() (oder besser strlcpy()) zum Kopieren verwenden.
Früher gab es nichts anderes als toCharArray(). Inzwischen gibt es c_str() für Lese-Zugriff, aber es wird in vielen Beispielen immer noch unnötigerweise toCharArray() verwenden, auch wenn man gar keine Kopie braucht. Hier willst du aber eine.
Oder soll ich das Terminierungszeichen auch noch ins EEprom schreiben?
Ja! Auf jeden Fall. Deshalb soll das Array ja 33 Zeichen haben.
Ach ja, und für C Strings bekommst du die Länge natürlich mit strlen(). length() wäre für eine String Objekt.
Im Prinzip würde aber beides gehen. Du kannst wirklich alles mögliche ins EEPROM schreiben (weil das eine Template Funktion ist kann die mit allen Datentypen umgehen, inklusive selbst definierten). Und ein struct kann auch beliebige Datentypen enthalten.
Serenifly:
.... weil das eine Template Funktion ist .....
Die EEPROMAnything Funktion meinst du, oder?
Auf alle Fälle müsste ich mir mit der Funktion keine Gedanken über die Startadressen der einzelnen Strukturelemente im EEprom machen. Nur über die Startadresse der Struktur.
Wie es bei den Beispielen von get() und put() aussieht, können die ja auch mit einer Struktur arbeiten.
Bei update() bin ich mir nicht sicher, da das Beispiel nur eine float schreibt.
Werde mal testen, ob es mit einem StringObjekt in der Struktur auch geht.
Edit:
exit status 1
no matching function for call to 'EEPROMClass::update(int, config_t&)'
Also mit StringObject geht es anscheinend auch. Wenn ich die Reset-Taste am Arduino drücke, lese ich immer den String aus dem vorherigen Durchlauf aus dem EEPROM
Allerdings hab ich noch das Problem, dass wenn ich das erste Mal im noch nicht beschriebenen Bereich lese, mir der Arduino abschmiert
Erst nachdem ich den Bereich einmal beschrieben habe, läuft es.
Anscheinend kann er keinen String aus dem undefinierten EEPROM Inhalt machen.
Kann man das irgendwie abfangen?
Hier mein TestCode:
Wobei ich mir da nicht wirklich sicher bin, was er ins EEPROM schreibt.
Wenn ich mir das EEPROM byteweise auslese, dann stehen in den ersten 10Byte immer die selben Werte drin. Egal welchen Inhalt der String hat.
Ich glaub ich arbeite doch lieber mit charArrays.
Da weiss ich was ich hab, und wo was steht...
Wobei, wenn ich mal darüber nachdenke...geht das mit einem String Objekt wirklich? Das Objekt verwaltet ja nur einen Zeiger auf dynamischen Speicher (+ 2 ints für die Größe und Kapazität des Arrays). Und es wird erstmal nur der Zeiger abgespeichert. Der eigentliche String steht dann weiter im RAM...
Kann gut sein dass das doch nur mit C Strings geht.
Die erzeugte EEP Datei kann, wenn es gewünscht wird, per Hand, ins EEProm geladen werden. Arduino macht das leider, oder zum Glück, nicht automatisch.
Wenn die Struktur geändert wird, sollte die Versionskonstante um einen erhöht werden. Das vermeidet das lesen von Schrottdaten und erleichtert die Inbetriebnahme.