Менеджер EEPROM - библиотека для уменьшения износа памяти
- Отложенная запись (обновление) по таймеру
- Работает на базе стандартной EEPROM.h
- Встроенный механизм ключа первой записи
Для esp8266 и esp32 гораздо лучше хранить данные в файловой системе, используйте библиотеку FileData (бинарные данные в файле) или Pairs (человеко-читаемые файлы)
Совместима со всеми Arduino платформами (используются Arduino-функции)
- Для esp8266 не забудь вызвать EEPROM.begin(размер)!
EEManager(T& data, uint16_t tout = 5000);
EEManager(void* data, uint16_t size, uint16_t tout = 5000);
// Начать работу, прочитать данные в переменную.
// Принимает адрес начала хранения даты и ключ
// Возвращает:
// 0 - ключ совпал, данные прочитаны из епром
// 1 - ключ не совпал (первый запуск), данные записаны в епром
// 2 - ошибка, в епроме не хватает места
uint8_t begin(uint16_t addr, uint8_t key);
void setTimeout(uint16_t tout = 5000); // сменить таймаут
void updateNow(); // обновить данные в еепром сейчас
void update(); // отложить обновление и сбросить таймер
void stop(); // отменить отложенное обновление
bool tick(); // тикер обновления
void reset(); // сбросить ключ запуска. При перезагрузке (или вызове begin) запишутся стандартные данные
uint16_t dataSize(); // получить размер данных
uint16_t blockSize(); // получить размер всего блока (данные + ключ)
uint16_t keyAddr(); // получить адрес ключа (совпадает с переданным в begin())
uint16_t startAddr(); // получить адрес первого байта данных в блоке (равен адресу в begin() + 1)
uint16_t endAddr(); // получить адрес последнего байта в блоке
uint16_t nextAddr(); // получить первый свободный адрес для следующего блока
Общие функции/макросы
EEBlock(data); // возвращает размер указанных данных data (любой тип) +1 на ключ (для вычисления адресов блоков в памяти)
- Объявить переменную, в которой хранятся данные (целочисленная, массив, структура...)
- Передать её в EEManager:
EEManager memory(data);
2.1 [Только для ESP] Запустить EEPROM с указанием размера:EEPROM.begin(размер);
. Если будут храниться ТОЛЬКО указанные данные, можно сделать так:EEPROM.begin(memory.blockSize());
- Запустить менеджер
memory.begin(адрес, ключ);
- Адрес - начиная с этого адреса блок будет храниться в памяти (сначала ключ, потом данные)
- Ключ - метка "первой записи" типа
byte
(можно использовать символ). Если сменить ключ - данные перезапишутся из переменной, т.е. сбросятся до умолчаний
- Вызывать
memory.tick()
внутриloop()
- После изменения данных вызвать
memory.update()
- данные в EEPROM обновятся автоматически спустя таймаут внутри функцииtick()
- Ключ "первой записи" хранится в самом начале блока (по указанному в begin() адресу), поэтому при изменении размера записываемых данных не пострадает
Библиотека позволяет отложить запись данных на заданный таймаут, таким образом при настройке параметров девайса (кнопками/крутилками) можно безопасно вызывать update() после каждого изменения, так как данные запишутся спустя таймаут после прекращения изменений.
// структура для хранения данных
struct Data {
char val = 'H';
char str[15] = "ello kitty!";
};
Data data; // переменная, с которой мы работаем в программе
#include <EEManager.h> // подключаем либу
EEManager memory(data); // передаём нашу переменную (фактически её адрес)
// можно задать таймаут обновления, по умолч. 5 секунд (5000мс)
//EEManager memory(data, 1000);
void setup() {
Serial.begin(9600);
// для esp8266 не забудь вызвать EEPROM.begin(размер)!
/*
Запускаем менеджер, передаём:
- Стартовый адрес в памяти для записи даты
- Ключ хранения (0.. 255) или символ
*/
byte stat = memory.begin(0, 'b');
/*
Коды возврата:
0 - ключ совпал, данные прочитаны из епром
1 - ключ не совпал (первый запуск), данные записаны в епром
2 - ошибка, в епроме не хватает места
*/
Serial.println(stat);
// выведем в порт всё содержимое блока памяти, включая ключ
for (uint16_t i = memory.startAddr(); i < memory.endAddr() + 1; i++)
Serial.write(EEPROM.read(i));
Serial.println();
data.val = 'X'; // изменим данные в переменной
memory.update(); // отложим обновление
// примечание: если нужно создать ещё один блок следующим в памяти -
// запускаем его на адресе memory.endAddr() + 1, это первый
// свободный байт после первого блока
}
void loop() {
// в лупе вызываем tick(), в нём по таймеру произойдёт обновление
// функция вернёт true, когда это случится
if (memory.tick()) Serial.println("Updated!");
// выведем в порт всё содержимое блока памяти, включая ключ
for (uint16_t i = memory.startAddr(); i < memory.endAddr() + 1; i++)
Serial.write(EEPROM.read(i));
Serial.println();
// таймер сброса на 10 секунд: через 10 секунд
// произойдёт сброс ключа данных, и при следующем запуске
// в епром будут записаны данные по умолчанию (то что в ярлыке структуры)
static uint32_t tmr;
if (millis() - tmr >= 10000) {
memory.reset();
Serial.println("reset");
for (;;);
}
delay(1000); // чилим
}
- v1.0
- v1.1 - изменены коды возврата begin
- v1.2 - добавлена nextAddr()
- v1.2.1 - поддержка esp32
- v1.2.2 - пофиксил варнинг
- v1.3 - исправлен критический баг с адресацией, добавлен макрос EEBlock
- v1.4 - ещё больше поддержки esp8266/32
- v2.0 - ключ запуска перенесён в начало блока для удобства. Обновление библиотеки сбросит данные в EEPROM!
- Библиотеку можно найти по названию EEManager и установить через менеджер библиотек в:
- Arduino IDE
- Arduino IDE v2
- PlatformIO
- Скачать библиотеку .zip архивом для ручной установки:
- Распаковать и положить в C:\Program Files (x86)\Arduino\libraries (Windows x64)
- Распаковать и положить в C:\Program Files\Arduino\libraries (Windows x32)
- Распаковать и положить в Документы/Arduino/libraries/
- (Arduino IDE) автоматическая установка из .zip: Скетч/Подключить библиотеку/Добавить .ZIP библиотеку… и указать скачанный архив
- Читай более подробную инструкцию по установке библиотек здесь
- Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
- Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
- Вручную: удалить папку со старой версией, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
При нахождении багов создавайте Issue, а лучше сразу пишите на почту alex@alexgyver.ru
Библиотека открыта для доработки и ваших Pull Request'ов!
При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
- Версия библиотеки
- Какой используется МК
- Версия SDK (для ESP)
- Версия Arduino IDE
- Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
- Какой код загружался, какая работа от него ожидалась и как он работает в реальности
- В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код