Read/Write 32 bit float to 4 consecutive 8 bit memory slots

I am trying to implement a storage for data from sensors to avoid the array limitations of the inherent EEPROM. I purchased the MKR memory board with 2MB of storage which is more than sufficient.

My thoughts were to create a small routine that would take a floating point number which I know to be 32-bits in size and by shifting that number sequentially by 24, 26, 8, and 0 I could assign the lowest 8 bits of the number to an unsigned char array. This array could then be passed to the SPI.h library for sequential writes of 4 bytes to a beginning address. Of course in my dreams and aspirations the reverse would be to read 4 addresses and build a 32 bit float by shifting bits into a float.

I am beginning to believe that the only real way to do this is to accept precision to 2 (0.00) decimals, multiply by 100 and convert to an unsigned long.

Any thoughts?

I'd use a union.

union
{
    float x = 1.23;
    byte dataArray[4];   //3F9D70A4; dataArray[0] = A4
} myData;

Thanks to both of you. I am currently exploring the "union" as I had not been introduced to it many years ago when I coded for a living.

lavignema:
Thanks to both of you. I am currently exploring the "union" as I had not been introduced to it many years ago when I coded for a living.

(1) When we declare float x = 1.23;, the compiler automatically stores this 3F9D70A4 32-bit pattern into 4 consecutive memory locations as per binary32 format of IEEE-754 Standard.

(2) When we declare the following union data structure, a 4-byte wide buffer space is shared by both of these two variables: x and dataArray[4]. The 32-bit value of x becomes available to the user as separate 4-byte via the members of the dataArray[]. The lower indexed member of the array contains the lower byte of the 32-bit value. In union, we define only one variable whose value is automatically taken care of by other variables according to their data types.

union
{
    float x = 1.23;
    byte dataArray[4];   //3F9D70A4; dataArray[0] = A4; dataArray[1] = 70; dataArray[2] =9D, ... ,
} myData;

(3) To access the individual bytes of the dataArray, we use the following commands:

byte x0 = myData.dataArray[0];
byte x1 = myData.dataArray[1];
byte x2 = myData.dataArray[2];
byte x3 = myData.dataArray[3];

(4) The 32-bit value of x can be printed on the Serial Monitor by executing the following codes:

long *ptr;
ptr = (long*) &myData.x;
long m = *ptr;
Serial.println(m, HEX);   //Serial Monitor shows: 3F9D70A4

(5) The byte-wise components of the 32-bit value of float x = 1.23; can be found by executing the following codes (without using union):

void setup() 
{
  Serial.begin(9600);
  float x = 1.23;
  byte *ptr;
  ptr = (byte*) &x;

  byte m0 = *ptr;   //lower byte
  Serial.println(m0, HEX);

  ptr++;
  byte m1 = *ptr;
  Serial.println(m1, HEX);

   ptr++;
  byte m2 = *ptr;
  Serial.println(m2, HEX);

   ptr++;
  byte m3 = *ptr;
  Serial.println(m3, HEX); //most significant byte
}

void loop() 
{
  
}

Thanks, this works so well. :slight_smile:

I'd use a cast.