Problem mit "long int in byteArray wandeln"

Hi,

ich möchte unsigned long int Werte so in 4 Bytes zerlegen, dass ich diese direkt ins Eeprom schreiben kann.
Im Inet habe ich dazu folgenden Code gefunden:

         unsigned long int longInt = 1234567890;
         unsigned char byteArray[4];
                      
         // convert from an unsigned long int to a 4-byte array
         byteArray[0] = (int)((longInt >> 24) & 0xFF) ;
         byteArray[1] = (int)((longInt >> 16) & 0xFF) ;
         byteArray[2] = (int)((longInt >> 8) & 0XFF);
         byteArray[3] = (int)((longInt & 0XFF));

          for (int i = 0; i < 4; i++){
          EEPROM.write(i,byteArray[i]);
          }

Das funktioniert auch. Als Ergebnis erhalte ich: “49 96 02 D2” (als hex-Werte)

Wenn ich die Werte wieder auslesen will und in ein long-Integer wandle:

         unsigned long int longInt;
         unsigned char byteArray[4];
         
         for (int i = 0; i < 4; i++){
             byteArray[i] = EEPROM.read(i);
         }
         // convert from a 4-byte array to an unsigned long int
         longInt = ( (byteArray[0] << 24) 
                   + (byteArray[1] << 16) 
                   + (byteArray[2] << 8) 
                   + (byteArray[3] ) );

        Serial.println(longInt);

Da bekomme ich dann als Resultat den Dezimalwert 722. Dies ist in HEX: “02 D2”. Also die beiden letzten Byte.

Was mach ich da falsch?
Oder habt Ihr evtl. noch eine bessere Methode für meine Aufgabenstellung?

Geuß/hk007

hk007: Was mach ich da falsch?

In diesen beiden Zeilen: byteArray[0] = (int)((longInt >> 24) & 0xFF) ; byteArray[1] = (int)((longInt >> 16) & 0xFF) ; müßtest Du natürlich auf (long) typecasten statt auf einen vom Typ her zu kurz gegriffenen (int).

hk007: Oder habt Ihr evtl. noch eine bessere Methode für meine Aufgabenstellung?

Wenn es auf Geschwindigkeit ankommen würde (was in dem Fall natürlich nicht zutrifft, das langsamste ist sowieso das Schreiben ins Eeprom), dann würde ich direkt per Pointer auf die vier einzelnen Bytes zugreifen.

jurs:
In diesen beiden Zeilen:
byteArray[0] = (int)((longInt >> 24) & 0xFF) ;
byteArray[1] = (int)((longInt >> 16) & 0xFF) ;
müßtest Du natürlich auf (long) typecasten statt auf einen vom Typ her zu kurz gegriffenen (int).

Bist du dir da sicher? Dieser Teil funktioniert ja. Ich sehe im Eeprom die richtigen Werte.
Was nicht klappt ist das Zurückwandeln von dem bytearray ins longinteger Format

jurs:
Wenn es auf Geschwindigkeit ankommen würde (was in dem Fall natürlich nicht zutrifft, das langsamste ist sowieso das Schreiben ins Eeprom), dann würde ich direkt per Pointer auf die vier einzelnen Bytes zugreifen.

Oh ja die Pointer…
Hab auch schon in die Richtung gedacht. Der LongInteger Wert steht ja bereits im 4 Byte-Format irgendwo im RAM
Wenn man den dann irgendwie mit longInt.byte(0) etc. lesen bzw. schreiben könnte.
Also irgendwie so:

unsigned long int longInt;
for (int i = 0; i < 4; i++){
longInt.Byte(i) = EEPROM.read(i);
}

Aber dazu kenn ich mich leider mit Pointern auf C zu wenig aus :frowning:
(Das in Rot ist nur eine Denkweise)

Hi,

hab schnell mal einen CrashCurs zu Pointern durchgezogen. Internet sei Dank

Ich hab mir jetzt folgende Funktion gestickt:

unsigned long Eeprom_Read_LongInt (unsigned int addr)
{
      unsigned long result;
      byte *ptr = (byte *)&result;
      byte i;

      for (i=0;i<4;i++)
          *(ptr++)=EEPROM.read(addr++);
      return result;
}

Gefällt mir ganz gut.
Hab damit aber ein Low-Byte/High-Byte Problem, da die Daten über meine erste Funktion genau andersrum abgespeichert werden.

Ok. Das ist jetzt Definitionssache, wie rum man das jetzt speichert.
Irgendwie schreit ja alles danach, die Zahl so im Eeprom abzulegen, wie es auch im RAM erfolgt. Also das höchste Byte auch in der höchsten Adresse des Eeprom.
Allerdings hab ich eine Funktion, die mir einen HexDump des Eeprom (immer 8 Byte nebeneinander, viele Zeilen untereinander) ausgibt. Da liest es sich natürlich schöner, wenn die LongInt genau andersrum abgespeichert wird.

Was meint ihr dazu?

Auf jeden Fall sollten die Funktionen zum EPROM lesen und schreiben genau untereinander stehen und man auf den ersten Blick sehen können, dass sie zusammen passen.

Ich hab mich dran gewöhnt, dass 7A 55 33 00 als Int32 0x33557A aussehen würde, als Text aber richtig rum "zU3"