Progmem
Типы памяти на Arduino
Оперативная память очень ценна для микроконтроллера, а PROGMEM (память программ) не так важна. На Arduino Uno (с использованием Atmega328P) у вас есть:
- 1 КБ EEPROM
- 2 КБ ОЗУ
- 32 КБ PROGMEM (флэш-память - место, где хранится ваша программа)
Очевидно, что памяти программ гораздо больше, чем ОЗУ.
Константы обычно копируются из PROGMEM в оперативную память
Константы в вашей программе изначально хранятся в PROGMEM (где еще они могут храниться при отключении питания?), но копируются в оперативную память кодом инициализации, сгенерированным компилятором, в самом начале выполнения вашего скетча (программа).
Например:
Serial.println ("Hello, world!");
Постоянная строка "Hello, world!" изначально находится в PROGMEM, но копируется в оперативную память при запуске. Это означает, что для него должно быть предусмотрено место в ОЗУ а также во флэш-памяти.
Это использует ценную оперативную память для того, что на самом деле является просто копией чего-то, что никогда не изменится.
Другой пример:
const int NUMBER_OF_ELEMENTS = 10;
const float table[NUMBER_OF_ELEMENTS] =
{ 1.0, 34.234, 324.234, 23.1, 52.0, 3.6, 5.6, 42.42, 1908, 23.456 } ;
Хотя эта таблица значений с плавающей запятой не изменится, она также будет скопирована в оперативную память. Если у вас большая таблица, у вас скоро закончится оперативная память.
Атрибут PROGMEM
Вы можете предотвратить это копирование в оперативную память, добавив PROGMEM
в объявление данных, например:
const int NUMBER_OF_ELEMENTS = 10;
const float table[NUMBER_OF_ELEMENTS] PROGMEM =
{ 1.0, 34.234, 324.234, 23.1, 52.0, 3.6, 5.6, 42.42, 1908, 23.456 } ;
Доступ к константам PROGMEM
К сожалению, компилятор (по крайней мере, на AVR Arduino) ожидает, что все данные будут в ОЗУ, и не позволяет получить доступ к данным непосредственно из PROGMEM.
Можно сделать небольшую библиотеку PROGMEM_readAnything.h
:
#include <Arduino.h> // для определений типов
template <typename T> void PROGMEM_readAnything (const T * sce, T& dest)
{
memcpy_P (&dest, sce, sizeof (T));
}
template <typename T> T PROGMEM_getAnything (const T * sce)
{
static T temp;
memcpy_P (&temp, sce, sizeof (T));
return temp;
}
Скопируйте вышеприведенное в текстовый файл, сохраните его как PROGMEM_readAnything.h
и поместите его в папку с именем PROGMEM_readAnything
и поместите эту папку в ваш Arduino libraries
, которая находится внутри папки вашего альбома. Вот так:
(sketchbook location)/libraries/PROGMEM_readAnything/PROGMEM_readAnything.h
Теперь вы можете получить доступ к константе PROGMEM следующим образом:
float thisOne;
PROGMEM_readAnything (&table[3], thisOne);
Или:
float thisOne = PROGMEM_getAnything (&table[3]);
Макрос F()
Для простых строковых констант можно использовать макрос F()
, чтобы легко сохранять строки в PROGMEM, например:
Serial.println (F("Hello, world!"));
Вопросы, связанные с [progmem]:
- PROGMEM: эквивалент pgm_read_float_near() для double? (Ардуино Дуэ) Я использую Arduino Due, где размер double составляет 8 байт. В своем программном обеспечении я использую константу двойной таблицы, хранящуюся в памяти программ. Раньше я использовал UNO и…
- Могу ли я использовать [[__progmem__]] вместо PROGMEM? В pgmspace.h PROGMEM определяется как __ATTR_PROGMEM__ , который определяется как __attribute__((__progmem__)) . AFAIK, __attribute__ предназначен только для GNU. Начиная с C++ 11, у нас…
- Большие массивы приводят к сбою Arduino У меня есть три больших массива PROGMEM для хранения музыкальных нот песни. Один массив — это ноты, другой — длительность нот и третий — пауза после ноты. Первый массив — это int , а два других…
- ПлатформаIO и константа PROGMEM Я использую библиотеку DuinoWitchery LCD ( https://github.com/duinoWitchery/hd44780 ) в PlatformIO Arduino проект с CLion. Следующий код будет работать, если я вставлю его в main.cpp: // почти…
- Печать элементов массива символов из PROGMEM Дано: const char* PROGMEM names[] = {"Foo","Bar"}; Serial.print(names[0]); Я получаю вывод мусора. Есть ли какая-нибудь функция, которая будет печатать строку из PROGMEM? Например: …
- Отправить массив 2d PROGMEM через SoftwareSerial У меня есть двумерный массив: const byte messages_for_measurement[2][8] PROGMEM = { { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }, { 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }…
- Есть ли хороший справочник для Arduino архитектуры и использования памяти? Найти справочный источник или руководство по использованию оказалось сложнее, чем я ожидал. Есть несколько источников, которые я просмотрел на пути к этому вопросу: Должный указан здесь и …
- Программа для хранения ИК-команд Я работаю над кодом, который способен отправлять необработанные данные в виде ИК-сигнала на ИК-передатчик, памяти arduino Nano недостаточно для хранения массива в памяти SRAM, поэтому я собираюсь…
- strcpy_P увеличивает использование IROM на 400% Использование ESP8266 (NodeMCU 1) в Arduino IDE: Я не могу загрузить свой скетч, потому что один вызов strcpy_P , кажется, увеличивает использование IROM примерно на 400%: 25% общего…
- Вспомогательный объект Flash String в качестве переменной Таким образом, у меня есть куча часто используемых массивов символов для построения команд в моей библиотеке. Поэтому, чтобы сохранить память, я помещаю их во flash,через PROGMEM ext, typedef…
- Считывание байтов из массива PROGMEM Отказ от ответственности: Я только начал использовать C++, и я немного новичок. Имейте это в виду при ответе. Поэтому я недавно купил свой первый Arduino. Он изготовлен по индивидуальному заказу…
- Как функция/метод может определить, является ли передаваемый массив const PROGMEM (flash) или нет (RAM)? Может ли функция/метод узнать, находится ли переданный массив констант во флэш-памяти или в ОЗУ? Если у меня есть метод или функция, которая получает массив констант, который находится в…
- Чтение PROGMEM приводит к неправильному шестнадцатеричному значению Я уверен, что делаю здесь какую-то глупость, но приведенный ниже код должен записывать тестовые шестнадцатеричные значения в EEPROM I2C, однако, когда я пытаюсь прочитать EEPROM, он имеет…
- Как создавать большие массивы программ и не раздражать компоновщика У меня есть довольно сложный проект (PlatformIO, но у меня также было это в vanilla IDE) с несколькими вложенными включениями. Допустим, есть три файла и основной скетч. Основной скетч включает №2 и…
- Инициализировать объект с константами PROGMEM У меня есть класс со свойством const char * : class A { public: const PROGMEM char* text; }; void setup() { // A a{"Hello World!"}; // A…
- Ошибка компиляции ESP8266: "previous declaration of 'HTTPMethod HTTP_HEAD'" У меня есть программа ESP8266, которая раньше работала, но теперь не компилируется с этой ошибкой: C:\...\Arduino\libraries\WiFiManager/WiFiManager.h:25:24: note: in expansion of macro…
- Arduino IDE: как получить длину PROGMEM const? Я определил массив байтов как константу во флэш-памяти Atmel: const uint8_t eye [] PROGMEM = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; Как я…
- Использование программной памяти в ESP8266 по сравнению с AVR, а также как обрабатывать большие динамические строки Это довольно сложный вопрос, связанный с реализацией и лучшими практиками ESP8266. В идеале я надеюсь, что на него ответят люди, хорошо разбирающиеся в проблеме. Как вы, надеюсь, знаете,…
- Преимущества глобальных переменных перед статическими членами класса? Во встроенной системе мы часто используем глобальные переменные, чтобы поддерживать низкое потребление динамической памяти в куче и стеке. Но глобальные переменные также считаются плохой практикой…
- Записать во флэш-память с помощью PROGMEM По документации Arduino цитирую: http://playground.arduino.cc/Learning/Memory Примечание. Флэш-память (PROGMEM) может быть заполнена только во время записи программы. Вы не можете изменить…
- Проблема с памятью Arduino со старыми чипами дисплея HP HDSP-2000 У меня возникли проблемы с памятью, когда Arduino Nano управляет некоторыми старыми чипами HDSP-2000/HDSP-2011. Кажется, я не могу получить массив ASCII 5x7 в PROGMEM и правильно его…
- Можно ли во время выполнения определить, объявлен ли указатель PROGMEM? Можно ли во время выполнения определить, указывает ли указатель на значения, введенные в PROGMEM , или на обычные значения? Это дало бы некоторую гибкость при написании кода, который обрабатывает и…
- Память программы Arduino закончилась У меня есть скетч Arduino, который я сделал, и у меня закончилась динамическая память на моем Arduino Nano. Как я могу уменьшить объем памяти, который занимает программа? (я не очень хорошо…
- Как использовать PROGMEM в файле .h/.cpp вместо файла .ino? Я хочу использовать множество файлов .h / .cpp , которые будут использоваться в моем скетче ino . В одном из этих файлов .cpp (и позже) я хочу использовать константные массивы (например, таблицы…
- Чтение элемента вложенного массива из PROGMEM. У меня есть 2D-массив массивов uint16_t (ИК-коды удаленного доступа). Из-за размера этих данных в оперативной памяти у меня возникают всевозможные проблемы, когда мой массив превышает один код.…
- Доступ к двумерному массиву во внутреннем цикле PROGMEM Я не могу получить доступ к элементам 2D-массива PROGMEM из цикла. См. следующий пример: const byte a1[] PROGMEM = {'a', 'b', 'c', 'd'}; const byte a2[] PROGMEM = {'e', 'f', 'g', 'h',…
- Проблемы с нехваткой памяти Arduino + IR + Raw code У меня проблема с моим новым проектом с Arduino + ИК-эмиттером + большими необработанными кодами. Я пробовал так: https://gist.github.com/jjmjr/41ed083c8229d0218c962641c5af27b0 Как вы…
- PROGMEM поврежден массив Я пытаюсь сохранить большое количество значений в нескольких массивах с помощью PROGMEM, но обнаруживаю, что некоторые значения считываются обратно поврежденными. Я сохраняю только 1 и 0, но когда я…
- Инициализировать и читайть из массива указателей PROGMEM на массивы PROGMEM. Я работаю над проектом для Arduino Uno, для которого мне нужно несколько константных массивов байтов. Такой массив инициализируется следующим образом: const byte charR[] PROGMEM = { B01111111…
- ATmega328, ошибка кода arduino nano v3, говорящая о недостаточной оперативной памяти об этом говорится в ошибке кода, и я не уверен, что делать, пожалуйста, мне нужна срочная помощь :( ` // Простая прокрутка текста, управляемая через Bluetooth // автор: Йорук для…
- ЛДЦ в паре с Ардуино зависает и зависает. Закончились СПРАМ? Я делаю будильник, используя ЖК-дисплей 4x20, RTC и Arduino Pro Mini 3,3 В. Я реализовал систему меню для установки времени/даты, которая мигает текстом на ЖК-дисплее, чтобы указать, что я его…
- 1