Documente Academic
Documente Profesional
Documente Cultură
//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
}
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
Circuit
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.
***/
/***
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.
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.
delay(100);
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EEPROM
write()
Description
Syntax
EEPROM.write(address, value)
Parameters
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
Returns
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
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()
{
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EEPROM
put()
Description
Syntax
EEPROM.put(address, data)
Parameters
data: the data to write, can be a primitive type (eg. float) or a custom struct
Returns
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.
#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
}
//One simple call, with the address first and the object second.
EEPROM.put(eeAddress, f);
/** 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
Syntax
EEPROM.get(address, data)
Parameters
data: the data to read, can be a primitive type (eg. float) or a custom struct
Returns
Example
#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 Leonardo only
}
Serial.print( "Read float from EEPROM: " );
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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
Circuit
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.
***/
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
Circuit
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
}
void loop() {
/* Empty loop */
}
>>>>>>>>>>>>>>>>>>>>>>>>
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
Circuit
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.
#include <EEPROM.h>
void setup() {
/***
Iterate the EEPROM using a for loop.
***/
/***
Iterate the EEPROM using a while loop.
***/
int index = 0;
/***
Iterate the EEPROM using a do-while loop.
***/
int idx = 0; //Used 'idx' to avoid name conflict with 'index' above.
do {
void loop() {}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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.
#include <EEPROM.h>
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);
}
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.
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:
>>>>>>>>>>>>>>>>>>>>>>>>>>>
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.
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.
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.
#include <EEPROM.h>
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.
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:
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
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!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>