├── .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 | [](https://github.com/GyverLibs/EEManager/releases/latest/download/EEManager.zip)
2 | [](https://registry.platformio.org/libraries/gyverlibs/EEManager)
3 | [](https://alexgyver.ru/)
4 | [](https://alexgyver.ru/support_alex/)
5 | [](https://github-com.translate.goog/GyverLibs/EEManager?_x_tr_sl=ru&_x_tr_tl=en)
6 |
7 | [](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 |
--------------------------------------------------------------------------------