Probleme mit 24lc256 EEPROM

Hallo,
ich möchte auf einem 24lc256 Messwerte abspeichern, die aus jeweils der Uhrzeit und dann noch 2 Byte an Daten bestehen; also gesamt 6 byte groß sind. Dazu verwende ich folgenden Code:

zum Schreiben:

void LC256_writeEntry(unsigned int addr, byte *data)
{
  Wire.beginTransmission(EEPROM_ADDR);
  Wire.write((int)(addr >> 8));       // MSB
  Wire.write((int)(addr & 0xFF));     // LSB
  for(int i = 0; i < 6; i++)
  {
    Wire.write(data[i]);
  }
  Wire.endTransmission();
  delay(5);
}

zum Lesen:

struct logValue {
  time_t zeit;
  byte neue;
  byte alte;
};

struct logValue LC256_readEntry(unsigned int startAddr)
{
  int length = 6;
  byte buf[length];
  Wire.beginTransmission(EEPROM_ADDR);
  Wire.write((int)(startAddr >> 8)); // MSB
  Wire.write((int)(startAddr & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(EEPROM_ADDR, length);
  for (int c = 0; c < length; c++ )
  {
    if (Wire.available()) 
    {
      buf[c] = Wire.read();
    }
  }
  delay(1);
  
  struct logValue returnpowervalues;
  returnpowervalues.neue = buf[4];
  returnpowervalues.alte = buf[5];
  
  returnpowervalues.zeit = ( ((unsigned long)buf[0] << 24) 
                   + ((unsigned long)buf[1] << 16) 
                   + ((unsigned long)buf[2] << 8) 
                   + ((unsigned long)buf[3] ) );
  return returnpowervalues;
}

Soweit funktioniert das auch, allerdings werden anscheinend nicht alle Werte sauber geschrieben oder gelesen. Wenn ich mir die Werte byteweise ausgeben lasse erhalte ich folgende Ausgabe (alle Werte wurden zum Test mit 0 beschrieben):

0 0 0 0 0 0
...
0 0 0 0 0 0
0 0 255 255 255 255
0 0 0 0 0 0
...
0 0 0 0 0 0
0 0 255 255 255 255
0 0 0 0 0 0
...
0 0 0 0 0 0
0 0 255 255 255 255
0 0 0 0 0 0
...
0 0 0 0 0 0

Ich habe am Anfang vermutet, dass vielleicht bestimmt Speicherzellen kaputt sind, aber egal in welchem Bereich auf dem EEPROM ich meine Daten schreibe/lese bekomme ich die selben Ergebnisse. Auch dass der Abstand zwischen den Fehlern immer gleich ist, finde ich seltsam.

Hat jemand eine Idee, an was es liegen könnte?

Keine Lösung, nur 'ne Rückfrage zu einer Vermutung:
Beim Aufruf der Schreib-Funktion übergibst du eine Adresse im INT-Format, sendest dann 2x INT ans EEPROM als Adresse (MSB+LSB). Müsste man dort bei write(...) nicht auf "Byte" casten?
Auch später bei Read?
(Das Thema interessiert mich nämlich für einige Versuche in den nächsten Wochen)

void LC256_writeEntry(unsigned int addr, byte *data)

Wo ist bei deinem Schreibvorgang die Länge der Struktur angegeben?

Ich hatte da mal was gebaut....

Leider ist dein EEProm nicht in der Liste.
Es ist ein Beispiel dabei, wie man eigene EEProms definiert.
Und dein EEProm ist kompatible zum:

  1. Atmel AT24C256
  2. STMicroelectronics M24256
    Die sind beide implementiert.

RudiDL5:
Keine Lösung, nur 'ne Rückfrage zu einer Vermutung:
Beim Aufruf der Schreib-Funktion übergibst du eine Adresse im INT-Format, sendest dann 2x INT ans EEPROM als Adresse (MSB+LSB). Müsste man dort bei write(...) nicht auf "Byte" casten?
(Das Thema interessiert mich nämlich für einige Versuche in den nächsten Wochen)

Ich rufe den Schreibbefehl so auf (wobei ich den Code nicht selber geschrieben hab, sondern irgendwoher kopiert habe; die Frage mit dem int habe ich mir auch schon gestellt, aber falls das falsch sein sollte dürfte es ja bei mir nicht 31 von 32 mal funktionieren...):
wobei in NowLong die aktuelle Zeit steht

unsigned char byteArray[6];
    
// convert time from an unsigned long int to a 4-byte array
byteArray[0] = (int)((NowLong >> 24) & 0xFF) ;
byteArray[1] = (int)((NowLong >> 16) & 0xFF) ;
byteArray[2] = (int)((NowLong >> 8) & 0XFF);
byteArray[3] = (int)((NowLong & 0XFF));
byteArray[4] = powerByte(NEU);
byteArray[5] = powerByte(ALT);
    
LC256_writeEntry(pos, byteArray);

dürfte es ja bei mir nicht 31 von 32 mal funktionieren

Ist ein Argument, ich kanns halt (noch) nicht selbst testen, weil es erst in ein paar Wochen auf dem Plan steht. Aber ich verfolge das gerne, war ja auch nur 'ne Vermutung.

combie:
Wo ist bei deinem Schreibvorgang die Länge der Struktur angegeben?

Ich gebe zu, dass das nicht die beste Möglichkeit ist, aber die Länge ist hart codiert in der for Schleife

for(int i = 0; i < 6; i++)

combie:
Ich hatte da mal was gebaut....
GitHub - CombiesGit/I2C_EEPROM: Supports a wide range I2C eeproms
Leider ist dein EEProm nicht in der Liste.
Aber es ist ein Beispiel dabei, wie man eigene EEProms definiert.

Vorteil:
Die Lib hat Methoden um Strukturen/Objekte zu schreiben.

Sieht nicht schlecht aus, aber eigentlich wollte ich für diese vermeintliche Kleinigkeit kein library verwenden, da ich eh schon Speicherplatzprobleme habe...

Soooo groß ist die LIB von "combie" ja auch wieder nicht (habe ich übrigens für mich schon gesichert...) aber wenn du eh schon knapp mit dem Speicher bist - dann bleibt dir wohl auf Dauer nichts anderes übrig als das Programm zu optimieren. Allein schon bei for(int i = 0; i < 6; i++) würde ich selbst nur "byte" als Zähler nehmen, spart schon einige Bytes, so etwas ist an anderen Stellen sicherlich auch noch mehrfach vorhanden und summiert sich.

Sieht nicht schlecht aus, aber eigentlich wollte ich für diese vermeintliche Kleinigkeit kein library verwenden, da ich eh schon Speicherplatzprobleme habe...

Dann solltest du auch verstehen, wie solche EEProms funktionieren.

Meine Glaskugel sagt:
Du schreibst über Pagegrenzen hinweg.
Du schreibst also an ganz andere Adressen, als du eigentlich glaubst.

Nachtrag:
Dieses Problem wird bei I2C und SPI Eeproms auftreten

Problem gelöst :slight_smile:

Ich habe meine Daten jetzt einfach um 2 byte vergrößert und damit passen jetzt immer genau 8 Werte in eine Page und ich muss nicht über Seitengrenzen hinausschreiben.

Glückwunsch!
(auch wenn es etwas nach "Dirty Hack" riecht)