Arduino: Легкий алгоритм сжатия для хранения данных в EEPROM

Я хочу хранить большой объем данных на моем Arduino с помощью ATmega168/ATmega328, но, к сожалению, всего 256 КБ /512 КБ EEPROM-хранилища.

Моя идея - использовать алгоритм сжатия для разметки размера. Но хорошо, мои знания по алгоритмам сжатия довольно низки, и мой поиск готовых к использованию библиотек не удался.

Итак, есть ли хороший способ для оптимизации размера хранилища?

Ответы

Ответ 1

Вы можете взглянуть на алгоритм LZO, который должен быть легким. Я не знаю, есть ли какие-либо реализации для системы AVR, но это может быть что-то, что вы могли бы реализовать самостоятельно.

Возможно, вы несколько ошибочно проинформированы о количестве хранилища, доступного в EEPROM на вашем чипе; в соответствии со спецификацией у меня размеры EEPROM:

ATmega48P: 256
ATmega88P: 512
ATmega168P: 512
ATmega256P: 1024

Обратите внимание, что эти значения находятся в байтах, а не в KB, как вы упомянули в своем вопросе. Это никоим образом не означает "shitload".

Ответ 2

AVR имеют только несколько килобайт EEPROM, и очень немногие имеют много больше, чем 64K Flash (нет стандартных Arduinos).

Если вам нужно что-то хранить и редко изменять, например изображение, вы можете попробовать использовать Flash, так как там гораздо больше места для работы. Для простых изображений некоторая грубая RLE-кодировка проделала бы долгий путь.

Сжатие всего более случайного, например, записанных данных, аудио и т.д., потребует огромного объема накладных расходов для AVR, вам будет лучше повезти с помощью последовательного чипа EEPROM для хранения этих данных. На сайте Arduino есть страница на взаимодействии с чипом 64K. Если вы хотите больше, посмотрите на взаимодействие с SD-картой с SPI, например, в этот звуковой экран

Ответ 4

Алгоритм, подобный LZSS, вероятно, будет хорошим выбором для встроенной платформы. Это простые алгоритмы и не требуют много памяти.

LZS - это тот, с которым я знаком. Он использует словарь 2 кБ для сжатия и декомпрессии (словарь - это самый последний 2 КБ несжатого потока данных). (LZS был запатентован HiFn, однако, насколько я могу судить, все патенты истекли.)

Но я вижу, что ATmega328, используемый на недавних Arduinos, имеет только 512 байт до 2 КБ SRAM, так что, возможно, даже LZS тоже большой для этого. Я уверен, что вы можете использовать вариант с меньшим словарем, но я не уверен, какие коэффициенты сжатия вы бы достигли.

Ответ 5

Вы также можете взглянуть на LZJB, будучи очень коротким, простым и легким.

Кроме того, FastLZ может стоить внимания. Он получает лучшие коэффициенты сжатия, чем LZJB, и имеет довольно минимальные требования к памяти для декомпрессии:

Ответ 6

Метод, описанный в статье "Алгоритмы сжатия данных для устройств с ограничением энергии в сетях с задержкой по току", может выполняться на ATmega328.

Ссылка: C. Сэдлер и М. Мартонози, "Алгоритмы сжатия данных для устройств с ограничением энергии в сетях с толерантными толерантами", Материалы конференции ACM по встроенным сетевым сенсорным системам (SenSys) 2006, ноябрь 2006 г..pdf. Источник S-LZW для MSPGCC: slzw.tar.gz. Обновлено 10 марта 2007 г.

Ответ 7

Если вы просто хотите удалить какой-то повторяющийся нуль или такой, используйте Кодировка длины пробега Повторяющиеся байтовые последовательности будут сохранены как:

<mark><byte><count>

Это суперпростой алгоритм, который вы, вероятно, можете кодировать себе в нескольких строках кода.

Ответ 8

Является ли внешний EEPROM (например, через I2C) не вариантом? Даже если вы используете алгоритм сжатия, нижняя сторона заключается в том, что размер данных, которые вы можете хранить во внутренней EEPROM, не может быть определен простым способом. И с корнем, если вы действительно имеете в виду kBYTES, тогда рассмотрите SDCard, подключенную к SPI... В сети есть несколько легкосчитаемых файловых систем FAT с открытым исходным кодом.