Problem mit EEPROM beschreiben

  • Guten Abend

    Herzlichen Dank für Eures Feedback. Der Code funktioniert nun :)

    Folgende drei Dinge habe ich geändert:


    - #define EESIZE 1024

    - geändert auf EEPROM.read und EEPROM.write

    - delay(100) nach EEPROM.write


    Schöner Abend Euch allen.

    Grüsse

    Felix

  • Bei aller Spekulation lässt sich sagen, dass @kukuks ursprünglich geposteter Codeschnipsel funktionieren müsste. Ich habe es mit einem Arduino Nano Clone ohne Problem nachvollziehen können.


    Darum habe ich darum gebeten den kompletten Code zu posten, um erkennen zu können, ob sich wirklich alles nur in der setup() Funktion abspielt oder es vielleicht nur ein Ausgabeproblem ist (z.B. Gültigkeitsbereich von Variablen o.ä.). So ganz wurde das leider wieder nicht gemacht.


    Ich habe den Verdacht, dass vielleicht schon in der Loop() Funktion mit dem EEPRom Befehl herum probiert wurde und deshalb die Speicherzelle schon „verbraucht“ ist.


    Am besten das Ganze mal an einer anderen Adresse probieren, die noch nicht verwendet wurde. Also nicht „0“.

  • Sinnvollerweise schreibt man Daten nur direkt ins EEPROM, wenn man sicher ist, dass das nur selten vorkommt denn da spielt der Faktor Zeit dann eine untergeordnete Rolle, also speichert man die Daten im RAM und kopiert sie nur in grösseren Zeitabständen ins EEPROM oder wenn die Versorgungsspannung ausfällt. In letzterem Fall ist eine Pufferschaltung schon ein must-have.

    EEPROM's haben auch ein Problem mit der Lebensdauer (100k Zyklen je Zelle hört sich erst mal viel an aber bei write alle 1 sec ist nach 1,5 Tagen die Zelle obsolet). Da bietet sich vielleicht doch besser ein NVRAM Shield an.


  • Ich habe mal kurz in die EEPROM Sourcen geschaut. Ja ich weiss, es gibt vermutlich unterschiedliche Sourcen dazu.

    Dabei sehe ich nichts, das auf eine zeitliche Sicherstellung der Funktionen hindeutet. Vor allem die write Funktion scheint mir da kritisch, wenn man nach dem Schreiben nicht 3.3 mS (diese Zeit wird zumindest beschrieben) abwartet, bevor man erneut auf das EEPROM zugreift.

    Daher ist der Vorschlag von Reiner mit dem delay(100) nach der Schreiboperation zielführend. Wie René beschrieben hat, ist beim Schreiben von Typen mit einer Grösse über ein Byte vermutlich eine Wartezeit nach jedem Byte notwendig.

  • Hi Felix,

    dein letzter Code kann nicht funktionieren.

    So muss das aussehen ...

  • Vielen Dank René und dem ganzen Forum.

    Ich bin Neuling in der Arduino Programmierung. Bis jetzt war es immer meine eigenen Bugs dass es nicht klappte ;)

    Ich bleibe dran.


    Herzlichen Dank

    Grüsse

    Felix

  • Hallo Felix


    So richtig ist mir auch nicht klar, wieso es nicht geht.

    Du kannst entweder mit write() / read() oder mit put() / get() arbeiten. Mischen solltest Du es nicht.


    write() und read() arbeiten immer mit exakt 1 Byte.

    Ich verwendet normalerweise aber put() und get(). Dabei hängt die Anzahl geschriebener oder gelesener Bytes von der Variablen ab. Sie muss also zwingend vom selben Typ sein.

    Ein Beispiel:

    Code
    1. void setup() {
    2. Serial.begin(9600);
    3. byte speichern = 5;
    4. byte lesen;
    5. EEPROM.put(0, speichern);
    6. delay(100);
    7. EEPROM.get(0, lesen);
    8. Serial.println(lesen);
    9. }

    Das sollte eigentlich funktioniere, ich habe es aber nicht getestet.

    Eine etwas ausführlichere Erklärung findest Du in Lektion 24 meiner Videoreihe zum Arduino oder im Dokument Zusammenfassung Programmierung.


    Gruss

    René

  • Guten Abend

    Vielen Dank für Eure Ideen. Trotzdem komme ich nicht weiter :(


    In der Setup() Routine setzte ich zu Testzwecken den Mode=2. Ich schreibe den Wert in das EEPROM und lese diesen Speicherplatz zu Testzwecken wieder aus. Nun erwarte ich, dass die korrekten LED für den Mode2 angehen. Wie gesagt, ist ein Testprogramm. Das Problem ist, dass häufig mal die falschen

    Mode-LED leuchten.


    Eigentlich wollte ich mit Serial.println(Mode) den Mode zur Kontrolle auslesen. Was ich nicht verstehe ist, wieso der Serial Monitor häufig nix ausgibt. Ja, ich habe mit Serial.begin(9600); vorgängig initialisiert ;)


    Hier zum Testcode:



    Mode=2;

    EEPROM.put(0,Mode);

    delay(100);

    Mode = EEPROM.read(0); // letzter gewählter Mode auslesen

    Serial.println(Mode);


    if ((Mode !=1) && (Mode !=2) && (Mode !=3)); { Mode =1;} //falls Vodoo initial im Speicherplatz steht


    if (Mode == 1) { // Mode 1

    digitalWrite(Pin_LED_Mode1, HIGH);

    digitalWrite(Pin_LED_Mode2, LOW);

    digitalWrite(Pin_LED_Mode3, LOW);

    }


    if (Mode == 2) { // Mode 2

    digitalWrite(Pin_LED_Mode1, LOW);

    digitalWrite(Pin_LED_Mode2, HIGH);

    digitalWrite(Pin_LED_Mode3, LOW);

    }


    if (Mode == 3) { // Mode 3

    digitalWrite(Pin_LED_Mode1, LOW);

    digitalWrite(Pin_LED_Mode2, LOW);

    digitalWrite(Pin_LED_Mode3, HIGH);

    }




    Herzlichen Dank für Tipps.

    Grüsse

    Felix

  • Code
    1. byte Mode =1; // Mode soll 1 sein
    2. EEPROM.put(0,2); // writes data on EEPROM using also the EEPROM.update() that writes data only if it is different from the          // previous content of the locations to be written.
    3. // hier wird an der Adresse 0 der Wert 2 geschrieben
    4. Mode = EEPROM.read(0); // lesen von der Adresse 0 ??
    5. // =====================================================================
    6. // Du meintest wohl:
    7. EEPROM.put(0, Mode); // den Inhalt von Mode auf Adresse 0 updaden
    8. Mode = EEPROM.read(0); // lesen von der Adresse 0, da ist Mode abgelegt

    Ich denke das reicht Dir so und natürlich, Zeit lassen, die Zugriffe aufs EEPROM sind langsam,

    Gruss

    Pius

  • Probiere mal

    Beachte bitte, dass EEPROM braucht ein wenig Zeit zum schreiben (3.3 ms)

    Code
    1. EEPROM.write(0, 2);
    2. EEPROM.read(0);
  • Geschätztes Forum


    Mir ist es wirklich ein Rätsel wieso das EEPROM des UNO R3 einen simplen Wert sich nicht merken will ;)

    Ich schreibe an Adresse 0 den Wert "2" und erwarte, dass ich den selben Wert wieder beim Auslesen erhalte.

    Funktioniert aber nicht :(

    Was mache ich falsch?


    Besten Dank.

    Grüsse

    Felix




    #include <EEPROM.h>

    byte Mode =1;




    EEPROM.put(0,2);

    Mode = EEPROM.read(0);