EEPROM schreiben und lesen

Hallo,

ich möchte auf einem Wemos D1 mini Daten dauerhaft speichern und lesen. Mein Testsketch dazu funktioniert jedoch nicht. Ich finde den Fehler nicht :frowning: Wert lesen: 0

#include <EEPROM.h>

int Schreibwert = 478; //the int to write to EEPROM
int Lesewert = 0;

void setup() {
  Serial.begin(9600);

  EEPROM.write(7, highByte(Schreibwert)); //write the first half
  EEPROM.write(8, lowByte(Schreibwert)); //write the second half

  Serial.print("Wert geschrieben: ");
  Serial.println(Schreibwert);
  Serial.println();
}

void loop() {
  
  byte high = EEPROM.read(7); //read the first half
  byte low = EEPROM.read(8); //read the second half
 
  Lesewert = (high << 8) + low; //reconstruct the integer
  Serial.print("Wert lesen: ");
  Serial.println(Lesewert);
  Serial.println();
  delay(10000);
    
  }

Tequilamixer:
Mein Testsketch dazu funktioniert jedoch nicht.

„Funktioniert nicht“ ist keine sonderlich hilfreiche Fehlerbeschreibung.

Was erwartest Du? Was passiert stattdessen? Erscheinen Fehlermeldungen?

Gruß

Gregor

sorry.

Zu Beginn soll der Wert 478 zerlegt und in 2 Byte geschrieben werden.

Diese 2 Byte werden danach wieder gelesen, zusammengesetzt und seriell ausgegeben.

Dabei erscheint leider der Wert 0.

Hi

Funktionieren die Funktionen highByte und lowByte korrekt?
Ich vermisse diverse Serial.print, um dem Problem auf die Spur kommen zu können.
Auch sollte statt WRITE eher UPDATE genommen werden, da WRITE ein explizieten Schreibzugriff bedeutet und so ein EEprom nicht ewig lebt.

MfG

Hallo,

beim ESP kommt im Setup die Größenfestlegung mit EEPROM.begin(Zahl); Zahl z.B. 10

nach den EEPROM-schreiben noch EEPROM.commit(); zum speichern.

@TO: Du solltest Dir mal die Methoden put und get anschauen. Die können beliebige Daten schreiben/lesen.

Gruß Tommy

ja mit EEPROM.begin(10); funktioniert es nun :slight_smile:

Was bewirkt EEPROM.commit() dann? Was passiert, wenn man den Befehl weg lässt?

Brauche ich bei put und get die int-Variable nicht zerlegen?

Zu put und get:

Nicht als Link, Das könntest Du vll. sogar selber hinbekommen ...

das .commit() findet zumindest meine Suchmaschine nicht direkt bei Arduino, sondern eher bei ESP.

MfG

Tequilamixer:
ja mit EEPROM.begin(10); funktioniert es nun :slight_smile:

Wirklich? Auch wenn Du die Spannung wegnimmst und neu startest? Sind die Daten dann noch da?

Hier kommt nämlich der commit ins Spiel. Die Daten werden zunächst nur in einem bei 'begin' angelegten Schatten-RAM gespeichert. Erst mit commit werden sie in den nichtfüchtigen flash umkopiert ( ein echtes EEPROM hat der esp8266 nicht )

Tequilamixer:
Was bewirkt EEPROM.commit() dann? Was passiert, wenn man den Befehl weg lässt?

Frag mal google, der weiß es genau, ich meine dass dann erst die Daten gespeichert werden da der ESP eigentlich kein echtes EEPROM hat. Und wenn es weglässt geht es halt nicht - das merkst dann wenn gespeicherte Wert nach einem !Neustart! lesen möchtest.
Was möchtest denn letztendlich speichern? Zahlen, Charakters, Strings?
Ich mache einfach aus allem Strings und speichere die dann Zeichen für Zeichen ins EEPROM mit put. Ob ich dabei ein paar Byte mehr oder weniger brauche ist mir eher egal....

Richtig: ohne EEPROM.commit() ist beim nächsten Start wieder alles weg, mit commit() ist die Variable dauerhaft vorhanden.

Und Richtig: mit EEPROM.get und put lassen sich größere Variablen speichern

PS: Mir fallen viele Anwendungen ein. Bei meiner Balkonbewässerung soll der eingestellte Intervall zur Bewässerung nach einem unabsichtlichen Neustart (Stromausfall, ...) wieder geladen wird. Oder die Statistik für meinen Lichtschalter (wie oft über Echo geschaltet wurde) nicht verloren geht und z.B. 1 mal pro Tag gespeichert wird.

Du hast aber im Hinterkopf, dass die Anzahl der Schreibzyklen begrenzt ist?

Gruß Tommy

Bei 100.000 Zyklen kann ich 270 Jahre einmal am Tag die Statistik abspeichern, den Bewässerungsintervall ändere ich noch seltener.

int Schreibwert = 478; 

EEPROM.write(7, highByte(Schreibwert)); //write the first half
EEPROM.write(8, lowByte(Schreibwert)); //write the second half

Erstens:
Ich verstehe was es werden soll!
Es wird aber nix.
Da ein int auf dem ESP 32Bit(4Byte) breit ist.

Zweitens:
Die händische Adressberechnung ist Fehler trächtig.
Diese könnte/sollte man dem Compiler überlassen.
Der ist meist sorgfältiger als ein Mensch.

Tequilamixer:
Bei 100.000 Zyklen kann ich 270 Jahre einmal am Tag die Statistik abspeichern, den Bewässerungsintervall ändere ich noch seltener.

Na prima. Solche Sachen kannst Du ausrechnen, aber für eine ordentliche Fehlerbeschreibung und für eine Erwähnung der Tatsache, dass Du noch nicht einmal einen Arduino benutzt, bist Du zu blöd?!
Sauber.

s. #18

gregorss:
….und für eine Erwähnung der Tatsache, dass Du noch nicht einmal einen Arduino benutzt, bist Du zu blöd?!

Sauber.

Das ist genau der Ton den ich hier oftmals sehr unpassend finde.
Und wer zu blöd ist richtig zu lesen (1. Post: ich möchte auf einem Wemos D1 mini Daten dauerhaft speichern und lesen) sollte mit solchen Bemerkungen vorsichtig sein. Oder musst du nur die Anzahl deiner Postings erhöhen?

@ uk1408: Danke, ganz meiner Meinung :slight_smile:

@ combie: Wie kann ich dem Compiler die Adressierung meiner Variable überlassen? Und wenn EEPROM.put(0,INT_VarA) 4 Byte belegt, darf ich die 2. Variable dann erst ab EEPROM.put(4,INT_VarB) schreiben?

Und wenn EEPROM.put(0,INT_VarA) 4 Byte belegt, darf ich die 2. Variable dann erst ab EEPROM.put(4,INT_VarB) schreiben?

Das fragst du doch jetzt nicht wirklich, oder?
Manno...

Wie kann ich dem Compiler die Adressierung meiner Variable überlassen?

In dem du deine Daten, die im virtuellen EEPROM landen sollen, in einer Struktur zusammenfasst.
offsetof() zeigt dir die Position in der Struktur.

struct PersistenteDaten
{
  int anzahl;
  float spannung;
} __attribute((__packed__));



// anzahl aus dem EEPROM lesen
int anz;
EEPROM.get(offsetof(PersistenteDaten,anzahl),anz);


// ganze Struktur aus dem EEPROM lesen
PersistenteDaten daten;
EEPROM.get(0,daten);

ungetestet

Schreiben geht natürlich äquvalent.

Wofür __attribute((packed)) gut ist, und ob du es benötigst darfst du selber herausfinden.
Aber Vorsicht, es besteht die Gefahr, dass du dabei was lernst.

Tipp:
Beim lernen der Sprache, welche du verwendest, würden dir dieses ganzen Dinge von selber ins Hirn hüpfen.
Ich rate dir zu einem schönen, dicken+fetten und modernem C++ Buch.

uk1408:
Das ist genau der Ton den ich hier oftmals sehr unpassend finde.
Und wer zu blöd ist richtig zu lesen (1. Post: ich möchte auf einem Wemos D1 mini Daten dauerhaft speichern und lesen) sollte mit solchen Bemerkungen vorsichtig sein. Oder musst du nur die Anzahl deiner Postings erhöhen?

Uh. Shit. Da habe ich mich ja mal ordentlich zum Deppen gemacht. Entschuldigung.

Gruß

Gregor