Найти в Дзене
IOT ENTERPRISE ©

EEPROM обновление данных в памяти ARDUINO

/***
Метод обновления EEPROM
Сохраняет значения, считанные с аналогового входа 0, в EEPROM.
Эти значения останутся в EEPROM после выключения платы
и могут быть извлечены позже другим скетчем.
Если значение в EEPROM не изменилось, оно не перезаписывается —
это позволяет неоправданно не сокращать срок службы EEPROM.
Распространяется под лицензией MIT.
***/
#include <EEPROM.h> // Подключаем библиотеку для работы с EEPROM
/** Текущий адрес в EEPROM (т. е. байт, в который будем записывать данные следующим) **/
int address = 0;
void setup() {
/** Пустая функция setup — здесь ничего не делаем **/
}
void loop() {
/***
Нужно разделить на 4, потому что аналоговые входы возвращают значения
от 0 до 1023, а каждый байт EEPROM может хранить только значение
от 0 до 255.
***/
int val = analogRead(0) / 4; // Считываем значение с аналогового входа 0 и уменьшаем в 4 раза
/***
Обновляем конкретную ячейку EEPROM.
Эти значения останутся там по
Оглавление

/***
Метод обновления EEPROM


Сохраняет значения, считанные с аналогового входа 0, в EEPROM.
Эти значения останутся в EEPROM после выключения платы
и могут быть извлечены позже другим скетчем.

Если значение в EEPROM не изменилось, оно не перезаписывается —
это позволяет неоправданно не сокращать срок службы EEPROM.

Распространяется под лицензией MIT.
***/

#include <EEPROM.h> // Подключаем библиотеку для работы с EEPROM

/** Текущий адрес в EEPROM (т. е. байт, в который будем записывать данные следующим) **/
int address = 0;


void setup() {
/** Пустая функция setup — здесь ничего не делаем **/
}

void loop() {
/***
Нужно разделить на 4, потому что аналоговые входы возвращают значения
от 0 до 1023, а каждый байт EEPROM может хранить только значение
от 0 до 255.
***/
int val = analogRead(0) / 4; // Считываем значение с аналогового входа 0 и уменьшаем в 4 раза


/***
Обновляем конкретную ячейку EEPROM.
Эти значения останутся там после выключения платы.
***/
EEPROM.update(address, val); // Записываем значение val по адресу address, если оно отличается от текущего


/***
Функция EEPROM.update(address, val) эквивалентна следующему коду:


if (EEPROM.read(address) != val) {
EEPROM.write(address, val);
}
***/

/***
Переходим к следующему адресу; когда достигнем конца — возвращаемся в начало.


Разные AVR‑процессоры имеют разный объём EEPROM, например:
- Arduino Duemilanove: 512 Б;
- Arduino Uno: 1024 Б (1 КБ);
- Arduino Mega: 4096 Б (4 КБ).


Вместо жёсткого задания размера используем встроенную функцию length(),
чтобы код работал на всех AVR‑процессорах.
***/
address = address + 1; // Увеличиваем адрес на 1
if (address == EEPROM.length()) { // Если достигли конца EEPROM
address = 0; // Возвращаемся к началу (адрес 0)
}

/***
Поскольку размеры EEPROM — степени двойки, перенос адреса (предотвращение переполнения)
можно сделать с помощью битовой операции «И» с длиной −1.

++address &= EEPROM.length() - 1;
***/

delay(100); // Ждём 100 мс перед следующей итерацией
}

Пояснение к коду

  1. #include <EEPROM.h>
    Подключает библиотеку EEPROM, необходимую для работы с энергонезависимой памятью микроконтроллера.
  2. int address = 0;
    Глобальная переменная, хранящая текущий адрес в EEPROM, куда будут записываться данные (начинаем с 0).
  3. void setup()
    Пустая функция, выполняемая один раз при запуске программы. В данном скетче не требует инициализации.
  4. void loop()
    Функция, выполняющаяся непрерывно после setup():
    int val = analogRead(0) / 4; — считывает значение с аналогового входа A0 (диапазон 0–1023) и делит на 4, чтобы уместить в диапазон 0–255 (один байт EEPROM).
    EEPROM.update(address, val); — записывает значение val в EEPROM по адресу address,
    только если оно отличается от уже хранящегося там. Это экономит ресурс памяти (число циклов записи).
    address = address + 1; — увеличивает адрес на 1 для перехода к следующей ячейке.
    if (address == EEPROM.length()) { address = 0; } — если достигли конца EEPROM (адрес равен длине памяти), сбрасывает адрес в 0 (циклическая запись).
    delay(100); — задержка 100 мс между итерациями, чтобы не перегружать EEPROM частыми записями.
  5. Комментарии о работе с EEPROM
    EEPROM.length()
    — возвращает размер EEPROM в байтах (зависит от модели платы). Использование этой функции делает код переносимым между разными AVR‑микроконтроллерами.
    EEPROM.update() — «умная» запись: проверяет, изменилось ли значение, и записывает только при необходимости. Это критично, так как EEPROM имеет ограниченный ресурс циклов записи (обычно ~100 000).
    Битовая операция ++address &= EEPROM.length() - 1 — альтернативный способ циклического увеличения адреса (работает только если размер EEPROM — степень двойки).

Ключевые моменты

  • Аналоговый вход → EEPROM: значение с A0 масштабируется (/4) для соответствия диапазону байта.
  • Обновление, а не перезапись: EEPROM.update() предотвращает лишний износ памяти.
  • Циклическая запись: после последнего байта адрес возвращается в 0.
  • Переносимость кода: использование EEPROM.length() вместо жёстких чисел позволяет работать с разными платами.