Fixed EEPROM examples and added readme

This commit is contained in:
Chris--A 2015-03-24 13:58:01 +10:00
parent ab14475248
commit bd2b9d1afd
9 changed files with 160 additions and 204 deletions

View File

@ -0,0 +1,139 @@
## **EEPROM Library V2.0** for Arduino
**Written by:** _Christopher Andrews_.
### **What is the EEPROM library.**
Th EEPROM library provides an easy to use interface to interact with the internal non-volatile storage found in AVR based Arduino boards. This library will work on many AVR devices like ATtiny and ATmega chips.
### **How to use it**
The EEPROM library is included in your IDE download. 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.
```Arduino
#include <EEPROM.h>
void setup(){
}
void loop(){
}
```
The library provides a global variable named `EEPROM`, you use this variable to access the library functions. The methods provided in the EEPROM class are listed below.
You can view all the examples [here](examples/).
### **Library functions**
#### **`EEPROM.read( address )`** [[_example_]](examples/eeprom_read/eeprom_read.ino)
This function allows you to read a single byte of data from the eeprom.
Its only parameter is an `int` which should be set to the address you wish to read.
The function returns an `unsigned char` containing the value read.
#### **`EEPROM.write( address, value )`** [[_example_]](examples/eeprom_write/eeprom_write.ino)
The `write()` method allows you to write a single byte of data to the EEPROM.
Two parameters are needed. The first is an `int` containing the address that is to be written, and the second is a the data to be written (`unsigned char`).
This function does not return any value.
#### **`EEPROM.update( address, value )`** [[_example_]](examples/eeprom_update/eeprom_update.ino)
This function is similar to `EEPROM.write()` however this method will only write data if the cell contents pointed to by `address` is different to `value`. This method can help prevent unnecessary wear on the EEPROM cells.
This function does not return any value.
#### **`EEPROM.get( address, object )`** [[_example_]](examples/eeprom_get/eeprom_get.ino)
This function will retrieve any object from the EEPROM.
Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, 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 conveience.
#### **`EEPROM.put( address, object )`** [[_example_]](examples/eeprom_put/eeprom_put.ino)
This function will write any object to the EEPROM.
Two parameters are needed to call this function. The first is an `int` 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 conveience.
#### **Subscript operator: `EEPROM[address]`** [[_example_]](examples/eeprom_crc/eeprom_crc.ino)
This operator allows using the identifier `EEPROM` like an array.
EEPROM cells can be read _and_ **_written_** directly using this method.
This operator returns a reference to the EEPROM cell.
```c++
unsigned char val;
//Read first EEPROM cell.
val = EEPROM[ 0 ];
//Write first EEPROM cell.
EEPROM[ 0 ] = val;
//Compare contents
if( val == EEPROM[ 0 ] ){
//Do something...
}
```
#### **`EEPROM.length()`**
This function returns an `unsigned int` containing the number of cells in the EEPROM.
---
### **Advanced features**
This library uses a component based approach to provide its functionality. This means you can also use these components to design a customized approach. Two background classes are available for use: `EERef` & `EEPtr`.
#### **`EERef` class**
This object references an EEPROM cell.
Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM.
This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell.
```C++
EERef ref = EEPROM[ 10 ]; //Create a reference to 11th cell.
ref = 4; //write to EEPROM cell.
unsigned char val = ref; //Read referenced cell.
```
#### **`EEPtr` class**
This object is a bidirectional pointer to EEPROM cells represented by `EERef` objects.
Just like a normal pointer type, this type can be dereferenced and repositioned using
increment/decrement operators.
```C++
EEPtr ptr = 10; //Create a pointer to 11th cell.
*ptr = 4; //dereference and write to EEPROM cell.
unsigned char val = *ptr; //dereference and read.
ptr++; //Move to next EEPROM cell.
```
#### **`EEPROM.begin()`**
This function returns an `EEPtr` pointing to the first cell in the EEPROM.
This is useful for STL objects, custom iteration and C++11 style ranged for loops.
#### **`EEPROM.end()`**
This function returns an `EEPtr` pointing at the location after the last EEPROM cell.
Used with `begin()` to provide custom iteration.
**Note:** The `EEPtr` returned is invalid as it is out of range. Infact the hardware causes wrapping of the address (overflow) and `EEPROM.end()` actually references the first EEPROM cell.

View File

@ -38,7 +38,7 @@ unsigned long eeprom_crc( void ){
unsigned long crc = ~0L;
for( int index = 0 ; index < 32 ; ++index ){
for( int index = 0 ; index < EEPROM.length() ; ++index ){
crc = crc_table[( crc ^ EEPROM[index] ) & 0x0f] ^ (crc >> 4);
crc = crc_table[( crc ^ ( EEPROM[index] >> 4 )) & 0x0f] ^ (crc >> 4);
crc = ~crc;

View File

@ -20,7 +20,7 @@
void setup(){
float f = 0.00f; //Variable to store data read from EEPROM.
int eeAddress = 0; //Location of the IP address inside the class.
int eeAddress = 0; //EEPROM address to start reading from
Serial.begin( 9600 );
Serial.print( "Read float from EEPROM: " );

View File

@ -51,22 +51,6 @@ void setup() {
idx++;
}while( idx < EEPROM.length() );
/***
Iterate the EEPROM using a C++11 ranged for loop.
This version of the loop is best explained in the example 'eeprom_pointer'
as this kind of iteration uses pointers rather than an index/integer.
!! Note: C++11 is not yet enabled by default in any IDE version.
Unless you manually enable it, this sketch will not compile.
You can comment the loop below to verify the non C++11 content.
***/
for( auto cell : EEPROM ){
//Add one to each cell in the EEPROM
cell += 1;
}
} //End of setup function.

View File

@ -1,74 +0,0 @@
/***
eeprom_pointer example.
This example shows how the built-in EEPtr
object can be used to manipulate the EEPROM
using standard pointer arithmetic.
Running this sketch is not necessary, this is
simply highlighting certain programming methods.
Written by Christopher Andrews 2015
Released under MIT licence.
***/
#include <EEPROM.h>
void setup() {
Serial.begin(9600);
/***
In this example, we will iterate forward over the EEPROM,
starting at the 10th cell (remember indices are zero based).
***/
EEPtr ptr = 9;
//Rather than hard coding a length, we can use the provided .length() function.
while( ptr < EEPROM.length() ){
Serial.print( *ptr, HEX ); //Print out hex value of the EEPROM cell pointed to by 'ptr'
Serial.print( ", " ); //Separate values with a comma.
ptr++; //Move to next cell
}
/***
In this example, we will iterate backwards over the EEPROM,
starting at the last cell.
***/
ptr = EEPROM.length() - 1;
do{
Serial.print( *ptr, HEX );
Serial.print( ", " );
}while( ptr-- ); //When the pointer reaches zero the loop will end as zero is considered 'false'.
/***
And just for clarity, the loop below is an equivalent implementation
of the C++11 ranged for loop.
***/
for( EEPtr ptr = EEPROM.begin() ; ptr != EEPROM.end() ; ++ptr ){
Serial.print( *ptr, HEX );
Serial.print( ", " );
}
/***
The actual C++11 version:
for( auto ptr : EEPROM ){
Serial.print( *ptr, HEX );
Serial.print( ", " );
}
***/
}
void loop(){}

View File

@ -16,6 +16,12 @@
#include <EEPROM.h>
struct MyObject{
float field1;
byte field2;
char name[10];
};
void setup(){
Serial.begin(9600);
@ -31,12 +37,6 @@ void setup(){
/** Put is designed for use with custom structures also. **/
struct MyObject{
float field1;
byte field2;
char name[10];
};
//Data to store.
MyObject customVar = {
3.14f,

View File

@ -42,15 +42,15 @@ void loop()
Rather than hard-coding the length, you should use the pre-provided length function.
This will make your code portable to all AVR processors.
***/
addr = addr + 1;
if(addr == EEPROM.length())
addr = 0;
address = address + 1;
if(address == EEPROM.length())
address = 0;
/***
As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an
EEPROM address is also doable by a bitwise and of the length - 1.
++addr &= EEPROM.length() - 1;
++address &= EEPROM.length() - 1;
***/
delay(500);

View File

@ -1,93 +0,0 @@
/***
eeprom_reference example.
This example shows how to use the EEPROM
reference object EERef, which allows usage
similar to using a simple char (uint8_t in this case).
Running this sketch is not necessary, this is
simply highlighting certain programming methods.
Written by Christopher Andrews 2015
Released under MIT licence.
***/
#include <EEPROM.h>
void setup() {
/***
To create a reference to an EEPROM cell, simply create an EERef variable.
To let it know which cell you want to reference, you can simply assign the
address when you create it.
***/
EERef ref = 0;
/***
An equivalent way is by calling the constructor directly:
EERef ref( 0 );
***/
/** Using the reference **/
/***
Updating cell data.
To prevent unnecessary wear on the EEPROM cells
this function will only write the data when it
is different to what is already stored.
***/
ref.update( 44 ); //May write 44 if not present.
ref.update( 44 ); //This second call will not write anything.
/***
Assign values directly to the EEPROM cell.
You can use any form of assignment that would otherwise be available
to a standard uint8_t:
*=
/=
+=
-=
^=
%=
&=
|=
<<=
>>=
***/
ref = 4; /***
Take care to notice, this changes the EEPROM cell data, it does not
change the index of the cell referenced by 'ref'.
Only the initial declaration like 'EERef ref = 0;' will set the address.
Using an assignment anywhere else modifies the referenced cell.
To modify the referenced address after declaring your variable see below.
***/
/***
Changing the referenced object.
The class has a member named 'index' which is an integer you can modify.
***/
ref.index++; //Move reference to the next cell.
/***
Grouping of references.
Using EERef objects you can create a contiguous array referencing
non-contiguous EEPROM cells.
***/
EERef array[] = { 0, 20, 40, 60, 80 };
} //End of setup function.
void loop(){}

View File

@ -14,7 +14,7 @@
#include <EEPROM.h>
/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/
int addr = 0;
int address = 0;
void setup(){ /** EMpty setup **/ }
@ -32,13 +32,13 @@ void loop()
these values will remain there when the board is
turned off.
***/
EEPROM.update(addr, val);
EEPROM.update(address, val);
/***
The function EEPROM.update(addr, val) is equivalent to the following:
The function EEPROM.update(address, val) is equivalent to the following:
if( EEPROM.read(addr) != val ){
EEPROM.write(addr, val);
if( EEPROM.read(address) != val ){
EEPROM.write(address, val);
}
***/
@ -54,15 +54,15 @@ void loop()
Rather than hard-coding the length, you should use the pre-provided length function.
This will make your code portable to all AVR processors.
***/
addr = addr + 1;
if(addr == EEPROM.length())
addr = 0;
address = address + 1;
if(address == EEPROM.length())
address = 0;
/***
As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an
EEPROM address is also doable by a bitwise and of the length - 1.
++addr &= EEPROM.length() - 1;
++address &= EEPROM.length() - 1;
***/
delay(100);