====== Энергонезависимая память Arduino ======
===== Понятия =====
EEPROM или энергонезависимая память - память, которая может стираться и записываться большое количество раз, при этом данные в такой памяти хранятся независимо от питания контроллера.

Размер памяти EEPROM различается в зависимости от типа контроллера. Размер памяти у популярных контроллеров обозначен в таблице ниже.

^ Наименование платы  ^ Наименование контроллера  ^ Объём памяти  ^
| Arduino UNO         | ATmega328                 | 1 Кб          |
| Smart UNO           | ATmega328                 | 1 Кб          |
| Arduino Mega        | ATmega2560                | 4 Кб          |
| Smart Mega          | ATmega2560                | 4 Кб          |
| Arduino Leonardo    | ATmega32u4                | 1 Кб          |
| Smart Leionardo     | ATmega32u4                | 1 Кб          |
| Arduino Due         | AT91SAM3X8E               | нет EEPROM    |
| Nano, Pro Mini      | ATmega328                 | 1 Кб          |
| Pro Micro           | ATmega32u4                | 1 Кб          |

Обратите внимание, что на контроллерах Arduino Due EEPROM-память отсутствует. Запись возможна только во Flash-память.

//Внимание! Производитель заявляет, что память EEPROM имеет жизненный цикл в 100000 раз записи/стирания, хранение информации возможно до 100 лет при температуре 25°С. Чтение данных ограничений не имеет. В связи с этим, старайтесь осторожнее относиться к операциям записи и стирания в своих скетчах. Минимальное время, требуемое для процесса записи в память составляет 3,3 мс. При использовании библиотеки EEPROM в среде Arduino эта особенность уже учтена в коде библиотеки, поэтому дополнительно закладывать время на запись не требуется.//

В Arduino IDE уже встроена библиотека для работы с энергонезависимой памятью - EEPROM.

===== Примеры работы =====
==== Запись байта данных. write() ====
Для того чтобы записать байт данных в требуемую ячейку памяти, необходимо вызвать метод write()

<file Arduino>
#include <EEPROM.h> //подключение библиотеки для работы с энергонезависимой памятью

int address = 0;    //адрес ячейки памяти для записи данных
byte value = 111;   //значение для записи в ячейку

void setup() {
  EEPROM.write(address, value); //запись данных value в ячейку по адресу address
}

void loop() {

}
</file>

==== Обновление данных. update() ====
Так как память имеет ограниченное число циклов записи, лучше пользоваться методом update() для записи данных. В отличии от write() он записывает данные, только в случае, если они отличаются от уже сохранённых.

<file Arduino>
#include <EEPROM.h> //подключение библиотеки для работы с энергонезависимой памятью

int address = 0;    //адрес ячейки памяти для записи данных
byte value = 111;   //значение для записи в ячейку

void setup() {
  EEPROM.update(address, value); //обновление данных value в ячейке по адресу address
}

void loop() {

}
</file>

==== Запись произвольного типа данных. put() ====
В отличии от метода write(), который позволяет сохранить байт данных, существует метод put(), который расширяет возможности до записи произвольных значений: примитивных типов (например, int или float) или пользовательских структур. Однако, следует внимательнее работать с данным методом, потому как с помощью него запись происходит не в одну конкретную ячейку, а в ряд ячеек. 

<file Arduino>
#include <EEPROM.h> //подключение библиотеки для работы с энергонезависимой памятью

int address = 10;    //адрес ячейки памяти для записи данных
float value = 36.6;   //значение для записи в ячейку

void setup() {
  EEPROM.put(address, value); //запись данных value типа float в ячейки, начиная с address
}

void loop() {

}
</file>

==== Чтение произвольного типа данных. get() ====
Для того чтобы получить данные, записанные методом put() (прочитать информацию из ряда ячеек), нужно воспользоваться методом get().

<file Arduino>
#include <EEPROM.h> //подключение библиотеки для работы с энергонезависимой памятью

int address = 10;    //адрес ячейки памяти для записи данных
float value = 0.0;   //значение для чтения из ячейки

void setup() {
  Serial.begin(9600); //инициализация монитора Serial-потра
  EEPROM.get(address, value); //получение данных value типа float из ячейки, начиная с address
  Serial.println(value, 1); //вывести число с одним знаком после запятой
}

void loop() {

}
</file>

==== Чтение из ячейки памяти. read() ====
Для чтения данных из определенной ячейки памяти нужно воспользоваться методом read().

<file Arduino>
#include <EEPROM.h>                     //подключение библиотеки для работы с энергонезависимой памятью

int address = 0;                        //адрес ячейки памяти для чтения данных
byte value = 0;                         //значение для чтения из ячейки

void setup() {
  Serial.begin(9600);                   //инициализация монитора Serial-порта
  value = EEPROM.read(address);         //чтение данных в value из ячейки по адресу address
  Serial.println(value);                //вывести данные
}

void loop() {

}
</file>

==== Чтение всех данных из памяти. Определение размера памяти. length() ====
Так как в разных контроллерах различное количество встроенной памяти, можно прочитать данные всех ячеек, перед этим определив размер данных. Для этого следует воспользоваться методом length().

<file Arduino>
#include <EEPROM.h>                     //подключение библиотеки для работы с энергонезависимой памятью

int address = 0;                        //адрес ячейки памяти для чтения данных
byte value = 0;                         //значение для чтения из ячейки

void setup() {
  Serial.begin(9600);                   //инициализация монитора Serial-потра
  int memory_size = EEPROM.length();    //вычисление объёма памяти
  while (address < memory_size) {       //цикл по ячейкам памяти
    value = EEPROM.read(address);       //запись данных value в ячейку по адресу address
    Serial.println(value);              //вывести значение
    address++;                          //увеличение адреса читаемой ячейки
  }  
}

void loop() {

}
</file>

//Обратите внимание, что ячейки памяти, которые изначально не содержали данных, имеют значение 255//