Saving Floats, Longs, and Ints to EEPROM in Arduino Using Unions

The Arduino EEPROM library provides the read() and write() functions for accessing the EEPROM memory for storing and recalling values that will persist if the device is restarted or its operation interrupted.  Unfortunately, these functions only allow accessing one byte at a time.  The float, double (the same as float on most Arduinos), and long data types are all four bytes long, and the int data type is two bytes long, the same length as the word data type.  Some trickery is needed to easily store and recall these values.

The trick is the C language union construct.  A union allows a single memory space to be accessed through variables of different types.  Using float as an example, we can use a union that contains a float and a four element array of bytes.  When a value is written to the float, the four bites of data that make up that float are now available as an array of four bytes (bytes 0-3).   Look at the table below for a better representation.

Float (823.5)

01000100

01001101

11100000

00000000

Byte[3]

Byte[2]

Byte[1]

Byte[0]

The binary representation of 823.5 as a floating point number is 01000100 01001101 11100000 00000000.  Using a union, each of the bytes of this data can be accessed independently.  We can read from or write to them.  As long as the same method is used to do the operation for both a write and read operation (accessing the bytes in the same order, high-to-low or low-to-high), the data we save to EEPROM from a float can be put back together as a float.

Here are a pair of functions that implement the union to perform the reads/writes:

float readFloat(unsigned int addr)
{
 union
 {
  byte b[4];
  float f;
 } data;
 for(int i = 0; i < 4; i++)
 {
  data.b[i] = EEPROM.read(addr+i);
 }
 return data.f;
}
void writeFloat(unsigned int addr, float x)
{
 union
 {
  byte b[4];
  float f;
 } data;
 data.f = x;
 for(int i = 0; i < 4; i++)
 {
  EEPROM.write(addr+i, data.b[i]);
 }
}

These functions can be modified for any data type, just change the function names, the number of bytes in the arrays within the unions (if different from 4), and change the data types of the function arguments and union variable.

When selecting the addresses to use for the values you want to store, remember that you’re using that address, as well as the next however many bytes your data type is long.  So, if you wrote a float using these functions to address 20, you are actually writing to 20, 21, 22, and 23.  Make sure you don’t write other values into that address space or you will lose data.

Best of luck!

5 thoughts on “Saving Floats, Longs, and Ints to EEPROM in Arduino Using Unions”

Leave a Reply