Увеличение памяти ардуино с помощью sd карты
Согласно документации Arduino, ATmega328 имеет 32 КБ флэш-памяти для загрузчика + загруженный эскиз и только 2 КБ SRAM для данных времени выполнения. ATmega2560 имеет немного больше, общий объем 256 КБ и 8 КБ соответственно.
В любом случае эти ограничения кажутся довольно небольшими, особенно по сравнению с потребительскими устройствами аналогичного размера, такими как смартфоны.
Что вы можете сделать, если у вас кончились? Например, если ваш эскиз слишком большой или вам нужно обрабатывать много данных (например, строк) во время выполнения? Есть ли способ расширить Flash или SRAM?
Попробуйте использовать некоторые переменные оптимизации. Некоторые различные переменные обсуждаются здесь Используйте надлежащие области действия для ваших переменных, если это еще не сделано, компилятор оптимизирует использование оперативной памяти для вас, когда переменные не используются. Вы можете использовать Teensy 3.2 (с программным обеспечением Teensyduino), которое будет сравнимо с Arduino. Учитывая, что у вас заканчивается RAM / PROGMEM, это также означает, что вы, скорее всего, пытаетесь подтолкнуть Arduino. Teensy 3.2 не намного дороже. но имеет: 32-битную, 72 МГц (wtf !?) флэш-память 256 КБ, 64 КБ ОЗУ и 3x UART. Не больше памяти программ, как у ATmega2560, но должно быть достаточно оперативной памяти и увеличения скорости.Оптимизация
Низкоуровневое программирование для встроенных систем весьма отличается от программирования для устройств общего назначения, таких как компьютеры и мобильные телефоны. Эффективность (с точки зрения скорости и пространства) гораздо важнее, потому что ресурсы стоят на первом месте. Это означает, что самое первое, что нужно сделать, если вам не хватает места, это посмотреть, какие части вашего кода вы можете оптимизировать.
С точки зрения сокращения использования программного пространства (Flash) размер кода может быть довольно трудно оптимизировать, если вы неопытны или более привыкли к программированию для настольных компьютеров, которые не склонны к этим навыкам. К сожалению, не существует подхода «волшебной пули», который будет работать во всех ситуациях, хотя он помогает, если вы серьезно задумаетесь над тем, что в действительности должен иметь ваш эскиз . Если функция не нужна, уберите ее.
Иногда также полезно определить, где несколько частей вашего кода одинаковы (или очень похожи). Вы можете сжать их в многократно используемые функции, которые можно вызывать из нескольких мест. Однако имейте в виду, что иногда попытка сделать код слишком многократно используемым на самом деле делает его более многословным. Это сложный баланс для забастовки, который имеет тенденцию приходить с практикой. Можно потратить некоторое время на изучение того, как изменения кода влияют на вывод компилятора.
Оптимизация данных времени выполнения (SRAM) имеет тенденцию быть немного легче, когда вы к этому привыкли. Очень распространенная ловушка для начинающих программистов - использование слишком большого количества глобальных данных. Все, что объявлено в глобальном масштабе, будет существовать в течение всего времени существования эскиза, и это не всегда необходимо. Если переменная используется только внутри одной функции, и она не должна сохраняться между вызовами, то сделайте ее локальной переменной. Если значение должно быть разделено между функциями, подумайте, можете ли вы передать его как параметр вместо того, чтобы делать его глобальным. Таким образом, вы будете использовать SRAM только для тех переменных, которые вам действительно нужны.
Еще одним убийцей использования SRAM является обработка текста (например, использование String класса). Вообще говоря, вам следует избегать выполнения операций со строками, если это возможно. Они огромные боровы памяти. Например, если вы выводите много текста в последовательный порт, используйте несколько вызовов Serial.print() вместо вместо конкатенации строк. Также попытайтесь сократить количество строковых литералов в вашем коде, если это возможно.
Избегайте рекурсии, если это возможно. Каждый раз, когда выполняется рекурсивный вызов, стек поднимается на уровень глубже. Перефразируйте ваши рекурсивные функции, чтобы они стали итеративными.
Использование EEPROM
EEPROM используется для долговременного хранения вещей, которые изменяются только изредка. Если вам нужно использовать большие списки или справочные таблицы с фиксированными данными, подумайте о том, чтобы заранее сохранить их в EEPROM и извлекать только то, что вам нужно, когда это необходимо.
Очевидно, что EEPROM довольно ограничен по размеру и скорости и имеет ограниченное количество циклов записи. Это не лучшее решение для ограничения данных, но этого может быть достаточно, чтобы облегчить нагрузку на Flash или SRAM. Также возможно взаимодействие с аналогичным внешним хранилищем, таким как SD-карта.
Расширение
Если вы исчерпали все остальные варианты, возможно, расширение возможно. К сожалению, расширение флэш-памяти для увеличения места в программе невозможно. Тем не менее, есть возможность расширить SRAM. Это означает, что вы сможете реорганизовать свой эскиз, чтобы уменьшить размер кода за счет увеличения размера данных.
Получить больше SRAM на самом деле довольно просто. Один из вариантов - использовать один или несколько чипов 23K256 . Доступ к ним осуществляется через SPI, и есть библиотека SpiRAM, которая поможет вам их использовать. Просто знайте, что они работают при 3,3 В, а не 5 В!
Если вы используете Mega, вы также можете получить щиты расширения SRAM от Lagrangian Point или Rugged Circuits .
Иногда у меня заканчивается пространство размера программы для встроенной программы на C, которую я хочу наложить на arduino. Итак, какой чип мне нужно расширить память программ для arduino, чтобы я мог использовать более крупные программы на C с моим arduino?
ATmega2560 - это чип, который добавит для большего объема памяти, когда вы закончите память программы на Uno. Ссылаясь на веб-страницу Memory на arduino.cc, вы увидите, что у нее есть Flash = 256 КБ, SRAM = 8 КБ, EEPROM = 4 КБ, где чип ATmega328 на Uno имеет Flash = 32 КБ, SRAM = 2 КБ, EEPROM = 1 КБ.
Когда у вас заканчивается память программы на Uno, у вас есть около трех вариантов, которые являются практичными: сделать программу меньшей; удалить загрузчик (освободить один или два КБ); используйте другую плату с более мощным процессором. Процессор на плате Uno не имеет возможности получить доступ к программным байтам из других мест, кроме встроенной вспышки 32 КБ. Процессор на плате Mega2560 запускается с частотой в 8 раз больше, поэтому он может хранить большие программы, чем Uno.
Другой способ (кроме MCU с большим объемом памяти) не использует структуру Arduino и ее библиотеки. Такой уровень абстракции дорог в обоих направлениях - использование памяти и скорость. Но это намного сложнее. Если вам нужна библиотека, вам необходимо ее портировать (если вы не нашли родной) или хотя бы предоставить требуемые функции от Arduino.
Например, в Arduino IDE 1.6.11 пустой эскиз использует 444 байта вспышки. Используя один pinMode и digitalWrite(13, ! digitalRead(13)); + delay(500); означает 964 байта. Конечно, это, скорее всего, одноразовые. Если вы используете еще шесть контактов и переключаете их, он использует гораздо меньше памяти программ, чем первый (1192B). Но он все еще растет очень быстро.
В чистой C пустой программе примерно 134 байта. Та же функциональность (переключение на один вывод каждые 500 мс) занимает 158 байтов (и это быстрее).
Но для проекта хобби я бы пошел вместо ATMega2560 или ATMega644 /1284.
И вы также можете использовать прямой доступ к оборудованию. Переключить эскиз вывода с использованием регистров напрямую, а _delay_ms из avr-библиотек использует 468 байт вместо 964B. С задержкой с основными библиотеками Arduino это 602B.
Как насчет малины pi zero ? У меня есть пара и часто использую их как ардуины.
Вы также можете посмотреть на другие платформы. Например, Teensy 3.2 совместим с Arduino и имеет 2 Кбайт eeprom и 64 Кбайт оперативной памяти.
Вэнь, задавая широкий вопрос, полезно включить некоторые детали. Как сколько памяти и почему вы думаете, что вам нужно.
Я однажды указал процессор на 2 КБ программного пространства, 64 байта RAM и 1 KIPS. Инженер спросил, MIPS, я объяснял тысячи в секунду. Он ответил, что они не так медленно. В конце проекта был добавлен огромный пользовательский интерфейс, и память сжалась . но по-прежнему без проблем.
Итак, подумайте о том, чтобы быть более продуманным в отношении используемых ресурсов.
Чтобы ответить на вопрос:
1) Arduino не обеспечивает удобную шину для извлечения памяти. Таким образом, нет возможности подключить чип, чтобы получить больше памяти.
2) Arduino имеет SPI, поэтому можно получить доступ к SD-карте. Любой код на SD-карте должен быть загружен в исполняемую память. Это сложно, а не для новичков .
3) Как было предложено, затяните код. Это, вероятно, хороший способ узнать.
3) Переместитесь к более крупному Arduino.
Существуют различные процессоры Arduino. Некоторые в строке ACR, другие - в линии ARM. Переход на другое устройство в одной семье - относительно скромное изменение и может обеспечить до 368 байт прогаммы FLASH. Но это не платы Arduino.
Устройства Arduino ARM очень разные и используют разные библиотеки.
Проверьте Arduino Mega 2560, он очень похож на Uno, имеет аналогичный след, код должен относиться относительно легко и недорого.
В семействе AVR есть более крупные устройства.
Обратите внимание, что AVR32 - это другой процессор, и периферийные устройства достаточно различны, что это другое устройство.
Если вы хотите попасть в очень большие программы (гигабайты памяти), проверьте Beagleboard. Он имеет полный Linux, с виртуальной памятью (см. № 2 выше) и имеет более мощные механизмы ввода-вывода.
Отвечаем на вопрос читателя о том, как можно использовать модуль SD-карты для проектов Arduino с большим объемом данных, которые требуют больше памяти.
Комплектующие
Для того, чтобы платы Ардуино работали с SD-картами нам нужны следующие комплектующие проекта:
- Arduino UNO
- Адаптер SD-карты
- Провода-перемычка
Когда нужна SD-карта
Некоторые проекты могут собирать большое количество данных, таких как данные датчиков, считываемые в течение месяца, которые вы хотите хранить постоянно. Этот большой объем данных, вероятно, не поместится в EEPROM. Кроме того, вы не сможете удобным образом перенести информацию на компьютер таким способом.
Тем не менее, если вы храните данные на SD-карте, вы можете легко переносить созданные файлы и работать с ними на любом компьютере с устройством для чтения SD-карт.
Эта статья покажет как подключить и использовать стандартный модуль SD-карты с Arduino. Весь код и тестовые программы можно найти в виде zip-файла в конце этой статьи.
Подключение Arduino к адаптеру карт
Эти модули обычно используют последовательный периферийный интерфейс (SPI) для связи с микроконтроллером. Поэтому он будет занимать три вывода GPIO на Arduino. Кроме того, вам необходимо подключить линию выбора микросхемы, чтобы включить SD-карту и линии питания для питания адаптера.
Схема подключения Arduino к адаптеру SD-карты
Зеленая (MISO) и желтая (MOSI) линии соединяются с контактами 12 и 11 Arduino. Clock (тактовый сигнал, синий) должен быть привязан к контакту 13. Обратитесь к документации Arduino, если вы не уверены, какие контакты необходимо использовать на Arduino.
Тестовая программа
После выполнения необходимых подключений пришло время подключить SD-карту. В коротком тестовом скетче отображает файлы, присутствующие на карте. Код можно взять ниже или в zip-файле в конце этой статьи как - sd_info.
Как видите, большая часть кода обрабатывает вывод консоли. Всего несколько строк необходимо для подключения к устройству и инициализации файловой системы для чтения и записи файлов. В этом примере, однако, печатаются только некоторые основные свойства карты, такие как размер, тип и сохраненные файлы.
Запись в файлы на SD-карте
Теперь, когда мы знаем, что карта и модуль работают, пришло время записать некоторые значения в файл. Пример SD_write (найденный в архиве) записывает две строки в файл журнала, который хранится на SD-карте.
Часть кода инициализации почти такая же, как в первой программе. Однако вместо открытия тома сама карта SD должна быть инициализирована. После инициализации файл должен быть открыт.
При открытии файла для записи файл создается автоматически, если он не существует. Курсор всегда находится в конце файла. Поэтому, если вы не перемещаете его при открытии файла, вы просто добавляете в него новый текст. Поскольку содержимое хранится на SD-карте, вы можете использовать свой компьютер для чтения содержимого файла.
Чтение из файла, хранящегося на SD-карте
Вы также можете использовать библиотеку SD-карты для чтения файла. Однако по сравнению со стандартными функциями C доступные методы довольно ограничены. Я обнаружил, что в библиотеке SD-карт часто возникают проблемы с поиском файлов в папках. В следующем примере (в папке SD_read в zip-файле) показано, как можно прочитать значение из файла, который содержит показания датчика.
Код должен быть понятным. Единственная реальная разница между этим примером и примером записи заключается в том, что файл читается побайтно. Таким образом, вам нужно перебрать количество байтов, которые вы хотите прочитать из файла. Результат должен выглядеть примерно так:
Адаптеры/модули SD-карт могут быть полезны, если вы хотите оставить проект без присмотра и заставить его создавать файлы журнала или сохранять большое количество показаний датчиков в течение более длительного периода времени. Однако, важно понимать, что чтение файлов с SD-карты не всегда работает должным образом. Ниже вы можете скачать архив с программами, которые были также приведены выше:
Сегодня речь пойдет об использовании SD и micro SD карт в Arduino. Мы разберемся как можно подключить SD карты к Ардуино, как записывать и считывать информацию. Использование дополнительной памяти может быть очень полезно во многих проектах. Если вы не знаете что такое SPI, I2C и аналоговые выводы, то советую вам посмотреть прошлые уроки и разобраться с этими интерфейсами связи Ардуино.
Подключить SD карту к Arduino напрямую не получится, так как она не поддерживает нужный протокол связи. Но мы можем использовать дополнительные модули или шилды для этого. К счастью, стоят они очень дешево и доступны в разных вариантах.
В этом уроке используется:
Отличный набор для начинающих: | Купить |
Arduino Uno: | Купить |
Инфракрасный датчик расстояния: | Купить |
Плата расширения для считывания micro SD карт c SPI интерфейсом: | Купить |
Шилд для Arduino Uno: | Купить |
Карты micro SD: | Купить |
Датчики освещенности: | Купить |
Датчик температуры I2C: | Купить |
Подключение sd карт к Arduino
Модуль и шилд для считывания sd карт подключается по интерфейсу SPI. Шилд просто вставляется в Arduino Uno сверху. А плата подключается к пинам D10 -> CS, D11 -> MOSI, D12 -> MISO, D13 -> SCLK, 5V -> VIN (если на плате есть стабилизатор, если нет то 3,3V), GND -> GND. Вот наглядная схема:
Обратите внимание на напряжение питания платы. Если на плате есть стабилизатор питания, то можете подавать на нее 5 В. Если же стабилизатора нет, то необходимо подвести 3.3 В. В остальном все так же как мы разбирали в уроке по SPI интерфейсу. Теперь перейдем к программной части.
Запись и считывание SD карты на Arduino
Для работы с картами памяти в Arduino есть библиотека SD.h. Она по умолчанию доступна в Arduino IDE. С ней мы и будем работать. Для начала напишем простую программу, которая будет записывать обычную строку на SD карту. Теперь посмотрим на скетч:
Отлично! У меня все работает так как и было задумано. Теперь я хочу немного доработать этот скетч. Давайте закинем текстовый файл на карту памяти с каким-нибудь значением и попробуем считать это на Arduino. Например я создам текстовый файл в котором будет всего одно число. Это число я буду использовать в качестве задержки между записью нашей строки на эту же карту памяти. Немного доработаем предыдущий скетч.
Давайте теперь сделаем что-то более сложное и полезное. Добавим несколько датчиков и будем записывать их показания на карту памяти. Я подключу пару инфракрасных дальномеров, датчик температуры и фото резистор для определения уровня освещенности. Вот так все будет выглядеть:
Подробно скетч моего регистратора показаний я расписывать не буду, потому что мы все это уже разбирали подробно в этом и прошлых уроках. В этом скетче сочетаются навыки из уроков по аналоговым входам, I2C и SPI интерфейсам и подтягивающим резисторам. Вы можете найти все это в разделе сайта уроки по Arduino. Вот скетч:
На сегодня все. В следующий раз мы разберемся с подключением RFID метками. Надеюсь вам все было понятно.
Столкнулся с проблемой нехватки flash-памяти - не хватает места для хранения скетча. Оптимизировал код как можно, а надо еще много всего добавить.
Есть ли внешнии модули, которые увеличивают flash-память? Или можно как-нибудь увеличить место для хранения скетча?
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Замена микроконтроллера вам нужна, если действительно оптимизировали.
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
кстати ,вопрос к тем кто сюда заглянет : можно ли в среде ардуино настроить PROGMEM на работу с внешней энергонезаисимой памятью,по шине I2C или SPI?или как то по другому нативно расширить адресное пространство(не RAM,о примере ардуино на 512КБ ,знаком)
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Progmem наврядли можно прям вот так с полтычка, иначе давно бы уже все еепромы по i2c в полный рост пользовали. А вот какой-нить драйвер можно, наверное, накатать. Только медленный он будет. Или с доп. буфером, как для SD-карты мутить.
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
EEPROM использовать вообще не проблема. А вот если скетч не влазит - оптимизация, или замена контроллера.
Вообще чистый СИ очень сильно снижает вес программы. Но, как сказал mixail844 , нужно определиться что там у вас за код, и что в нем используется. То что можно подгрузить - на флешку, а код перевести (хотя бы частично) в чистый СИ.
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
zzzzza , и RAM и PROGMEM находятся внутри адресного пространства процессора, а I2C или SPI - нет. Защищенного режима у AVR подобно как в 386+ тоже нет, значит программно прозрачная эмуляция тоже невозможна. Т.е. хранить константы где-то снаружи по I2C или SPI можно (написав для их добывания свои функции), а исполнять код из них - нет.
Могу порекомендовать Мегу 2560 - у нее и flash памяти побольше и при необходимости можно организовать внешнюю память в общем адресном пространстве.
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Либо переходить на STM или ESP - вот там пямяти на много больше.
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Спасибо за ответы!
Очень много места занимает все то, что связано с дисплеем. Как подключаешь эту библиотеку, сразу минус 30-40 процентов памяти. И каждый вызов дисплейных функцей тоже немало места занимает. Как смог все вынес в функции, чтобы лишний раз их не вызывать.
Думал о меге, но у нее размер большой. Сейчас думаю между STM и Iskra JS. Больше в пользу Iskra JS, так как побаиваюсь, что памяти STM тоже может не хватить в будущем. Но придется переписывать все на JavaScript. Отсюда вопрос для тех кто сталкивался с микроконтроллерами с AVR процессорами, на которых установлен интерпретатор JavaScript: можно ли как-то писать код на Arduino Wiring?
Возможно, можно снести интерпретатор, но тогда придется писать на чистом СИ, а это, как я думаю, придется переписывать библиотеки, да и явно море проблем будет.
Читайте также: