Official EEPROM library: support and reference.

EEPROM Library for Arduino

Written by: Christopher Andrews.


What is the EEPROM library?

The EEPROM library provides an easy to use interface to interact with the internal non-volatile storage found on AVR based Arduino boards. The library uses a set of native C++ classes which allows for very efficient usage by preventing any unnecessary overhead from being added to a sketch. This library will work on many AVR devices containing an EEPROM, such as ATtiny and ATmega chips.

Purpose of this thread:

The EEPROM library has been rebuilt from the ground up. It has an improved set of basic functionality helping to make entry level use easier. As a consequence of its own design, it includes an advanced API for all the seasoned and tasty programmers out there.

This thread is intended for discussion as well as support. If you have a question on how to use the EEPROM library in your project, fire away. Once the discussion is over, hopefully this thread can become a one stop shop for EEPROM help and various examples. Don't hold back if you would like to discuss some aspect of the library/documentation, or simply let me know what you think. Also if you create an example sketch you feel highlights a useful feature, or solution to a common problem: post it and it can be linked from this index, or even proposed as an addition to the IDE.

The site reference has just been updated with the basic set of functionality (after writing this article). However this documentation will eventually contain all the reference material from basic to advanced usage. And to allow for the best documentation possible, we can take the time here to improve on it before adding it to the official resource if warranted. Or simply have an in-depth resource here. Once I'm happy with the next sections, I'll update these posts.

A quick overview:
The basic functionality for the library now consists of seven functions.

EEPROM.read( address )
EEPROM.write( address, value )
EEPROM.update( address, value )
EEPROM.get( address, object )
EEPROM.put( address, object )
Subscript: EEPROM[ address ]
EEPROM.length()

For IDE versions prior to 1.6.2, only the
** **.read()** **
and
** **.write()** **
members are available.

Whats next?

I already have an update currently on the test bench containing a few improvements. I decided to leave these separate as they need in-depth testing and I want to consult the community as there may be additions I haven't considered yet. The two main features the next update includes are below. These additions do not impact the performance of the class, but more so, the library will encapsulate every feature found in all custom EEPROM libraries (and more).

  • Modification allowing
  • ```*
  • .get()*
  • ```*
    and
  • ```*
  • .put()*
  • ```*
    to accept arrays, not just objects.
  • Addition of
  • ```*
  • .readBit()*
  • ```*
    and
  • ```*
  • .writeBit()*
  • ```*
    functions to EEPROM class.

Also, any interest in some EEPROM versions of the standard memory functions like
** **strlen_E** **
,
** **strcpy_E** **
,
** **memset_E** **
,... similar to what is provided for PROGMEM (
** **memcpy_P** **
).

Conclusion

As a member of the forums for over three years, I can see the value regular members place on being kept up to date with what is happening in the Arduino project. So as the author of this library I feel it necessary to provide support for my code, as well as collaborating with the actual users of the library to help create a great end result.

Cheers.

How to use the library

This library is included in your IDE download [1]. To add its functionality to your sketch you'll need to reference the library header file. You do this by adding an include directive to the top of your sketch.

#include <EEPROM.h>

void setup(){

}

void loop(){

}

The library provides a global variable named

[b]EEPROM[/b]

, you use this variable to access the library functions. The methods provided in the EEPROM class are listed below.

Most functions provided by the library take either one or two parameters. Any function that reads or writes data takes an address as its first parameter. These addresses refer to EEPROM cells, and are zero based like arrays; as in the first address/cell is zero.


Library functions

EEPROM.read( address ) [example]

This function allows you to read a single byte of data from the eeprom. Its only parameter is an

[b]int[/b]

which should be set to the address you wish to read.

The function returns an

[b]unsigned char[/b]

[2] containing the value read.

EEPROM.write( address, value ) [example]

The

[b]write()[/b]

method allows you to write a single byte of data to the EEPROM. Two parameters are needed. The first is an

[b]int[/b]

containing the address that is to be written, and the second is a the data to be written (

[b]unsigned char[/b]

).

This function does not return any value.

EEPROM.update( address, value ) [example]

This function is similar to

[b]EEPROM.write()[/b]

however this method will only write data if the cell contents pointed to by

[b]address[/b]

is different to

[b]value[/b]

. This method can help prevent unnecessary wear on the EEPROM cells.

This function does not return any value.

EEPROM.get( address, object ) [example]

This function will retrieve any object from the EEPROM. Two parameters are needed to call this function. The first is an

[b]int[/b]

containing the address that is to be read, and the second is the object you would like to read.

This function returns a reference to the object passed in. It does not need to be used and is only returned for convenience.

EEPROM.put( address, object ) [example]

This function will write any object to the EEPROM. Two parameters are needed to call this function. The first is an

[b]int[/b]

containing the address that is to be written, and the second is the object you would like to write.

This function uses the update method to write its data, and therefore only rewrites changed cells.

This function returns a reference to the object passed in. It does not need to be used and is only returned for convenience.

Subscript operator: EEPROM[ address ] [example]

This operator allows using the identifier

[b]EEPROM[/b]

like an array. EEPROM cells can be read and written directly using this method. This can be used as an alternative to the read, write, and update functions.

This operator returns a reference to the EEPROM cell pointed to by

[b]address[/b]

.

byte val;

//Read first EEPROM cell.
val = EEPROM[0];  

//Write first EEPROM cell.
EEPROM[0] = val;  

//Compare contents
if( val == EEPROM[ 0 ] ){
  //Do something...
}

//Update method is also available for cell references.
EEPROM[4].update( val );

EEPROM.length()

This function returns an

[b]unsigned int[/b]

containing the number of cells in the EEPROM. Not all devices have the same size EEPROM, this can be useful for writing code portable to different Arduinos.


Tag Notes:

  • This library is included in Arduino IDE versions 1.6.2 or greater.
    For all earlier versions, the only part of the documentation that applies is for the functions:

[iurl=#func_read]EEPROM.read( address )[/iurl]


- ```
[b][iurl=#func_write]EEPROM.write( address, value )[/iurl][/b]
  • Many examples found around the internet use different types to represent a byte of data. In the Arduino environment a
[b]byte[/b]

,

[b]uint8_t[/b]

, and

[b]unsigned char[/b]

are all referring to the same type.

-- This post reserved for additional documentation :slight_smile:

Latest IDE release:

Got skills in C++ or Java, you could contribute to the project.
There are always many issues to solve.

Found a bug/problem in the forum? Add to, or create an issue.

thanks :slight_smile:

pYro_65:
Modification allowing .get() and .put() to accept arrays, not just objects.

Please, please, please!!

Please, please, please!!

This is almost finished, just doing up examples and documentation.

Hopefully this'll be added before the release of IDE 1.6.6

Here is the code if you want to copy it over now:
EEPROM.h code

And the comparison of the next updates.
ee-update

The documentation should be ready tonight or tomorrow.

Great work on this library pYro_65! That's great you added the bit functions. Thanks!

Hi, I downloaded the EEPROM.h file listed above and the examples including the one showing bit manipulation. I then installed both under Arduino 1.6.5r2 in the /hardware/avr/ libraries path as per the old EEPROM.h and examples.
however in the samples the file to change EEPROM bits does not show up, any idea why please?

Also is the code to save arrays to EEPROM available?

Thanks

The bit access is part of the latest update, your IDE does not have the example I added for this feature yet. If you copied over the examples already, the IDE must be restarted to detect the new files (the compiler will load the new library code, however the examples need refreshing).

Here is the readme
and example

And yes, put() and get() work with arrays of any dimensions in the update I posted above. The documentation is not online yet (and the bit access example has been updated). I have a few more examples which I'll try push in a few hours.

Hi, still no joy I am afraid. I clicked the Readme file and then got to the Git and backed up through the directories until I got the download button. I downloaded all the files, expanded them and copied the whole EEPROM folder to the same location as the existing EEPROM folder after first removing the original EEPROM folder. I then started the IDE and looked at the EEPROM example folder, still no example on setting bits.
I then copied the example you posted into the Arduino IDE and tried to compile it. I got the error message 'EEPROM class has no member called write_bit.

I am obviously doing something wrong but I do not know what, do you have a suggestions please.

Thanks

Bob

The download .zip, I'm pretty sure will only download the master branch, not the working branch with the changes (its not merged into master yet).

Here is a zip, with only the library folder.

EEPROM.zip (21.7 KB)

Hi, Thanks for your help and patience so far. I downloaded the EEPROM.zip you provided, unzipped it and used it to over write the existing EEPROM library in the Hardware\Arduino\Avr\Libraries folder.

Using file manager I can see all the example files. However using the IDE examples option I can only see the original EEPROM examples. So I deleted all of the Arduino 1.6.5 r2 installation and then re-installed it using the .exe version of the IDE. I then replaced the newly installed version of EEPROM (that can with the IDE) with the copy you provided. Still no joy!

I then tried to open the example files manually using 'file open', the array and CRC example load and compile OK. the bits, memory block and iterate do not compile without errors.

When I tried to compile the 'bits' example the reported error was struct EEPROMClass has no member named WriteSet. So I opened up EEPROM.h in a text editor and sure enough the EEPROMClass is there and so are the bit access methods which contains WriteBit. Thus to me it seems that the Arduino software is somehow using another EEPROM.h file but from where I have no idea.

I have earlier versions of Arduino 104 and 164 loaded on the machine but in different directories. I'll delete those and see if that helps.

If you have any other suggestions I would, once again, greatly appreciate your help.

Thanks

Bob

Ah, version 1.6.4 had the AVR core separated into the Arduino15 folder (mine is here C:\Users\Chris\AppData\Roaming\Arduino15).

1.6.5 reverted and placed the AVR core back in the install folder, however the Arduino15 folder takes precedence (scanned first).

Locate the Arduino15 folder and move to the directory: packages\arduino\hardware

Delete the AVR folder. However if you run 1.6.4 again, it'll automatically be extracted there again!

Hi Chris, That solved it!

I knew that 1.6.5 r2 had changed the location of certain files but I had not thought about that as a cause of my problems.
Everything looks to be working OK now except for one curious thing in Visual Micro. If I use EEPROM.read for example VM underlines EEPROM with a red line and says it is undefined yet the code compiles and runs correctly.

Thank you very much for all of your help in solving this issue and especially for the brilliant EEPROM library.

Bob

I only want to thank you for this library!
I used it in a project and now i can't do without it almost in every project i can think of!

Thank you!

pYro_65, thanks for the new EEPROM library !

I have a question: Would it be possible to define a structure based on EEPROM[] using c++ and let the code update only a single item when that item is written. Even if the size of that item is more than one byte.
Something like a union of the structure and the EEPROM[] and the compiler chooses the EEPROM[] when a item of the structure is written.

The EEMEM can define a struct in EEPROM, but the eeprom_write_byte() functions are still needed.

The information to do this a available for the compiler, but I don't know if c++ extends that far.

Or perhaps there is a possibility to use the .update() to update the complete structure, every time an item is written.

@macktsk, Koepel
Thank you, I'm glad its been a benefit.

@Koepel

The EEMEM can define a struct in EEPROM, but the eeprom_write_byte() functions are still needed.

The information to do this a available for the compiler, but I don't know if c++ extends that far.

Or perhaps there is a possibility to use the .update() to update the complete structure, every time an item is written.

When using the EEPROM library alone you will need to use EEPROM.get() & EEPROM.put() to read and write the values. However it seems you want to read/write the variable declared as EEMEM directly?

For this, you'll also need my EEWrap library. It makes the EEPROM even simpler, and can do what you want.

Its available through the library manager, just search for EEWrap.

There is a quick write up for it here: GitHub - Chris--A/EEWrap: EEPROM access made dead simple!

And here is a sample sketch showing how easy it is to use. Basically instead of building your struct/arrays out of standard types like 'unsigned int' or 'uint16_t' you use my provided types like 'uint16_e'. You can also create your own types by wrapping them in an EEWrap class.

#include <EEPROM.h>
#include <EEWrap.h>

//Use the xxx_e types rather than the standard types like uint8_t
struct Foo{
  uint8_e a;
  int16_e b;
  float_e c;
};

Foo foo EEMEM; //EEMEM tells the compiler that the object resides in the EEPROM

void setup(){

  //Write to values stored in EEPROM
  foo.a = 45;
  foo.b = 12345;
  foo.c = 3.1415f;

  //Print values from EEPROM
  Serial.begin(9600);
  Serial.println(foo.a);
  Serial.println(foo.b);
  Serial.println(foo.c);
}

void loop() {}

As you can see, no more using eeprom_read_byte, or even the EEPROM library (EEWrap uses the EEPROM library though and must be included also).

Have fun!

That is super awesome !
Thank you so much. I was thinking/dreaming about this for a few years, even before I started with Arduino and was using EEMEM for AVR projects.

Great work! Thank you.

I like the .update() method.

In the DS1624 library I adapted from Federico and Riccardo Galli I implemented something similar, but built-in into the .write() method: the value is only written if it differs from existing values.

Like you wrote, this prevents unnecessary wear of the EEPROM cells, thus substantially increasing their lifespan.

I really like the implementation of this. :sunglasses: And because it is too easy to ask :blush: , would it be very difficult adapting this to an external I2C eeprom? (like the 24LC256) :sweat_smile: