Problem mit EEprom Werte laden

Hallo,

ich habe ein Problem mit laden von Werten aus dem Controller EEprom. Es funktioniert erst mit dem 2. Aufruf der Funktion. Der erste Aufruf liefert Datenmüll aus dem EEprom. Ich weiß nicht warum. Kann mir bitte jemand helfen?

Das ist Terminal gesteuert.

Eigentlich sollen nach Reset 3 Werte aus dem EEprom in den RAM geladen/übernommen werden. dataEEprom/dataRAM.
Das macht die Funktion loadValuesFromEEpromInRAM() die man auch mit dem Befehl 'load' aufrufen kann.

Alle aktuellen Werte im EEprom und RAM kann man sich mit dem Befehl 'read' anzeigen lassen.

Mit dem Befehl 'save' kann einen der 3 Werte einzeln ins RAM übernehmen und mit "y/Y" Bestätigung wird das ins EEprom gespeichert. Das funktioniert soweit.
Bsp.
save 1 111
save 2 222
save 3 333

Mein Problem ist das das laden der Werte nach Reset nicht wie gewünscht funktioniert. Warum nur?
Es ist auch egal ob die EEprom Startadresse auf 0 oder bspw. auf 20 steht.
Im EEprom stehen 111, 222 und 333.

LOAD nach Reset

uC Reset ### ### ###
EEPROM.length: 4096
aktuell im EEprom > A:3724541952 B:1291845632 C:4278190081
aktuell im RAM    > A:3724541952 B:1291845632 C:4278190081
Werte vom EEprom in den RAM geladen.

Eingelesen: load
Länge: 4
Debug: rxCommand: 'load' countCharacter: 4
aktuell im EEprom > A:111 B:222 C:333
aktuell im RAM    > A:111 B:222 C:333
Werte vom EEprom in den RAM geladen.

READ nach Reset

uC Reset ### ### ###
EEPROM.length: 4096
aktuell im EEprom > A:3724541952 B:1291845632 C:4278190081
aktuell im RAM    > A:3724541952 B:1291845632 C:4278190081
Werte vom EEprom in den RAM geladen.

Eingelesen: read
Länge: 4
Debug: rxCommand: 'read' countCharacter: 4
aktuell im EEprom > A:111 B:222 C:333
aktuell im RAM    > A:3724541952 B:1291845632 C:4278190081

Alles mit der Standard Arduino IDE 1.8.16 und original Arduino Mega2560.
Ideen?

/*
  Arduino IDE 1.8.16
  Arduino Mega 2560
  13.11.2021
*/

#include <Streaming.h>
#include <EEPROM.h>

constexpr bool DEBUG {false};

constexpr uint8_t BUFFER_SIZE_COMMAND {5};
constexpr uint8_t BUFFER_SIZE_VALUE {20};
constexpr uint8_t BUFFER_SIZE {BUFFER_SIZE_COMMAND + BUFFER_SIZE_VALUE};

struct ReceiveData
{
  char buffer [BUFFER_SIZE + 3];            // + zwei Leerzeichen + Null-Terminator
  char command [BUFFER_SIZE_COMMAND + 1];   // + Null-Terminator
  uint8_t  valueFirst;
  uint32_t valueSecond; 
};
ReceiveData rx;
  
struct sensorDaten
{
  const int16_t startAddr {20};
  uint32_t sensorA {0};
  uint32_t sensorB {0};  
  uint32_t sensorC {0};
};
sensorDaten dataEEprom;
sensorDaten dataRAM;

// --------------------------------------------------------

void setup (void)
{
  Serial.begin(9600);            
  Serial.println(F("\nuC Reset ### ### ###"));
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.print(F("EEPROM.length: "));
  Serial.println(EEPROM.length() ); 
  loadValuesFromEEpromInRAM(Serial);
  Serial.println();
}

void loop (void)
{
  if (readSerial(Serial, rx.buffer, sizeof(rx.buffer)))
  {    
    findCommand(Serial, rx.buffer, sizeof(rx.buffer));
  }  

  heartbeat(500);
}

// ****** Funktionen ****************************** //

// Sucht die n'te nummerische Zeichkette (num) in der übergegeben Zeichenkette (ptrString) und liest ab da
// solange wie es Digits sind bzw. bis die maximal übergebene Zeichenanzahl (maxDigits) erreicht ist. 
// Die gefunden nummerischen Zeichen werden in einen Integer gewandelt und zurückgegeben.
uint32_t findValueFromString (char *ptrString, byte num, const uint8_t maxDigits)
{
  /* 
    input:  pointer to a char array
    return: an integer number from the string (positive numbers only!)
    num=1,  returns 1st number from the string
    num=2,  returns 2nd number from the string, and so on
  */
  uint8_t countDigits {0};
  char *ptrEnd {nullptr}; 

  char numberChain [BUFFER_SIZE_VALUE + 1];
  
  while (num > 0)
  {
    num--;
    
    // skip non-digits
    while ( (!isdigit(*ptrString)) && (*ptrString != 0) )
    {
      if (DEBUG) {
        Serial << F("Debug0: ") << F("ptrString: zeigt auf addr: ") << ((uint16_t) ptrString)
               << F(" Inhalt: ") << ptrString << endl; 
      }        
      ptrString++;
    }
    if (DEBUG) {
      Serial << F("Debug1: ") << F("ptrString: zeigt auf addr: ") << ((uint16_t) ptrString)
             << F(" Inhalt: ") << ptrString << endl; 
    }      
    ptrEnd = ptrString;
    countDigits = 0;
    
    // find digits
    while ( (isdigit(*ptrEnd)) && (*ptrEnd != 0) && (countDigits < maxDigits) )
    { 
      numberChain [countDigits] = (*ptrEnd);
      if (DEBUG) {
        const uint8_t var = (*ptrEnd)-48;
        Serial << F("Debug2: ") << F("countDigits: ") << countDigits << F(" var: ") << var << endl; 
        Serial << F("Debug3: ") << F("ptrEnd: zeigt auf addr: ") << ((uint16_t) ptrEnd) 
               << F(" Inhalt: ") << ptrEnd << endl;
      }      
      ptrEnd++;
      countDigits++;
    }
    numberChain [countDigits] = '\0';
    if (num > 0) ptrString = ptrEnd;  // new search string is the string after that number
  }  
  if (DEBUG) {
    Serial << F("Debug4: ") << F("ptrEnd: zeigt auf addr: ") << ((uint16_t) ptrEnd)
           << F(" Inhalt: ") << ptrEnd << endl;
    Serial << F("Debug5: ") << F("countDigits: ") << countDigits << endl;
    Serial << F("Debug6: ") << F("numberChain: ") << numberChain << endl;
  }
  ptrEnd = numberChain;
  return (strtoul(numberChain, &ptrEnd, 10));
}

// Sucht nach Buchstaben in der übergegeben Zeichenkette (ptrString) und liest ab da
// solange wie es Buchstaben sind bzw. bis die maximal übergebene Zeichenanzahl (maxChars) erreicht ist. 
// Die gefundene Zeichenkette wird dem char buffer 'rx.command' übergeben.
// Zurückgegeben wird die Länge der gefundenen Zeichenkette.
uint8_t findCommandFromString (char *ptrString, const uint8_t maxChar)
{
  uint8_t index {0};
  
  // find alphas
  while ( (isalpha(*ptrString)) && (*ptrString != 0) && (index < maxChar) )
  {
    rx.command[index] = (*ptrString);
    if (DEBUG) {
      Serial << F("Debug7: ") << F("ptrString: zeigt auf addr: ") << ((uint16_t) ptrString) 
             << F(" Inhalt: ") << ptrString << endl;
    } 
    index++;
    ptrString++;
  }
  if (DEBUG) {
    Serial << F("Debug8: ") << F("ptrString: zeigt auf addr: ") << ((uint16_t) ptrString) 
           << F(" Inhalt: ") << ptrString << endl;
  } 
  
  rx.command[index] = '\0';
  
  return index;
}

void findCommand (Stream &out, char *buffer, const uint8_t LENGTH)
{
  out << F("Eingelesen: ") << buffer << endl;
  out << F("Länge: ") << strlen(buffer) << endl; 

  const uint8_t countCharacter = findCommandFromString (buffer, BUFFER_SIZE_COMMAND);
  out << F("Debug: ") << F("rxCommand: '") << rx.command << F("' countCharacter: ") << countCharacter << endl; 

  // ****** LOAD & 4 ************
  if ( (countCharacter == 4) && (strstr(buffer, "load") == buffer) )   
  {     
    loadValuesFromEEpromInRAM (out);
  }
  
  // ****** READ EEPROM/RAM & 4 ************
  else if ( (countCharacter == 4) && (strstr(buffer, "read") == buffer) )   
  {     
    readValuesFromEEprom (out);
    readValuesFromRAM (out);
  }
  // ****** SAVE & 4 ************
  else if ( (countCharacter == 4) && (strstr(buffer, "save") == buffer) ) 
  {     
    rx.valueFirst  = findValueFromString (buffer, 1, BUFFER_SIZE_VALUE);
    rx.valueSecond = findValueFromString (buffer, 2, BUFFER_SIZE_VALUE);
    out << F("save erkannt &") << F(" rx.valueFirst: ") << rx.valueFirst
           << F(" rx.valueSecond: ") << rx.valueSecond << endl;

    if ( (rx.valueFirst > 0) && (rx.valueFirst < 4) )
    {   // Übernahme der Benutzereingabe in den RAM 
        switch (rx.valueFirst)
        {
          case 1: dataRAM.sensorA = rx.valueSecond; break;
          case 2: dataRAM.sensorB = rx.valueSecond; break;
          case 3: dataRAM.sensorC = rx.valueSecond; break;
          default: break;
        }
        readValuesFromEEprom (out);
        readValuesFromRAM (out);
        out.println(F("save RAM to EEprom? [Y/N]"));
        // warten auf Benutzereingabe         
        while ( !readSerial(out, buffer, LENGTH) ) 
        { ; }                  
       
        const uint8_t c = findCommandFromString (buffer, BUFFER_SIZE_COMMAND);         
        if ( (c == 1) && ( (strstr(buffer, "y")) || (strstr(buffer, "Y")) == buffer) )
        { // Wert vom RAM in den EEprom speichern 
          switch (rx.valueFirst)
          {
            case 1: dataEEprom.sensorA = dataRAM.sensorA; break;
            case 2: dataEEprom.sensorB = dataRAM.sensorB; break;
            case 3: dataEEprom.sensorC = dataRAM.sensorC; break;
            default: break;
          }
          EEPROM.put(dataEEprom.startAddr, dataEEprom);
          out.println(F("Wurde im EEprom gespeichert."));
          readValuesFromEEprom (out);
          readValuesFromRAM (out);
        } 
        else {
          out.println(F("Es wurde nichts im EEprom geändert."));
        }
    }
    else {
      out.println(F("Erster Wert ist ungültig."));
    }
  }
  else
  {
    out.println(F("Befehl unbekannt."));
  } 
  out.println();
}

void readValuesFromRAM (Stream &out)
{
  out << F("aktuell im RAM    >") 
         << F(" A:") << dataRAM.sensorA 
         << F(" B:") << dataRAM.sensorB
         << F(" C:") << dataRAM.sensorC << endl;
}

void readValuesFromEEprom (Stream &out)
{
  EEPROM.get(dataEEprom.startAddr, dataEEprom);
  out << F("aktuell im EEprom >") 
         << F(" A:") << dataEEprom.sensorA
         << F(" B:") << dataEEprom.sensorB
         << F(" C:") << dataEEprom.sensorC << endl;
}

void loadValuesFromEEpromInRAM (Stream &out)
{
  readValuesFromEEprom(out);
  dataRAM.sensorA = dataEEprom.sensorA;
  dataRAM.sensorB = dataEEprom.sensorB;
  dataRAM.sensorC = dataEEprom.sensorC;
  readValuesFromRAM(out);
  out.println(F("Werte vom EEprom in den RAM geladen."));
}

bool readSerial (Stream &stream, char *buffer, const uint8_t LENGTH)
{
  static byte index {0};
  bool status {false};

  while (stream.available())
  {
    char c = stream.read();
    
    if (c == '\n')                            // wenn LF eingelesen
    {
      buffer[index] = '\0';                   // Terminierung
      index = 0;
      status = true;                          // Character fertig eingelesen
    }
    else if ( (c >= 32) && (index < LENGTH) ) // wenn noch Platz im Buffer ist
    {
      buffer[index++] = c;                    // Zeichen speichern und Index inkrementieren
    }
  }
  return status;
}

void heartbeat (const unsigned long interval)                     
{
  static unsigned long lastMillis {0};
  static bool state {false};
    
  if (millis() - lastMillis >= interval)
  {
    lastMillis += interval;
    state = !state;
    digitalWrite(LED_BUILTIN, state);
  }
}

Da geht gänzlich was schief.
Auf einem frischen MEGA mache ich folgendes:

  • lade Deinen Sketch // alles leer
  • frage load ab // alles leer
  • save 1 111 // RAM 111 EEprom 111
  • frage load ab // RAM 111 EEPROM 111
  • drücke Reset // alles leer
  • frage load ab // alles leer
15:09:05.053 -> 
15:09:05.053 -> uC Reset ### ### ###
15:09:05.053 -> EEPROM.length: 4096
15:09:05.053 -> aktuell im EEprom > A:4294967295 B:4294967295 C:4294967295
15:09:05.053 -> aktuell im RAM    > A:4294967295 B:4294967295 C:4294967295
15:09:05.053 -> Werte vom EEprom in den RAM geladen.
15:09:05.086 -> 
15:09:40.416 -> Eingelesen: load
15:09:40.416 -> Länge: 4
15:09:40.416 -> Debug: rxCommand: 'load' countCharacter: 4
15:09:40.449 -> aktuell im EEprom > A:4294967295 B:4294967295 C:4294967295
15:09:40.449 -> aktuell im RAM    > A:4294967295 B:4294967295 C:4294967295
15:09:40.449 -> Werte vom EEprom in den RAM geladen.
15:09:40.449 -> 
15:09:56.186 -> Eingelesen: save 1 111
15:09:56.186 -> Länge: 10
15:09:56.186 -> Debug: rxCommand: 'save' countCharacter: 4
15:09:56.186 -> save erkannt & rx.valueFirst: 1 rx.valueSecond: 111
15:09:56.186 -> aktuell im EEprom > A:111 B:4294967295 C:4294967295
15:09:56.219 -> aktuell im RAM    > A:111 B:4294967295 C:4294967295
15:09:56.219 -> save RAM to EEprom? [Y/N]
15:10:02.579 -> Wurde im EEprom gespeichert.
15:10:02.579 -> aktuell im EEprom > A:111 B:4294967295 C:4294967295
15:10:02.579 -> aktuell im RAM    > A:111 B:4294967295 C:4294967295
15:10:02.579 -> 
15:10:09.007 -> Eingelesen: load
15:10:09.007 -> Länge: 4
15:10:09.007 -> Debug: rxCommand: 'load' countCharacter: 4
15:10:09.007 -> aktuell im EEprom > A:111 B:4294967295 C:4294967295
15:10:09.007 -> aktuell im RAM    > A:111 B:4294967295 C:4294967295
15:10:09.007 -> Werte vom EEprom in den RAM geladen.
15:10:09.007 -> 
15:10:17.689 -> 
15:10:17.689 -> uC Reset ### ### ###
15:10:17.689 -> EEPROM.length: 4096
15:10:17.689 -> aktuell im EEprom > A:4294967295 B:4294967295 C:4294967295
15:10:17.689 -> aktuell im RAM    > A:4294967295 B:4294967295 C:4294967295
15:10:17.689 -> Werte vom EEprom in den RAM geladen.
15:10:17.722 -> 
15:10:23.751 -> Eingelesen: load
15:10:23.751 -> Länge: 4
15:10:23.784 -> Debug: rxCommand: 'load' countCharacter: 4
15:10:23.784 -> aktuell im EEprom > A:4294967295 B:4294967295 C:4294967295
15:10:23.784 -> aktuell im RAM    > A:4294967295 B:4294967295 C:4294967295
15:10:23.784 -> Werte vom EEprom in den RAM geladen.
15:10:23.784 -> 

Hallo,
sorry ich habs noch nicht ganz verstanden
in Setup rufst Du ja die

loadValuesFromEEpromInRAM (Stream &out)

in da wird dann als erstes

void readValuesFromEEprom (Stream &out)

aufgerufen , und darin sind die Werte für dataEEprom auch vorhanden. Anschließend In der aufrufenden ersten function sind dann die Werte für dataRAM aber nicht vorhanden ?

Heinz

Ich finde in Deinem Code nichts, womit die Ladeadresse aus dem EEPROM vor dem ersten Laden initialisiert wird. Verlässt Du Dich auf eine Startinitialisierung (0) durch den Compiler?

Gruß Tommy

dataEEprom.startAddr ist und bleibt -1

void readValuesFromEEprom (Stream &out)
{
  EEPROM.get(dataEEprom.startAddr, dataEEprom);
  out << F("Leseadresse > ") <<  dataEEprom.startAddr << endl;// <<--
  out << F("aktuell im EEprom >")
      << F(" A:") << dataEEprom.sensorA
      << F(" B:") << dataEEprom.sensorB
      << F(" C:") << dataEEprom.sensorC << endl;
}

Es sagt: Leseadresse > -1
Nach dem ersten Load sagt es : Leseadresse > 2559
Welches dann auch die genutzte Adresse ist.

Und nein:
Mir gefällt das durcheinander nicht.
Nicht dass mein "Geschmack" hier sonderlich wichtig wäre, aber so kann ich es weder lesen noch verstehen, somit auch den Fehler weder finden noch reparieren.

Wie auch immer:
Händisch festgelegte Adressen, sind mir ein Greul . (jetzt weiß ich einmal mehr, das Warum)
Kannst du das nicht dem Compiler überlassen?

Hallo,

@ my_xy
passiert nach einer 2. Eingabe von read oder load auch noch nichts?

@ Rentner
in loadValuesFromEEpromInRAM() werden beide read Funktionen aufgerufen. Damit sollte nach Reset in allen struct Member die Werte aus dem EEprom stehen. Tun sie aber nicht nicht. Erst nach manueller Eingabe von read bzw. load. Genau diese "Verzögerung" vertehe ich nicht.

@ Tommy
'grübel' Die Startadresse lege ich doch hier fest.

struct sensorDaten
{
  const int16_t startAddr {20};

@ uxomm
-1, na sowas. 'grübel' Warum das denn wenn ich diese mit const 20 initialisiere?

@ combie:
Irgendeine Startadresse muss man doch angeben. Wie sonst? Den ganzen Rest der struct Länge überlasse ich dem Compiler bzw. der get/put Funktion.
Wegen dem durcheinander. Du meinst sicherlich die findCommand Funktion. Ja das ist derzeit alles drin. Das wird später noch zerlegt. Für 3 Befehle sollte das derzeit noch überblickbar sein. Es ist kompilierbar und testbar. Die Terminal und Eingabefunktionalität ist ja gegeben. Das ist nicht mein Problem.

Im struct sensorDaten hast Du zwar eine Adresse drin, die wird auch zum lesen benutzt. 1Mal.

Ich hab das mal ergänzt:

void readValuesFromEEprom (Stream &out)
{
  Serial.print("readFromEEprommAdress: ");
  Serial.println(dataEEprom.startAddr);
  EEPROM.get(dataEEprom.startAddr, dataEEprom);
  out << F("aktuell im EEprom >") 

Dann einmal Sketch geladen
Dann einmal load
Die konstante ist zerstört

15:57:31.168 -> uC Reset ### ### ###
15:57:31.168 -> EEPROM.length: 4096
15:57:31.168 -> readFromEEprommAdress: 20
15:57:31.168 -> aktuell im EEprom > A:4294967295 B:4294967295 C:4294967295
15:57:31.168 -> aktuell im RAM    > A:4294967295 B:4294967295 C:4294967295
15:57:31.168 -> Werte vom EEprom in den RAM geladen.
15:57:31.201 -> 
15:57:40.779 -> Eingelesen: load
15:57:40.779 -> Länge: 4
15:57:40.779 -> Debug: rxCommand: 'load' countCharacter: 4
15:57:40.779 -> readFromEEprommAdress: -1
15:57:40.779 -> aktuell im EEprom > A:4294967295 B:4294967295 C:4294967295
15:57:40.779 -> aktuell im RAM    > A:4294967295 B:4294967295 C:4294967295
15:57:40.812 -> Werte vom EEprom in den RAM geladen.
15:57:40.812 -> 

Hallo,

jetzt dämmert es. Die startAddr wird ja mit aus dem EEprom geladen weil sie mit im struct steht. Und im EEprom steht an der Stelle irgendwas drin. Mich wundert nur das niemand meckert, weil die startAddr konstant ist. Die muss also aus dem struct.
Danke. Ich teste das einmal ...

Ich halte es sowieso für suboptimal, die Adresse in den zu speichernden Daten zu halten.

Gruß Tommy

Hallo,

startAddr aus dem struct rausgenommen und nun klappt das. Danke. :+1:

Ich hatte die Wirkungsweise übersehen. So ganz blöd war der Gedanke jedoch nicht, denn das war die Vorbereitung auf eine Art Wear Leveling. Dort wollte ich eine variable Startaddresse hinterlegen die je nach Schreibzählerstand um eine structlänge weiterspringt. Muss das nochmal überdenken ob ich das ganz weglasse oder anders lösen kann. Benötigen tue ich das im Grunde nicht. Die Werte ändern sich zu selten. Wäre eine Fehlerquelle weniger. Sonst hätte ich gleich ein FRAM genommen. Das EEprom Problem ist ja erstmal behoben. :+1:

Edit:
Ich finde es nur aktuell etwas blöd das die startAddresse so alleine ohne jeden Zusammenhang zum struct im Code rumsteht. :thinking:

Naja, Du kannst ja initialisieren, musst dann aber prüfen, was es an der Adresse gibt und wenn die -1 ist schreibst Du den initialisierten wert, sonst holst du den, der da ist und verwendest den weiter.

Hallo,

hatte gerade hunderte Gedanken. Ich werde sie wohl separat belassen. Denn zu den RAM-Daten gehört sie nicht. Wäre dann doppelt und verwirrt später vielleicht.

Danke @ all.

Hätte gern noch das "Warum" gewusst? put/get benötigen eine Startaddresse als Parameter. Was soll dabei der Compiler machen?

#include <EEPROM.h> 
#include <Streaming.h> // die Lib findest du selber ;-)
Stream &cout = Serial; // cout Emulation für "Arme"

struct SensorDaten
{
  uint32_t sensorA;
  uint32_t sensorB;
  uint32_t sensorC;
};

SensorDaten sensorDatenImRam{0,0,0};
SensorDaten sensorDatenImEEPROM EEMEM{123,231,321};// Arduino erzeugt *.eep Datei mit den Vorbesetzungen


void setup() 
{
  Serial.begin(9600);
  cout << F("Start: ") << F(__FILE__) << endl;
  EEPROM.get((int)&sensorDatenImEEPROM,sensorDatenImRam);
  cout << sensorDatenImRam.sensorA << endl;
  
}

void loop() 
{

}

Gerade wenn du an Wearleveling denkst, hat die Adresse nix in den Daten verloren.
Siehe dazu: http://ww1.microchip.com/downloads/en/appnotes/doc2526.pdf

Hallo,

na gut, ist gut zu wissen, nur inwieweit hilft mir das mit EEMEM und der .eep weiter? Das war nicht mein Problem mit dem EEprom. Der Fehler lag woanders.

Ich kann die Startadresse zwischen 0 ... (Endadresse - struct Länge) frei wählen.

Ich habe derzeit größer 0 festgelegt, weil ich beim entwickeln und testen nicht gleich den Anfangsbereich tot schreiben möchte, falls was schief geht. Kann auch 4000 sein.

Die *.eep kannst du per ISP aufspielen, hast so deine korrekten Vorbesetzungen im Speicher verankert.
Würde mal sagen, dass das übliche Verfahren bei der Produktion von Elektrogeräten ist.
Ob du das brauchst, oder nutzen möchtest? Mir egal.

Genau das ist dir ja hier auf die Füße gefallen, da du dabei Mist gebaut hast.

Dass ist kein Argument um es händisch zu machen, das geht auch automatisch.

Hier mal mit Abstandshalter, damit die Nutzdaten auf höherer Adresse landen.
Aber dafür ohne EEMEM, da du das ja nicht brauchst/willst

Auch hier wird die Adressberechnung vollständig dem Compiler überlassen.

#include <EEPROM.h> 
#include <Streaming.h> // die Lib findest du selber ;-)
Stream &cout = Serial; // cout Emulation für "Arme"

struct SensorDaten
{
  uint32_t sensorA;
  uint32_t sensorB;
  uint32_t sensorC;
};


struct StrukturImEEPROM
{
  char dummy[200]; // abstandshalter
  SensorDaten sensorDaten;
};

SensorDaten sensorDatenImRam{0,0,0};


void setup() 
{
  Serial.begin(9600);
  cout << F("Start: ") << F(__FILE__) << endl;
  EEPROM.get(offsetof(StrukturImEEPROM,sensorDaten),sensorDatenImRam);
  cout << sensorDatenImRam.sensorA << endl;
  
}

void loop() 
{

}

Hallo,

a)
.eep per ISP aufspielen wäre zwar möglich, okay, trifft jedoch später nicht zu, es wird noch einen Kalibriermodus geben womit individuelle Werte gespeichert werden. Die .eep wird ja zur Laufzeit nicht aktualisiert, sodass sich diese nicht einmal als Backup verwenden könnte. Wäre zu schön gewesen.

b)
Das ist mir eben gerade nicht auf die Füße gefallen. Der Fehler lag woanders im Verständnis. Ich habe ja keine falschen Berechnungen gemacht.

c) ...

d)
Das mit dem offsetof( ) ist eine Idee, machts aber nicht gerade lesbarer mit dem zusätzlichen struct. Da kann ich auch gleich als Startadresse 200 eingeben. Das offsetof macht nichts anderes als das was ohnehin klar ist. Kann man sicherlich in dem einfachen Sachverhalt halten wie Nolte.

Ach, du triffst schon die richtigen Entscheidungen!
Wenn nicht Heute, dann vielleicht Morgen.