Sunteți pe pagina 1din 25

EEPROM space, as already mentioned, will work if non-volatile is required.

However, you have not


qualified if it needs to be non-volatile or not. If not then you can use an __attribute__ to define the
variable space not to be initialized. As the SRAM on the ATmega's are not cleared by reset or power
cycle. The Compiler defaults to initializing them. Where this can be turned off per variable as in the
below example:

//non-initialized value
union configUnion{
uint8_t byte[6]; // match the below struct...
struct {
uint16_t value1;
uint16_t value2;
uint16_t chksum;
} val ;
} config __attribute__ ((section (".noinit")));

void setup() {
uint16_t sum;
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}

// prints title with ending line break


Serial.print("Out of Reset -");
sum = getchksum();
printValues();

if (sum != config.val.chksum) {
config.val.chksum = sum;
Serial.print("chksum is incorrect setting config.val.chksum = 0x");
Serial.println(config.val.chksum, HEX);
}

config.val.value1++;
config.val.value2++;
Serial.print("setup new values - ");
printValues();
config.val.chksum = getchksum();
Serial.print("updating chksum config.val.chksum = 0x");
Serial.println(config.val.chksum, HEX);
}

int counter = 0;

void loop() {
if (counter < 200) {
Serial.print("after a while - ");
printValues();
Serial.println();
while (true) {
continue;
}
}
counter++;
}

void printValues() {
Serial.print(" value1 = 0x"); Serial.print(config.val.value1, HEX);
Serial.print(", value2 = 0x"); Serial.print(config.val.value2, HEX);
Serial.print(", sum = 0x"); Serial.print(getchksum(), HEX);
Serial.print(", chksum = 0x"); Serial.println(config.val.chksum, HEX);
}

uint16_t getchksum() {
int sum = 0;
for (int position = 0; position < (sizeof(config) - sizeof(config.val.chksum));
position++) {
sum = sum + config.byte[position];
}
return sum;
}

Output of above code is below. Note that the first output was the result of powering the UNO up with
the Reset button depressed and then released after the Monitor window was started. Otherwise the
"incorrect setting" print would have been missed, before the monitor window can be started.

Out of Reset - value1 = 0xBFED, value2 = 0xD2F9, sum = 0x377, chksum = 0xF457
chksum is incorrect setting config.val.chksum = 0x377
setup new values - value1 = 0xBFEE, value2 = 0xD2FA, sum = 0x379, chksum = 0x377
updating chksum config.val.chksum = 0x379
after a while - value1 = 0xBFEE, value2 = 0xD2FA, sum = 0x379, chksum = 0x379

Out of Reset - value1 = 0xBFEE, value2 = 0xD2FA, sum = 0x379, chksum = 0x379
setup new values - value1 = 0xBFEF, value2 = 0xD2FB, sum = 0x37B, chksum = 0x379
updating chksum config.val.chksum = 0x37B
after a while - value1 = 0xBFEF, value2 = 0xD2FB, sum = 0x37B, chksum = 0x37B

Out of Reset - value1 = 0xBFEF, value2 = 0xD2FB, sum = 0x37B, chksum = 0x37B
setup new values - value1 = 0xBFF0, value2 = 0xD2FC, sum = 0x37D, chksum = 0x37B
updating chksum config.val.chksum = 0x37D
after a while - value1 = 0xBFF0, value2 = 0xD2FC, sum = 0x37D, chksum = 0x37D

With this your variables will persist resets. As long as the power is not lost. Noting the above where you
will get random data, to start.

Using either EEPROM or .noinit I would recommend that you checksum your persistent variable space
during setup and if incorrect you can initialize or issue a warning.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

EEPROM Write
The microcontroller on the Arduino and Genuino boards have 512 bytes of EEPROM: memory whose
values are kept when the board is turned off (like a tiny hard drive).
This example illustrates how to store values read from analog input 0 into the EEPROM using the
EEPROM.write() function. These values will stay in the EEPROM when the board is turned off and
may be retrieved later by another sketch.

Hardware Required

 Arduino or Genuino Board

Circuit

There is no circuit for this example.

image developed using Fritzing. For more circuit examples, see the Fritzing project page

Schematics

image developed using Fritzing. For more circuit examples, see the Fritzing project page

Code

/*
* EEPROM Write
*
* Stores values read from analog input 0 into the EEPROM.
* These values will stay in the EEPROM when the board is
* turned off and may be retrieved later by another sketch.
*/

#include <EEPROM.h>

/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/
int addr = 0;

void setup() {
/** Empty setup. **/
}

void loop() {
/***
Need to divide by 4 because analog inputs range from
0 to 1023 and each byte of the EEPROM can only hold a
value from 0 to 255.
***/

int val = analogRead(0) / 4;

/***
Write the value to the appropriate byte of the EEPROM.
these values will remain there when the board is
turned off.
***/

EEPROM.write(addr, val);

/***
Advance to the next address, when at the end restart at the beginning.

Larger AVR processors have larger EEPROM sizes, E.g:


- Arduno Duemilanove: 512b EEPROM storage.
- Arduino Uno: 1kb EEPROM storage.
- Arduino Mega: 4kb EEPROM storage.

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;
}

/***
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;


***/

delay(100);
}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

EEPROM

write()
Description

Write a byte to the EEPROM.

Syntax

EEPROM.write(address, value)

Parameters

address: the location to write to, starting from 0 (int)

value: the value to write, from 0 to 255 (byte)

Returns

none

Note

An EEPROM write takes 3.3 ms to complete. The EEPROM memory has a specified life of 100,000
write/erase cycles, so you may need to be careful about how often you write to it.

Example

#include <EEPROM.h>

void setup()
{
for (int i = 0; i < 255; i++)
EEPROM.write(i, i);
}

void loop()
{
}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

EEPROM
read()
Description

Reads a byte from the EEPROM. Locations that have never been written to have the value of 255.

Syntax

EEPROM.read(address)

Parameters

address: the location to read from, starting from 0 (int)

Returns

the value stored in that location (byte)

Example
#include <EEPROM.h>

int a = 0;
int value;

void setup()
{
Serial.begin(9600);
}

void loop()
{
value = EEPROM.read(a);

Serial.print(a);
Serial.print("\t");
Serial.print(value);
Serial.println();

a = a + 1;

if (a == 512)
a = 0;

delay(500);
}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EEPROM

update()
Description

Write a byte to the EEPROM. The value is written only if differs from the one already saved at the same
address.

Syntax

EEPROM.update(address, value)

Parameters

address: the location to write to, starting from 0 (int)

value: the value to write, from 0 to 255 (byte)

Returns

none

Note

An EEPROM write takes 3.3 ms to complete. The EEPROM memory has a specified life of 100,000
write/erase cycles, so using this function instead of write() can save cycles if the written data does not
change often

Example

#include <EEPROM.h>

void setup()
{
for (int i = 0; i < 255; i++) {
// this performs as EEPROM.write(i, i)
EEPROM.update(i, i);
}
for (int i = 0; i < 255; i++) {
// write value "12" to cell 3 only the first time
// will not write the cell the remaining 254 times
EEPROM.update(3, 12);
}
}

void loop()
{
}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Reference Language | Libraries | Comparison | Changes

EEPROM

put()
Description

Write any data type or object to the EEPROM.

Syntax

EEPROM.put(address, data)

Parameters

address: the location to write to, starting from 0 (int)

data: the data to write, can be a primitive type (eg. float) or a custom struct

Returns

A reference to the data passed in

Note

This function uses EEPROM.update() to perform the write, so does not rewrites the value if it didn't
change.

Example
/***
eeprom_put example.

This shows how to use the EEPROM.put() method.


Also, this sketch will pre-set the EEPROM data for the
example sketch eeprom_get.

Note, unlike the single byte version EEPROM.write(),


the put method will use update semantics. As in a byte
will only be written to the EEPROM if the data is actually
different.

Written by Christopher Andrews 2015


Released under MIT licence.
***/

#include <EEPROM.h>

struct MyObject {
float field1;
byte field2;
char name[10];
};

void setup() {

Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

float f = 123.456f; //Variable to store in EEPROM.


int eeAddress = 0; //Location we want the data to be put.

//One simple call, with the address first and the object second.
EEPROM.put(eeAddress, f);

Serial.println("Written float data type!");

/** Put is designed for use with custom structures also. **/

//Data to store.
MyObject customVar = {
3.14f,
65,
"Working!"
};

eeAddress += sizeof(float); //Move address to the next byte after float 'f'.

EEPROM.put(eeAddress, customVar);
Serial.print("Written custom data type! \n\nView the example sketch eeprom_get to see how you can retrieve
the values!");
}

void loop() {
/* Empty loop */
}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

EEPROM

get()
Description

Read any data type or object from the EEPROM.

Syntax

EEPROM.get(address, data)

Parameters

address: the location to read from, starting from 0 (int)

data: the data to read, can be a primitive type (eg. float) or a custom struct

Returns

A reference to the data passed in

Example

#include <EEPROM.h>
struct MyObject{
float field1;
byte field2;
char name[10];
};

void setup(){

float f = 0.00f; //Variable to store data read from EEPROM.


int eeAddress = 0; //EEPROM address to start reading from

Serial.begin( 9600 );
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print( "Read float from EEPROM: " );

//Get the float data from the EEPROM at position 'eeAddress'


EEPROM.get( eeAddress, f );
Serial.println( f, 3 ); //This may print 'ovf, nan' if the data inside the EEPROM is not a valid float.

// get() can be used with custom structures too.


eeAddress = sizeof(float); //Move address to the next byte after float 'f'.
MyObject customVar; //Variable to store custom object read from EEPROM.
EEPROM.get( eeAddress, customVar );

Serial.println( "Read custom object from EEPROM: " );


Serial.println( customVar.field1 );
Serial.println( customVar.field2 );
Serial.println( customVar.name );
}

void loop(){ /* Empty loop */ }

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

EEPROM Clear
The microcontroller on the Arduino and Genuino boards have 512 bytes of EEPROM: memory whose
values are kept when the board is turned off (like a tiny hard drive).

This example illustrates how to set of all of those bytes to 0, initializing them to hold new information,
using the EEPROM.write() function.

Hardware Required

 Arduino or Genuino Board

Circuit

There is no circuit for this example.

image developed using Fritzing. For more circuit examples, see the Fritzing project page

Schematics

image developed using Fritzing. For more circuit examples, see the Fritzing project page

Code

/*
* EEPROM Clear
*
* Sets all of the bytes of the EEPROM to 0.
* Please see eeprom_iteration for a more in depth
* look at how to traverse the EEPROM.
*
* This example code is in the public domain.
*/

#include <EEPROM.h>

void setup() {
// initialize the LED pin as an output.
pinMode(13, OUTPUT);

/***
Iterate through each byte of the EEPROM storage.
Larger AVR processors have larger EEPROM sizes, E.g:
- Arduno Duemilanove: 512b EEPROM storage.
- Arduino Uno: 1kb EEPROM storage.
- Arduino Mega: 4kb EEPROM storage.

Rather than hard-coding the length, you should use the pre-provided length function.
This will make your code portable to all AVR processors.
***/

for (int i = 0 ; i < EEPROM.length() ; i++) {


EEPROM.write(i, 0);
}

// turn the LED on when we're done


digitalWrite(13, HIGH);
}

void loop() {
/** Empty loop. **/
}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

EEPROM CRC
The microcontroller on the Arduino and Genuino boards have 512 bytes of EEPROM: memory whose
values are kept when the board is turned off (like a tiny hard drive).

A CRC is a simple way of checking whether data has changed or become corrupted. This example
calculates a CRC value directly on the EEPROM values. This CRC is like a signature and any change in
the calculated CRC means a change in the stored data. The purpose of this example is to highlight how
the EEPROM object can be used just like an array.

Hardware Required

 Arduino or Genuino Board

Circuit

There is no circuit for this example.

image developed using Fritzing. For more circuit examples, see the Fritzing project page
Schematics

image developed using Fritzing. For more circuit examples, see the Fritzing project page

Code

/***
Written by Christopher Andrews.
CRC algorithm generated by pycrc, MIT licence ( https://github.com/tpircher/pycrc ).

A CRC is a simple way of checking whether data has changed or become corrupted.
This example calculates a CRC value directly on the EEPROM values.
The purpose of this example is to highlight how the EEPROM object can be used just like an array.
***/

#include <Arduino.h>
#include <EEPROM.h>

void setup() {

//Start serial
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

//Print length of data to run CRC on.


Serial.print("EEPROM length: ");
Serial.println(EEPROM.length());

//Print the result of calling eeprom_crc()


Serial.print("CRC32 of EEPROM data: 0x");
Serial.println(eeprom_crc(), HEX);
Serial.print("\n\nDone!");
}

void loop() {
/* Empty loop */
}

unsigned long eeprom_crc(void) {

const unsigned long crc_table[16] = {


0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};

unsigned long crc = ~0L;

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;
}
return crc;
}

>>>>>>>>>>>>>>>>>>>>>>>>

EEPROM Iterations
The microcontroller on the Arduino and Genuino boards have 512 bytes of EEPROM: memory whose
values are kept when the board is turned off (like a tiny hard drive).

The purpose of this example is to show how to go through the whole EEPROM memory space with
different approaches. The code provided doesn’t run on its own but should be used as a surce of code
snippets to be used elsewhere.

Hardware Required

 Arduino or Genuino Board

Circuit

There is no circuit for this example.

image developed using Fritzing. For more circuit examples, see the Fritzing project page

Schematics

image developed using Fritzing. For more circuit examples, see the Fritzing project page
Code

/***
eeprom_iteration example.

A set of example snippets highlighting the


simplest methods for traversing the EEPROM.

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() {

/***
Iterate the EEPROM using a for loop.
***/

for (int index = 0 ; index < EEPROM.length() ; index++) {

//Add one to each cell in the EEPROM


EEPROM[ index ] += 1;
}

/***
Iterate the EEPROM using a while loop.
***/

int index = 0;

while (index < EEPROM.length()) {

//Add one to each cell in the EEPROM


EEPROM[ index ] += 1;
index++;
}

/***
Iterate the EEPROM using a do-while loop.
***/
int idx = 0; //Used 'idx' to avoid name conflict with 'index' above.

do {

//Add one to each cell in the EEPROM


EEPROM[ idx ] += 1;
idx++;
} while (idx < EEPROM.length());

} //End of setup function.

void loop() {}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Save Values in Your Arduino's Permanent Memory


********************Although the Arduino Code works fine, Some Info in this Instructable is
not "Entirety" correct , please also read the comments**********************

This is a really short instructable, I never knew you could do this, actually I assumed that its not
possible, until I recently found that I was wrong, So I thought of sharing this with you.

The arduino has 512 memory address spaces where you can write data to, This means you can write a
string of 512 characters to it. You basically write an ASCII Character's ASCII Decimal value to it.

The arduino IDE comes standard with a EEPROM library.

All you you have to do is include it.

#include <EEPROM.h>

Then simply write your value to it.


Say I want to write my name to the Arduino's EEPROM.
I would convert each character in my name "MARTIN" to ASCII Decimal values.
I.E

M = 77<br>A = 65
R = 82
T = 84
I = 73
N = 78
void setup()<br>{
//EEPROM.write(ADDRESS,VALUE);<br>int MyVal=255;
EEPROM.write(0,77);<br> EEPROM.write(1,65);
EEPROM.write(2,82);<br> EEPROM.write(3,84);<br>
EEPROM.write(4,73);<br> EEPROM.write(5,78);
}

Step 1: Read the Values From Memory


You can then simply read the values again using a for loop
Try this after you switched off the Arduino and on again. It will print your saved values to the Serial
Monitor
If you want, check out this thread

http://techtinker.co.za/viewtopic.php?f=23&t=16

Its got some more detail about ASCII codes if you are not familiar with it.

#include <EEPROM.h><br>int MemoryAddr=0;<br>int Value=0;<br>void


setup()<br>{<br>Serial.begin(38400);<br>}<br>
void loop()<br>{

for (int MemoryAddr=0; MemoryAddr <= 5; MemoryAddr++)


{
value = EEPROM.read(MemoryAddr);
char MyCharacter = char(value);
Serial.println(MyCharacter);
}
delay(5000);
}
Hey, I didn't know you could do that. Thanks for this instructable!

A check on the Arduino official website shows a couple of useful tips...

From: http://arduino.cc/en/Reference/EEPROM

The EEPROM memory has a specified life of 100,000 write/erase cycles, so you may need to be careful
about how often you write to it.

The microcontrollers on the various Arduino boards have different amounts of EEPROM:

1024 bytes on the ATmega328

512 bytes on the ATmega168 and ATmega8

4096 bytes on the ATmega1280 and ATmega2560.

>>>>>>>>>>>>>>>>>>>>>>>>>>>

Did you know the Arduino can store data when it’s turned off? Not the sketch stored in flash memory.
I’m talking about variable data in the EEPROM. Join me as I show you how to read and write to it, and
what it can do for your projects.

If you’re new to Arduino, make sure you check out our beginners guide.

Getting Started With Arduino: A Beginner's Guide Arduino is an open-source electronics prototyping
platform based on flexible, easy-to use hardware and software. It's intended for artists, designers,
hobbyists, and anyone interested in creating interactive objects or environments. Read More

What Is EEPROM?
EEPROM stands for electrically erasable programmable read-only memory. It’s a type of non-
volatile memory. Don’t worry if you don’t understand what any of that means. It simply stores data even
with the power removed (unlike RAM, which needs electricity to retain any data).
EEPROM is built into a myriad of processors, such as the field-programmable gate array (FPGA) used
in the Matrix Creator Pi HAT. All Arduinos have EEPROM available, but the capacity varies per model.
Make sure you take a look at our buying guide for more details on each board.

How Does It Work?


EEPROM is electrically erased and programmed using Fowler-Nordheim tunneling. You don’t need to
know the technical details to be able to use it. The basic premise is that electricity is used to change the
binary data (what is binary). It can be read, erased, and re-written electronically.

Fortunately, the Arduino Language makes it easy to change data, all without needing a degree in
computer science.
Life Expectancy
While it is easy to use EEPROM in the Arduino, it does have a limited life. EEPROM is specified to
handle 100,000 read/erase cycles. This means you can write and then erase/re-write data 100,000 times
before the EEPROM will become unstable. In reality, Atmel (the manufacturers of the Arduino “Chip”)
semiconductors may handle a higher or lower number of cycles, depending on the tolerances of each and
every processor.

Once a location has been written and erased too many times it can start to become unreliable. It may not
return the correct data, or return the value from a neighbouring bit.

This may sound like a lot of writes, but it can be easy to reach this limit if reading and writing
programmatically (in a loop, for example). Reading data does not degrade the silicon, only writing
does. You can read data from EEPROM as much as you like without fear!

It’s important to note that this limit applies to each memory location. Your Arduino may have 1,000 or
more memory locations available in EEPROM, so if you write too many times to one location, it is only
that location impacted, and not any of the others. Later on I’ll be discussing wear levelling, which can
reduce EEPROM wear by distributing data evenly — something that SSDs make use of.

What’s It Useful For?


EEPROM is incredibly useful for your Arduino projects. As it remembers data even when the power is
removed, you could store the state of the Arduino. Maybe you could build a laser turret that remembers
its position or how much “ammo” is remaining. You could use it to control your appliances, and log how
many times your appliance was activated.

EEPROM is best suited for things like settings or high-scores. If you want to regularly write complex
data, maybe consider an ethernet shield (with built-in SD slot) or a Raspberry Pi.

Read and Write


Now that the theory is out the way, let’s look at how to read and write some data! First, include the
library (this comes with the Arduino IDE):

#include <EEPROM.h>

Now write some data:

EEPROM.write(0, 12);

This writes the number 12 to EEPROM location 0. Each write takes 3.3 milliseconds (ms, 1000ms = 1
second). Notice how you cannot write letters (char), only the numbers from zero to 255 are allowed.
This is why EEPROM is ideal for settings or high scores, but not so good for player names or words. It
is possible to store text using this method (you could map each letter of the alphabet to a number),
however you will need to have multiple memory locations — one location for each letter.

Here’s how you read that data:

EEPROM.read(0);

Zero is the address you wrote to previously. If you have not written to an address before, it will return
the maximum value (255).

There are some slightly more useful methods available. Say you wanted to store a decimal place or
string:

EEPROM.put(2,"12.67");

This writes the data to multiple locations — something that would be easy to write yourself, but handy
none the less. You will still need to keep track of how many locations this has written to, so you don’t
accidentally overwrite your data! You have to use the get method to retrieve this data again:
float f = 0.00f;
EEPROM.get(2, f);

The value from get is stored into the float f variable. Notice how this is initialized with 0.00f as the
value. The f lets the compiler know that you might want to store a large number in this variable, so it
sets up some additional configurations during compilation.

The EEPROM documentation on the Arduino website has lots more examples.

Wear Leveling
Wear leveling is a technique used to reduce the wear and increase the life of EEPROM. If you are only
working on a small project, you may not need to worry about this.

The simplest thing you can do to preserve EEPROM life is to limit your writes to a particular location.
You can do this by reading the address first, and if the value you want to write is already present, there’s
no need to write it again (remember, reading data does no harm). Here’s how you would do that:

int safeWrite(int data, address) {


if(EEPROM.read(address) != data) {
EEPROM.write(address, data);
}
}

That is quite a simple bit of code, however it only works for integers! Instead of re-inventing the wheel,
use the function built into the Arduino EEPROM library:

EEPROM.update(address, val);

This method has exactly the same signature as the write method, although it may drastically reduce the
number of writes needed!
If you need to write a lot of data, and are concerned about wearing out the silicon, you can keep track of
how many writes you do, although this uses more data. Here’s a rough implementation in pseudocode:

var address = 0
var writeCount = 0

if(writeCount > 75,000)


writeCount = 0
address += 1

EEPROM.write(address, data)

You will need to store address and writeCount in EEPROM (and writeCount will need to be split across
address locations). The majority of the time, this level of protection will not be necessary. Arduinos are
so cheap as well, so you may find it easier to purchase a backup!

You should now know enough to make some awesome projects. Let us know if you make
something cool! Can you recognise all the devices in the pictures? Leave us a comment below!

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

S-ar putea să vă placă și