У микроконтроллера три вида памяти, и путать их — источник загадочных багов.
Flash — энергонезависимая, хранит прошивку. У ESP32 внешняя, 4 МБ, у AVR 32 КБ. Запись возможна, но ограничена: 10 000 циклов у типовой flash (у ESP32 заявлено 100 000). Читается быстро, пишется блоками.
SRAM — оперативная, хранит переменные и стек. У ESP32 520 КБ, у AVR 2 КБ. Быстрая, но при отключении питания всё исчезает. Закончилась — программа падает (переполнение стека, «мусор»).
EEPROM — энергонезависимая, для настроек. У AVR 1 КБ внутри, у ESP32 отдельной нет (эмулируется во flash). Ресурс 100 000 циклов на ячейку.
Практика:
— Настройки, калибровки, счётчики — в EEPROM (или эмуляцию), а не в SRAM.
— Логи и буферы — в SRAM, но с контролем размера: у AVR 2 КБ, и строка в 200 байт съедает 10 %.
— Константы, таблицы, строки — во flash (в AVR — через PROGMEM, иначе они копируются в SRAM).
— Не писать в EEPROM в цикле: ресурс кончится за день. Пиши по изменению, а не каждую секунду.
Отдельная тема — wear leveling: у ESP32 есть библиотека Preferences, которая распределяет записи по секторам flash, чтобы не убить одну ячейку.
Что важно помнить: String в Arduino выделяет память динамически и может фрагментировать SRAM. На AVR с 2 КБ это реальная проблема; лучше char[] и snprintf.
И проверка: если программа падает через час работы — почти наверняка утечка памяти или переполнение буфера, а не «глючная плата».
Память объясняет «работает и падает» и куда писать настройки, чтобы они пережили выключение.
Запиши в EEPROM/Preferences число, перезагрузи плату и прочитай. Потом запиши в SRAM — увидишь, что после перезагрузки там мусор.
Проверь себя
Почему нельзя сохранять настройки в EEPROM каждую секунду?
Ресурс ячейки около 100 000 циклов. При записи раз в секунду это меньше двух суток. Нужно писать только при изменении, а ещё лучше — с wear leveling.
-
Wikipedia: Flash memory
flash-память
-
Wikipedia: Static random-access memory
SRAM
-
Wikipedia: EEPROM
EEPROM