Arduino: легкий алгоритм сжатия для хранения данных в EEPROM - PullRequest
17 голосов
/ 22 октября 2009

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

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

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

Ответы [ 8 ]

16 голосов
/ 22 октября 2009

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

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

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

Обратите внимание, что эти значения находятся в байтах , а не в КБ, как вы упоминаете в своем вопросе. Это ни в коем случае не «дерьмо».

7 голосов
/ 22 октября 2009

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

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

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

3 голосов
/ 05 ноября 2009

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

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

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

3 голосов
/ 22 октября 2009

Исследование НАСА здесь (Постскриптум)

Репост статьи 1989 года о LZW здесь

Сохраняйте это простым и выполняйте анализ затрат / выплат добавления сжатия. Это включает время и усилия, сложность, использование ресурсов, сжимаемость данных и т. Д.

1 голос
/ 31 марта 2010

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

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

1 голос
/ 15 ноября 2009

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

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

0 голосов
/ 20 ноября 2014

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

0 голосов
/ 14 ноября 2014

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

<mark><byte><count>

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

...