├── .gitattributes ├── .github └── workflows │ └── tg-send.yml ├── LICENSE ├── README.md ├── README_EN.md ├── examples ├── demo │ └── demo.ino ├── demoSimple │ └── demoSimple.ino └── manyBlocks │ └── manyBlocks.ino ├── keywords.txt ├── library.properties └── src └── EEManager.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/workflows/tg-send.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Telegram Message 3 | on: 4 | release: 5 | types: [published] 6 | jobs: 7 | build: 8 | name: Send Message 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: send telegram message on push 12 | uses: appleboy/telegram-action@master 13 | with: 14 | to: ${{ secrets.TELEGRAM_TO }} 15 | token: ${{ secrets.TELEGRAM_TOKEN }} 16 | disable_web_page_preview: true 17 | message: | 18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }} 19 | ${{ github.event.release.body }} 20 | https://github.com/${{ github.repository }} 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 AlexGyver 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![latest](https://img.shields.io/github/v/release/GyverLibs/EEManager.svg?color=brightgreen)](https://github.com/GyverLibs/EEManager/releases/latest/download/EEManager.zip) 2 | [![PIO](https://badges.registry.platformio.org/packages/gyverlibs/library/EEManager.svg)](https://registry.platformio.org/libraries/gyverlibs/EEManager) 3 | [![Foo](https://img.shields.io/badge/Website-AlexGyver.ru-blue.svg?style=flat-square)](https://alexgyver.ru/) 4 | [![Foo](https://img.shields.io/badge/%E2%82%BD%24%E2%82%AC%20%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D1%82%D1%8C-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B0-orange.svg?style=flat-square)](https://alexgyver.ru/support_alex/) 5 | [![Foo](https://img.shields.io/badge/README-ENGLISH-blueviolet.svg?style=flat-square)](https://github-com.translate.goog/GyverLibs/EEManager?_x_tr_sl=ru&_x_tr_tl=en) 6 | 7 | [![Foo](https://img.shields.io/badge/ПОДПИСАТЬСЯ-НА%20ОБНОВЛЕНИЯ-brightgreen.svg?style=social&logo=telegram&color=blue)](https://t.me/GyverLibs) 8 | 9 | # EEManager 10 | Менеджер EEPROM - библиотека для уменьшения износа памяти 11 | - Отложенная запись (обновление) по таймеру 12 | - Работает на базе стандартной EEPROM.h 13 | - Встроенный механизм ключа первой записи 14 | 15 | > Для esp8266 и esp32 гораздо лучше хранить данные в файловой системе, используйте библиотеку [FileData](https://github.com/GyverLibs/FileData) (бинарные данные в файле) или [Pairs](https://github.com/GyverLibs/Pairs) (человеко-читаемые файлы) 16 | 17 | ### Совместимость 18 | Совместима со всеми Arduino платформами (используются Arduino-функции) 19 | - Для esp8266 не забудь вызвать EEPROM.begin(размер)! 20 | 21 | ## Содержание 22 | - [Инициализация](#init) 23 | - [Использование](#usage) 24 | - [Пример](#example) 25 | - [Версии](#versions) 26 | - [Установка](#install) 27 | - [Баги и обратная связь](#feedback) 28 | 29 | 30 | 31 | ## Инициализация 32 | ```cpp 33 | EEManager(T& data, uint16_t tout = 5000); 34 | EEManager(void* data, uint16_t size, uint16_t tout = 5000); 35 | ``` 36 | 37 | 38 | 39 | ## Документация 40 | ```cpp 41 | // Начать работу, прочитать данные в переменную. 42 | // Принимает адрес начала хранения даты и ключ 43 | // Возвращает: 44 | // 0 - ключ совпал, данные прочитаны из епром 45 | // 1 - ключ не совпал (первый запуск), данные записаны в епром 46 | // 2 - ошибка, в епроме не хватает места 47 | uint8_t begin(uint16_t addr, uint8_t key); 48 | 49 | void setTimeout(uint16_t tout = 5000); // сменить таймаут 50 | void updateNow(); // обновить данные в еепром сейчас 51 | void update(); // отложить обновление и сбросить таймер 52 | void stop(); // отменить отложенное обновление 53 | bool tick(); // тикер обновления 54 | void reset(); // сбросить ключ запуска. При перезагрузке (или вызове begin) запишутся стандартные данные 55 | 56 | uint16_t dataSize(); // получить размер данных 57 | uint16_t blockSize(); // получить размер всего блока (данные + ключ) 58 | 59 | uint16_t keyAddr(); // получить адрес ключа (совпадает с переданным в begin()) 60 | uint16_t startAddr(); // получить адрес первого байта данных в блоке (равен адресу в begin() + 1) 61 | uint16_t endAddr(); // получить адрес последнего байта в блоке 62 | uint16_t nextAddr(); // получить первый свободный адрес для следующего блока 63 | ``` 64 | 65 | Общие функции/макросы 66 | ```cpp 67 | EEBlock(data); // возвращает размер указанных данных data (любой тип) +1 на ключ (для вычисления адресов блоков в памяти) 68 | ``` 69 | 70 | ### Использование 71 | 1. Объявить переменную, в которой хранятся данные (целочисленная, массив, структура...) 72 | 2. Передать её в EEManager: `EEManager memory(data);` 73 | 2.1 *[Только для ESP]* Запустить EEPROM с указанием размера: `EEPROM.begin(размер);`. Если будут храниться ТОЛЬКО указанные данные, можно сделать так: `EEPROM.begin(memory.blockSize());` 74 | 3. Запустить менеджер `memory.begin(адрес, ключ);` 75 | - Адрес - начиная с этого адреса блок будет храниться в памяти (сначала ключ, потом данные) 76 | - Ключ - метка "первой записи" типа `byte` (можно использовать символ). Если сменить ключ - данные перезапишутся из переменной, т.е. сбросятся до умолчаний 77 | 4. Вызывать `memory.tick()` внутри `loop()` 78 | 5. После изменения данных вызвать `memory.update()` - данные в EEPROM обновятся автоматически спустя таймаут внутри функции `tick()` 79 | 6. Ключ "первой записи" хранится в самом начале блока (по указанному в begin() адресу), поэтому при изменении размера записываемых данных не пострадает 80 | 81 | Библиотека позволяет отложить запись данных на заданный таймаут, таким образом при настройке параметров девайса (кнопками/крутилками) можно безопасно вызывать update() после каждого изменения, так как данные запишутся спустя таймаут после прекращения изменений. 82 | 83 | 84 | 85 | ## Пример 86 | ```cpp 87 | // структура для хранения данных 88 | struct Data { 89 | char val = 'H'; 90 | char str[15] = "ello kitty!"; 91 | }; 92 | Data data; // переменная, с которой мы работаем в программе 93 | 94 | #include // подключаем либу 95 | EEManager memory(data); // передаём нашу переменную (фактически её адрес) 96 | 97 | // можно задать таймаут обновления, по умолч. 5 секунд (5000мс) 98 | //EEManager memory(data, 1000); 99 | 100 | void setup() { 101 | Serial.begin(9600); 102 | // для esp8266 не забудь вызвать EEPROM.begin(размер)! 103 | /* 104 | Запускаем менеджер, передаём: 105 | - Стартовый адрес в памяти для записи даты 106 | - Ключ хранения (0.. 255) или символ 107 | */ 108 | byte stat = memory.begin(0, 'b'); 109 | 110 | /* 111 | Коды возврата: 112 | 0 - ключ совпал, данные прочитаны из епром 113 | 1 - ключ не совпал (первый запуск), данные записаны в епром 114 | 2 - ошибка, в епроме не хватает места 115 | */ 116 | Serial.println(stat); 117 | 118 | // выведем в порт всё содержимое блока памяти, включая ключ 119 | for (uint16_t i = memory.startAddr(); i < memory.endAddr() + 1; i++) 120 | Serial.write(EEPROM.read(i)); 121 | Serial.println(); 122 | 123 | data.val = 'X'; // изменим данные в переменной 124 | memory.update(); // отложим обновление 125 | 126 | // примечание: если нужно создать ещё один блок следующим в памяти - 127 | // запускаем его на адресе memory.endAddr() + 1, это первый 128 | // свободный байт после первого блока 129 | } 130 | 131 | void loop() { 132 | // в лупе вызываем tick(), в нём по таймеру произойдёт обновление 133 | // функция вернёт true, когда это случится 134 | if (memory.tick()) Serial.println("Updated!"); 135 | 136 | // выведем в порт всё содержимое блока памяти, включая ключ 137 | for (uint16_t i = memory.startAddr(); i < memory.endAddr() + 1; i++) 138 | Serial.write(EEPROM.read(i)); 139 | Serial.println(); 140 | 141 | // таймер сброса на 10 секунд: через 10 секунд 142 | // произойдёт сброс ключа данных, и при следующем запуске 143 | // в епром будут записаны данные по умолчанию (то что в ярлыке структуры) 144 | static uint32_t tmr; 145 | if (millis() - tmr >= 10000) { 146 | memory.reset(); 147 | Serial.println("reset"); 148 | for (;;); 149 | } 150 | 151 | delay(1000); // чилим 152 | } 153 | ``` 154 | 155 | 156 | 157 | ## Версии 158 | - v1.0 159 | - v1.1 - изменены коды возврата begin 160 | - v1.2 - добавлена nextAddr() 161 | - v1.2.1 - поддержка esp32 162 | - v1.2.2 - пофиксил варнинг 163 | - v1.3 - исправлен критический баг с адресацией, добавлен макрос EEBlock 164 | - v1.4 - ещё больше поддержки esp8266/32 165 | - v2.0 - ключ запуска перенесён в начало блока для удобства. Обновление библиотеки сбросит данные в EEPROM! 166 | 167 | 168 | 169 | ## Установка 170 | - Библиотеку можно найти по названию **EEManager** и установить через менеджер библиотек в: 171 | - Arduino IDE 172 | - Arduino IDE v2 173 | - PlatformIO 174 | - [Скачать библиотеку](https://github.com/GyverLibs/EEManager/archive/refs/heads/main.zip) .zip архивом для ручной установки: 175 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64) 176 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32) 177 | - Распаковать и положить в *Документы/Arduino/libraries/* 178 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив 179 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA) 180 | ### Обновление 181 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи 182 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить" 183 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам! 184 | 185 | 186 | 187 | ## Баги и обратная связь 188 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru) 189 | Библиотека открыта для доработки и ваших **Pull Request**'ов! 190 | 191 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать: 192 | - Версия библиотеки 193 | - Какой используется МК 194 | - Версия SDK (для ESP) 195 | - Версия Arduino IDE 196 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде 197 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности 198 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код 199 | -------------------------------------------------------------------------------- /README_EN.md: -------------------------------------------------------------------------------- 1 | This is an automatic translation, may be incorrect in some places. See sources and examples! 2 | 3 | # Eemanager 4 | Eeprom manager - Library to reduce memory wear 5 | - postponed entry (update) by timer 6 | - works on the basis of standard eeprom.h 7 | - Built -in mechanism of the first record key 8 | 9 | ## compatibility 10 | Compatible with all arduino platforms (used arduino functions) 11 | - For ESP8266, do not forget to call EEPROM.BEGIN (size)! 12 | 13 | ## Content 14 | - [installation] (# Install) 15 | - [initialization] (#init) 16 | - [use] (#usage) 17 | - [Example] (# Example) 18 | - [versions] (#varsions) 19 | - [bugs and feedback] (#fedback) 20 | 21 | 22 | ## Installation 23 | - The library can be found by the name ** eemanager ** and installed through the library manager in: 24 | - Arduino ide 25 | - Arduino ide v2 26 | - Platformio 27 | - [download the library] (https://github.com/gyverlibs/eemanager/archive/refs/heads/main.zip) .Zip archive for manual installation: 28 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64) 29 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32) 30 | - unpack and put in *documents/arduino/libraries/ * 31 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive 32 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA) 33 | ### Update 34 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added 35 | - through the IDE library manager: find the library how to install and click "update" 36 | - Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors! 37 | 38 | 39 | 40 | ## initialization 41 | `` `CPP 42 | // We transfer our variable of any type (in fact its address) - structure, array, anything 43 | Eemanager Memory (Data); 44 | 45 | // You can set the update timout, by the silence.5 seconds (5000ms) 46 | Eemanager Memory (Data, 1000); 47 | `` ` 48 | 49 | 50 | ## Documentation 51 | `` `CPP 52 | // Start work, read data in a variable. 53 | // accepts the address of the start of storage of the date and key 54 | // returns: 55 | // 0 - the key coincided, the data is read from EPROM 56 | // 1 - the key did not coincide (the first launch), the data are recorded in EPROM 57 | // 2 - error, there is not enough space in Eprom 58 | Uint8_t Begin (Uint16_T Addr, Uint8_t Key); 59 | 60 | VOID settimeout (uint16_t tout = 5000);// change the timaut 61 | VOID updatenow ();// update data to her industry now 62 | VOID update ();// postpone the update and reset the timer 63 | Bool Tick ();// Tiker of updates 64 | VOID Reset ();// Reset the launch key.When rebooting (or calls is the Begin), standard data will be recorded 65 | 66 | uint16_t datasize ();// get data size 67 | Uint16_T BLOCKSIZE ();// Get the size of the entire block (data + key) 68 | 69 | uint16_t keyaddr ();// get the key address (coincides with the transferred to Begin ()) 70 | uint16_t Startaddr ();// get the address of the first byte of data in the block (equal to address in Begin () + 1) 71 | Uint16_T Endaddr ();// get the address of the last byte in the block 72 | uint16_t nEXTADDDR ();// Get the first free address for the next block 73 | `` ` 74 | 75 | General functions/macros 76 | `` `CPP 77 | EEBLOCK (DATA);// returns the size of the specified data Data (any type) +1 to the key (for calculating the addresses of the blocks in memory) 78 | `` ` 79 | 80 | ### Usage 81 | 1. declare a variable in which data is stored (integer, array, structure ...) 82 | 2. Pass it to Eemanager: `Eemanager Memory (Data);` 83 | 2.1 * [only for ESP] * Launch EEPROM indicating the size: `eeprom.begin (size);`.If only the specified data is stored, you can do it: `eeprom.begin (memory.blocksize ());` 84 | 3. Run the manager `Memory.Begin (address, key);` 85 | - Address - starting from this address, the block will be stored in memory (first the key, then data) 86 | - Key - the "first entry" tag type `byte` (you can use the symbol).If you change the key, the data will be rewritten from the variable, i.e.They will drop to default 87 | 4. Call `memory.tick ()` inside `loop ()` 88 | 5 and 89 | 6. The “first record” key is stored at the very beginning of the block (at the address indicated in the address), therefore, when the amount of the recorded data changes, it will not suffer 90 | 91 | The library allows you to postpone the data recording on a given timout, so when setting up the devices settings (buttons/twists), you can safely call update () after each change, since the data will be recorded after the timut after the change is stopped. 92 | 93 | 94 | ## Example 95 | `` `CPP 96 | // Data storage structure 97 | Struct Data { 98 | Char Val = 'H'; 99 | Chard [15] = "Ello Kitty!"; 100 | }; 101 | Data Data;// variable with which we work in the program 102 | 103 | #include // Connect Liba 104 | Eemanager Memory (Data);// We transmit our variable (in fact its address) 105 | 106 | // You can set the update timout, by the silence.5 seconds (5000ms) 107 | // Eemanager Memory (Data, 1000); 108 | 109 | VOID setup () { 110 | Serial.Begin (9600); 111 | // For ESP8266 Do not forget to call eEPROM.BEGIN (size)! 112 | /* 113 | We launch the manager, transmit: 114 | - starting address in memory for recording date 115 | - storage key (0 .. 255) or symbol 116 | */ 117 | byte stat = memory.begin (0, 'b'); 118 | 119 | /* 120 | Return codes: 121 | 0 - the key coincided, the data is read from EPROM 122 | 1 - the key did not coincide (the first launch), the data is recorded in EPROM 123 | 2 - error, in Eprom there is not enough space 124 | */ 125 | Serial.println (stat); 126 | 127 | // Determine the entire contents of the memory unit, including the key 128 | for (uint16_t I = Memory.startaddr (); i = 10000) { 155 | Memory.Reset (); 156 | Serial.println ("reset"); 157 | for (;;); 158 | } 159 | 160 | DELAY (1000);// Chilim 161 | } 162 | `` ` 163 | 164 | 165 | ## versions 166 | - V1.0 167 | - V1.1 - Code of Return Begin 168 | - v1.2 - added Nextadddr () 169 | - V1.2.1 - ESP32 support 170 | - v1.2.2 - fixed Varning 171 | - V1.3 - A critical bug with addressing was fixed, EEBLOCK macro has been added 172 | - V1.4 - even more support ESP8266/32 173 | - V2.0 - the launch key is transferred to the beginning of the block for convenience.The library update will drop data in Eeprom! 174 | 175 | 176 | ## bugs and feedback 177 | When the bugs are created** Issue **, or better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru) 178 | The library is open for refinement and your ** pull Request ** 'ow! 179 | 180 | 181 | When reporting about bugs or incorrect work of the library, it is necessary to indicate: 182 | - The version of the library 183 | - What is MK used 184 | - SDK version (for ESP) 185 | - version of Arduino ide 186 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code 187 | - what code has been loaded, what work was expected from it and how it works in reality 188 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code -------------------------------------------------------------------------------- /examples/demo/demo.ino: -------------------------------------------------------------------------------- 1 | // структура для хранения данных 2 | struct Data { 3 | char val = 'H'; 4 | char str[15] = "ello kitty!"; 5 | }; 6 | Data data; // переменная, с которой мы работаем в программе 7 | 8 | #include // подключаем либу 9 | EEManager memory(data); // передаём нашу переменную (фактически её адрес) 10 | 11 | // можно задать таймаут обновления, по умолч. 5 секунд (5000мс) 12 | //EEManager memory(data, 1000); 13 | 14 | void setup() { 15 | Serial.begin(9600); 16 | // для esp8266 не забудь вызвать EEPROM.begin(размер)! 17 | // EEPROM.begin(memory.blockSize()); 18 | /* 19 | Запускаем менеджер, передаём: 20 | - Стартовый адрес в памяти для записи даты 21 | - Ключ хранения (0.. 255) или символ 22 | */ 23 | byte stat = memory.begin(0, 'b'); 24 | 25 | /* 26 | Коды возврата: 27 | 0 - ключ совпал, данные прочитаны из епром 28 | 1 - ключ не совпал (первый запуск), данные записаны в епром 29 | 2 - ошибка, в епроме не хватает места 30 | */ 31 | Serial.println(stat); 32 | 33 | // выведем в порт всё содержимое блока памяти, включая ключ 34 | for (uint16_t i = memory.startAddr(); i < memory.endAddr() + 1; i++) 35 | Serial.write(EEPROM.read(i)); 36 | Serial.println(); 37 | 38 | data.val = 'X'; // изменим данные в переменной 39 | memory.update(); // отложим обновление 40 | 41 | // примечание: если нужно создать ещё один блок следующим в памяти - 42 | // запускаем его на адресе memory.endAddr() + 1, это первый 43 | // свободный байт после первого блока 44 | } 45 | 46 | void loop() { 47 | // в лупе вызываем tick(), в нём по таймеру произойдёт обновление 48 | // функция вернёт true, когда это случится 49 | if (memory.tick()) Serial.println("Updated!"); 50 | 51 | // выведем в порт всё содержимое блока памяти, включая ключ 52 | for (uint16_t i = memory.startAddr(); i < memory.endAddr() + 1; i++) 53 | Serial.write(EEPROM.read(i)); 54 | Serial.println(); 55 | 56 | // таймер сброса на 10 секунд: через 10 секунд 57 | // произойдёт сброс ключа данных, и при следующем запуске 58 | // в епром будут записаны данные по умолчанию (то что в ярлыке структуры) 59 | static uint32_t tmr; 60 | if (millis() - tmr >= 10000) { 61 | memory.reset(); 62 | Serial.println("reset"); 63 | for (;;); 64 | } 65 | 66 | delay(1000); // чилим 67 | } 68 | -------------------------------------------------------------------------------- /examples/demoSimple/demoSimple.ino: -------------------------------------------------------------------------------- 1 | // структура для хранения данных 2 | struct Data { 3 | byte valB; 4 | int valI; 5 | }; 6 | Data data; // переменная, с которой мы работаем в программе 7 | 8 | #include // подключаем либу 9 | EEManager memory(data); // передаём нашу переменную (фактически её адрес) 10 | 11 | // можно задать таймаут обновления, по умолч. 5 секунд (5000мс) 12 | //EEManager memory(data, 1000); 13 | 14 | void setup() { 15 | Serial.begin(9600); 16 | // для esp8266 не забудь вызвать EEPROM.begin(размер)! 17 | // EEPROM.begin(memory.blockSize()); 18 | 19 | /* 20 | Запускаем менеджер, передаём: 21 | - Стартовый адрес в памяти для записи даты 22 | - Ключ хранения (0.. 255) или символ 23 | */ 24 | memory.begin(0, 'b'); 25 | // здесь данные уже прочитаны из памяти 26 | Serial.println(data.valB); 27 | Serial.println(data.valI); 28 | 29 | // меняем данные 30 | data.valB = random(100); 31 | data.valI = random(10000); 32 | memory.update(); // отложить обновление 33 | 34 | // вызывать update несколько раз - безопасно 35 | // данные запишутся только после выхода таймаута 36 | memory.update(); 37 | memory.update(); 38 | memory.update(); 39 | } 40 | 41 | void loop() { 42 | // данные автоматически запишутся здесь по таймауту 43 | memory.tick(); 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /examples/manyBlocks/manyBlocks.ino: -------------------------------------------------------------------------------- 1 | // блок 1 - структура 2 | struct DataBlock { 3 | int valI; 4 | byte valB; 5 | }; 6 | DataBlock data; 7 | 8 | // блок 2 - массив 9 | int arr[10]; 10 | 11 | #include 12 | EEManager mem1(data); 13 | EEManager mem2(arr); 14 | 15 | void setup() { 16 | Serial.begin(9600); 17 | // для esp8266 не забудь вызвать EEPROM.begin(размер)! 18 | // EEPROM.begin(mem1.blockSize() + mem2.blockSize()); 19 | 20 | // первый блок храним с адреса 0 21 | mem1.begin(0, 'a'); 22 | 23 | // второй - следом за ним 24 | mem2.begin(mem1.nextAddr(), 'a'); 25 | } 26 | 27 | void loop() { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For EEManager 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | EEManager KEYWORD1 9 | 10 | ####################################### 11 | # Methods and Functions (KEYWORD2) 12 | ####################################### 13 | 14 | setTimeout KEYWORD2 15 | begin KEYWORD2 16 | updateNow KEYWORD2 17 | update KEYWORD2 18 | tick KEYWORD2 19 | reset KEYWORD2 20 | dataSize KEYWORD2 21 | blockSize KEYWORD2 22 | startAddr KEYWORD2 23 | endAddr KEYWORD2 24 | nextAddr KEYWORD2 25 | keyAddr KEYWORD2 26 | 27 | EEBlock KEYWORD2 28 | 29 | 30 | ####################################### 31 | # Constants (LITERAL1) 32 | ####################################### -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=EEManager 2 | version=2.0.1 3 | author=AlexGyver 4 | maintainer=AlexGyver 5 | sentence=Simple library for reducing EEPROM wear 6 | paragraph=Simple library for reducing EEPROM wear 7 | category=Data Storage 8 | url=https://github.com/GyverLibs/EEManager 9 | architectures=* 10 | -------------------------------------------------------------------------------- /src/EEManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | Менеджер EEPROM - библиотека для уменьшения износа памяти 3 | Документация: 4 | GitHub: https://github.com/GyverLibs/EEManager 5 | Возможности: 6 | - Отложенная запись (обновление) по таймеру 7 | - Работает на базе стандартной EEPROM.h 8 | - Встроенный механизм ключа первой записи 9 | 10 | AlexGyver, alex@alexgyver.ru 11 | https://alexgyver.ru/ 12 | MIT License 13 | 14 | Версии: 15 | v1.0 - релиз 16 | v1.1 - изменены коды возврата begin 17 | v1.2 - добавлена nextAddr() 18 | v1.2.1 - поддержка esp32 19 | v1.2.2 - пофиксил варнинг 20 | v1.3 - исправлен критический баг с адресацией, добавлен макрос EEBlock 21 | v1.4 - ещё больше поддержки esp8266/32 22 | v2.0 - ключ запуска перенесён в начало блока для удобства. Обновление библиотеки сбросит данные в EEPROM! 23 | */ 24 | 25 | #ifndef _EEManager_h 26 | #define _EEManager_h 27 | #include 28 | #include 29 | 30 | #define EEBlock(x) (sizeof(x) + 1) 31 | 32 | class EEManager { 33 | public: 34 | // передать данные любого типа, опционально таймаут обновления в мс 35 | template 36 | EEManager(T& data, uint16_t tout = 5000) { 37 | _data = (uint8_t*)&data; 38 | _size = sizeof(T); 39 | _tout = tout; 40 | } 41 | 42 | // передать данные любого типа и их размер, опционально таймаут обновления в мс 43 | EEManager(void* data, uint16_t size, uint16_t tout = 5000) { 44 | _data = (uint8_t*)data; 45 | _size = size; 46 | _tout = tout; 47 | } 48 | 49 | // сменить таймаут 50 | void setTimeout(uint16_t tout = 5000) { 51 | _tout = tout; 52 | } 53 | 54 | // начать работу, прочитать данные в переменную. Принимает адрес начала хранения даты и ключ 55 | uint8_t begin(uint16_t addr, uint8_t key) { 56 | _addr = addr + 1; // данные начнутся со следующего адреса 57 | if (nextAddr() > (uint16_t)EEPROM.length()) return 2; // не хватит места 58 | _ready = 1; // EEPROM запущен и размера хватит 59 | if (EEPROM.read(keyAddr()) != key) { // ключ не совпал 60 | EEPROM.write(keyAddr(), key); // пишем ключ 61 | updateNow(); // пишем стандартные значения 62 | return 1; 63 | } 64 | for (uint16_t i = 0; i < _size; i++) _data[i] = EEPROM.read(_addr + i); 65 | return 0; 66 | } 67 | 68 | // обновить данные в еепром сейчас 69 | void updateNow() { 70 | if (_ready) { 71 | #if defined(ESP8266) || defined(ESP32) 72 | for (uint16_t i = 0; i < _size; i++) EEPROM.write(_addr + i, _data[i]); 73 | EEPROM.commit(); 74 | #else 75 | for (uint16_t i = 0; i < _size; i++) EEPROM.update(_addr + i, _data[i]); 76 | #endif 77 | } 78 | } 79 | 80 | // отложить обновление и сбросить таймер 81 | void update() { 82 | _tmr = millis(); 83 | _update = 1; 84 | } 85 | 86 | // отменить отложенное обновление 87 | void stop() { 88 | _update = 0; 89 | } 90 | 91 | // тикер обновления 92 | bool tick() { 93 | if (_update && (uint16_t)((uint16_t)millis() - _tmr) >= _tout) { 94 | updateNow(); 95 | _update = 0; 96 | return 1; 97 | } 98 | return 0; 99 | } 100 | 101 | // сбросить ключ запуска. При перезагрузке (или вызове begin) запишутся стандартные данные 102 | void reset() { 103 | EEPROM.write(keyAddr(), EEPROM.read(keyAddr()) + 1); // меняем ключ на +1, при перезапуске будет дефолт 104 | #if defined(ESP8266) || defined(ESP32) 105 | EEPROM.commit(); 106 | #endif 107 | } 108 | 109 | // получить размер данных 110 | uint16_t dataSize() { 111 | return _size; 112 | } 113 | 114 | // получить размер всего блока (данные + ключ) 115 | uint16_t blockSize() { 116 | return _size + 1; 117 | } 118 | 119 | // получить адрес ключа 120 | uint16_t keyAddr() { 121 | return _addr - 1; 122 | } 123 | 124 | // получить адрес первого байта данных в блоке 125 | uint16_t startAddr() { 126 | return _addr; 127 | } 128 | 129 | // получить адрес последнего байта в блоке 130 | uint16_t endAddr() { 131 | return _addr + _size - 1; 132 | } 133 | 134 | // получить первый свободный адрес для следующего блока 135 | uint16_t nextAddr() { 136 | return _addr + _size; 137 | } 138 | 139 | private: 140 | uint8_t* _data; 141 | uint16_t _size, _addr; 142 | bool _ready = 0, _update = 0; 143 | uint16_t _tmr = 0; 144 | uint16_t _tout; 145 | }; 146 | 147 | #endif 148 | --------------------------------------------------------------------------------