Локально объявленная переменная занимает глобальное переменное пространство в динамической памяти/SRAM

Я пытаюсь заставить свой Arduino Uno управлять кондиционером, записывая необработанный ИК-сигнал нескольких пультов дистанционного управления с помощью AnalysisIR. Однако эти ИК-коды довольно длинные (массив из 343 элементов).

Объявление более одного кода IR в переменной приводит к ошибке: «Глобальные переменные используют 2064 байта (100%) динамической памяти, оставляя -16 байт для локальных переменных. Максимум - 2048 байт».

Однако, как видно из моего кода, я объявил ИК-коды локально в отдельной функции, чтобы отправить их на кондиционер. Я не понимаю, почему я получаю ошибку, говорящую о том, что глобальные переменные занимают слишком много динамической памяти.

Разве пространство, занимаемое локальной переменной, не должно освобождаться из SRAM после запуска функций, поскольку я объявил переменную локально?

Заранее спасибо.

Код:

#include <IRremote.h>


IRsend irsend;


int khz = 38;

void send23()
{

  unsigned int irSignal[]= {9048, 4496, 620, 1636, 620, 1636, 620, 520, 620, 520, 620, 524, 624, 524, 620, 532, 620, 1648, 620, 508, 620, 1640, 620, 1644, 620, 520, 620, 528, 616, 528, 620, 532, 624, 516, 620, 1636, 620, 516, 616, 520, 620, 520, 620, 524, 620, 528, 616, 536, 620, 520, 620, 508, 620, 1640, 620, 520, 620, 520, 620, 1648, 620, 1656, 620, 1656, 616, 524, 620, 508, 620, 516, 616, 520, 620, 520, 624, 520, 620, 528, 620, 532, 620, 520, 620, 508, 624, 508, 624, 516, 616, 520, 624, 524, 620, 524, 620, 532, 620, 504, 620, 7956, 616, 512, 620, 1640, 616, 520, 620, 520, 620, 524, 620, 528, 620, 528, 624, 1644, 620, 1636, 616, 1640, 624, 1640, 620, 1648, 616, 528, 620, 1652, 620, 532, 620, 520, 620, 512, 620, 512, 620, 516, 620, 524, 620, 524, 616, 528, 620, 532, 620, 520, 620, 508, 620, 512, 624, 512, 620, 520, 620, 520, 620, 528, 620, 532, 620, 520, 620, 508, 620, 516, 620, 516, 620, 520, 620, 524, 620, 524, 624, 528, 624, 516, 620, 508, 620, 512, 624, 512, 624, 516, 624, 520, 624, 524, 624, 528, 620, 520, 624, 504, 624, 512, 620, 516, 624, 516, 620, 524, 620, 524, 624, 528, 620, 520, 624, 504, 624, 1636, 624, 1640, 624, 1640, 624, 1648, 620, 524, 624, 1656, 624, 1624, 624, 7952, 616, 512, 624, 508, 624, 512, 624, 516, 624, 520, 624, 524, 624, 524, 624, 520, 624, 504, 624, 1636, 624, 512, 624, 516, 624, 520, 624, 524, 624, 524, 628, 516, 624, 504, 624, 508, 624, 512, 624, 516, 624, 520, 624, 524, 620, 528, 628, 512, 624, 508, 624, 508, 624, 512, 620, 520, 620, 524, 624, 520, 624, 528, 624, 516, 620, 508, 624, 508, 624, 512, 624, 1640, 624, 520, 624, 524, 624, 528, 624, 512, 628, 504, 624, 508, 624, 512, 624, 516, 624, 520, 624, 524, 624, 528, 624, 516, 620, 508, 624, 1632, 628, 508, 628, 1640, 624, 520, 624, 524, 620, 528, 624, 500, 608};
  irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz); //Note the approach used to automatically calculate the size of the array.
}

void send22()
{

  unsigned int irSignal[]=  {8988, 4548, 572, 1688, 572, 1688, 600, 532, 572, 568, 572, 572, 576, 572, 572, 580, 572, 1724, 544, 556, 576, 1684, 600, 1660, 608, 532, 604, 540, 608, 540, 600, 548, 608, 536, 604, 1652, 608, 520, 616, 524, 608, 532, 612, 532, 612, 532, 620, 532, 616, 524, 620, 512, 616, 1644, 624, 508, 628, 516, 624, 520, 628, 1676, 596, 1648, 632, 508, 632, 500, 632, 500, 632, 504, 636, 504, 636, 512, 628, 516, 632, 524, 628, 508, 636, 496, 632, 504, 628, 508, 632, 508, 632, 512, 632, 516, 632, 516, 632, 496, 628, 7948, 628, 500, 632, 1656, 600, 508, 628, 508, 632, 512, 632, 516, 632, 524, 628, 1636, 632, 496, 632, 504, 632, 504, 632, 508, 632, 1672, 600, 1672, 600, 520, 632, 508, 632, 500, 652, 480, 632, 504, 632, 512, 628, 512, 632, 516, 632, 520, 632, 508, 632, 496, 632, 504, 632, 504, 632, 508, 632, 516, 628, 520, 628, 520, 656, 484, 632, 500, 656, 476, 656, 480, 632, 508, 632, 516, 632, 512, 656, 496, 632, 508, 632, 500, 652, 480, 632, 504, 656, 484, 656, 488, 632, 516, 632, 520, 632, 508, 632, 500, 656, 476, 632, 508, 656, 484, 656, 488, 656, 492, 632, 520, 656, 484, 656, 1632, 624, 476, 632, 508, 656, 484, 656, 1620, 652, 488, 656, 1656, 600, 1648, 604, 7948, 656, 472, 656, 476, 660, 480, 632, 508, 656, 488, 652, 496, 656, 492, 656, 484, 632, 500, 656, 1608, 628, 504, 656, 484, 656, 488, 656, 492, 656, 496, 656, 484, 632, 496, 656, 480, 632, 504, 656, 484, 656, 488, 632, 516, 656, 496, 628, 508, 660, 472, 656, 480, 656, 480, 652, 488, 656, 488, 656, 492, 652, 496, 660, 484, 656, 472, 632, 504, 652, 484, 652, 1644, 624, 488, 656, 492, 656, 492, 632, 512, 628, 500, 664, 468, 656, 480, 656, 488, 652, 488, 656, 492, 656, 492, 632, 512, 652, 476, 656, 1632, 624, 484, 652, 1644, 620, 492, 656, 488, 628, 524, 652, 472, 608};
  irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz); //Note the approach used to automatically calculate the size of the array.
}

void setup()
{
  Serial.begin(9600);
  pinMode(13,OUTPUT);
  delay(2000);
  send23();
  delay(2000);
  send22();
}

void loop() {

}

РЕДАКТИРОВАНИЕ 05/07:

Вот мой новый код с использованием PROGMEM.

Как вы видите, я инициализировал массивы progmem глобально в верхней части программы. Когда я это делаю, моя SRAM больше не заполнена, но sendraw в функциях больше не работает.

Как ни странно, когда я объявляю переменную progmem ВНУТРИ функции send23() (В КОММЕНТАРИЯХ), sendraw работает! Но переменная снова занимает место в SRAM, и это говорит о том, что глобальные переменные использовали 100% динамической памяти.

Почему это происходит и что можно сделать, чтобы это обойти?

PROGMEM обновил код:

#include <IRremote.h>

const unsigned int irSignal23[] PROGMEM = {9048, 4496, 620, 1636, 620, 1636, 620, 520, 620, 520, 620, 524, 624, 524, 620, 532, 620, 1648, 620, 508, 620, 1640, 620, 1644, 620, 520, 620, 528, 616, 528, 620, 532, 624, 516, 620, 1636, 620, 516, 616, 520, 620, 520, 620, 524, 620, 528, 616, 536, 620, 520, 620, 508, 620, 1640, 620, 520, 620, 520, 620, 1648, 620, 1656, 620, 1656, 616, 524, 620, 508, 620, 516, 616, 520, 620, 520, 624, 520, 620, 528, 620, 532, 620, 520, 620, 508, 624, 508, 624, 516, 616, 520, 624, 524, 620, 524, 620, 532, 620, 504, 620, 7956, 616, 512, 620, 1640, 616, 520, 620, 520, 620, 524, 620, 528, 620, 528, 624, 1644, 620, 1636, 616, 1640, 624, 1640, 620, 1648, 616, 528, 620, 1652, 620, 532, 620, 520, 620, 512, 620, 512, 620, 516, 620, 524, 620, 524, 616, 528, 620, 532, 620, 520, 620, 508, 620, 512, 624, 512, 620, 520, 620, 520, 620, 528, 620, 532, 620, 520, 620, 508, 620, 516, 620, 516, 620, 520, 620, 524, 620, 524, 624, 528, 624, 516, 620, 508, 620, 512, 624, 512, 624, 516, 624, 520, 624, 524, 624, 528, 620, 520, 624, 504, 624, 512, 620, 516, 624, 516, 620, 524, 620, 524, 624, 528, 620, 520, 624, 504, 624, 1636, 624, 1640, 624, 1640, 624, 1648, 620, 524, 624, 1656, 624, 1624, 624, 7952, 616, 512, 624, 508, 624, 512, 624, 516, 624, 520, 624, 524, 624, 524, 624, 520, 624, 504, 624, 1636, 624, 512, 624, 516, 624, 520, 624, 524, 624, 524, 628, 516, 624, 504, 624, 508, 624, 512, 624, 516, 624, 520, 624, 524, 620, 528, 628, 512, 624, 508, 624, 508, 624, 512, 620, 520, 620, 524, 624, 520, 624, 528, 624, 516, 620, 508, 624, 508, 624, 512, 624, 1640, 624, 520, 624, 524, 624, 528, 624, 512, 628, 504, 624, 508, 624, 512, 624, 516, 624, 520, 624, 524, 624, 528, 624, 516, 620, 508, 624, 1632, 628, 508, 628, 1640, 624, 520, 624, 524, 620, 528, 624, 500, 608};
const unsigned int irSignal22[] PROGMEM = {8988, 4548, 572, 1688, 572, 1688, 600, 532, 572, 568, 572, 572, 576, 572, 572, 580, 572, 1724, 544, 556, 576, 1684, 600, 1660, 608, 532, 604, 540, 608, 540, 600, 548, 608, 536, 604, 1652, 608, 520, 616, 524, 608, 532, 612, 532, 612, 532, 620, 532, 616, 524, 620, 512, 616, 1644, 624, 508, 628, 516, 624, 520, 628, 1676, 596, 1648, 632, 508, 632, 500, 632, 500, 632, 504, 636, 504, 636, 512, 628, 516, 632, 524, 628, 508, 636, 496, 632, 504, 628, 508, 632, 508, 632, 512, 632, 516, 632, 516, 632, 496, 628, 7948, 628, 500, 632, 1656, 600, 508, 628, 508, 632, 512, 632, 516, 632, 524, 628, 1636, 632, 496, 632, 504, 632, 504, 632, 508, 632, 1672, 600, 1672, 600, 520, 632, 508, 632, 500, 652, 480, 632, 504, 632, 512, 628, 512, 632, 516, 632, 520, 632, 508, 632, 496, 632, 504, 632, 504, 632, 508, 632, 516, 628, 520, 628, 520, 656, 484, 632, 500, 656, 476, 656, 480, 632, 508, 632, 516, 632, 512, 656, 496, 632, 508, 632, 500, 652, 480, 632, 504, 656, 484, 656, 488, 632, 516, 632, 520, 632, 508, 632, 500, 656, 476, 632, 508, 656, 484, 656, 488, 656, 492, 632, 520, 656, 484, 656, 1632, 624, 476, 632, 508, 656, 484, 656, 1620, 652, 488, 656, 1656, 600, 1648, 604, 7948, 656, 472, 656, 476, 660, 480, 632, 508, 656, 488, 652, 496, 656, 492, 656, 484, 632, 500, 656, 1608, 628, 504, 656, 484, 656, 488, 656, 492, 656, 496, 656, 484, 632, 496, 656, 480, 632, 504, 656, 484, 656, 488, 632, 516, 656, 496, 628, 508, 660, 472, 656, 480, 656, 480, 652, 488, 656, 488, 656, 492, 652, 496, 660, 484, 656, 472, 632, 504, 652, 484, 652, 1644, 624, 488, 656, 492, 656, 492, 632, 512, 628, 500, 664, 468, 656, 480, 656, 488, 652, 488, 656, 492, 656, 492, 632, 512, 652, 476, 656, 1632, 624, 484, 652, 1644, 620, 492, 656, 488, 628, 524, 652, 472, 608};
const unsigned int irSignal21[] PROGMEM = {9044, 4496, 624, 1628, 628, 1592, 668, 508, 628, 512, 628, 516, 628, 520, 628, 524, 628, 1636, 632, 500, 628, 1632, 624, 1636, 628, 512, 628, 520, 628, 516, 628, 524, 628, 512, 628, 1628, 628, 512, 620, 512, 624, 516, 628, 516, 628, 520, 628, 524, 628, 512, 628, 500, 632, 1628, 628, 512, 628, 512, 628, 1644, 628, 520, 628, 1648, 628, 512, 628, 504, 624, 508, 628, 508, 632, 508, 628, 516, 632, 516, 628, 524, 628, 512, 628, 504, 628, 504, 628, 508, 628, 512, 628, 516, 628, 520, 628, 524, 624, 500, 624, 7948, 628, 504, 628, 1628, 628, 512, 624, 516, 624, 516, 628, 520, 628, 524, 628, 1636, 628, 504, 624, 1632, 628, 508, 628, 512, 628, 1640, 628, 1648, 628, 520, 628, 512, 628, 504, 628, 504, 628, 508, 628, 512, 628, 516, 628, 516, 628, 524, 628, 512, 628, 500, 628, 504, 628, 508, 628, 512, 628, 516, 628, 520, 628, 520, 628, 512, 628, 500, 632, 504, 628, 508, 628, 512, 624, 520, 624, 520, 628, 524, 624, 516, 624, 504, 628, 504, 628, 508, 628, 512, 628, 516, 628, 520, 628, 520, 628, 512, 628, 504, 628, 504, 628, 508, 624, 516, 628, 512, 628, 520, 628, 524, 624, 516, 628, 1624, 628, 1632, 628, 508, 628, 512, 628, 516, 628, 1644, 628, 1648, 628, 1620, 628, 7944, 628, 500, 628, 504, 628, 512, 624, 512, 628, 516, 628, 520, 628, 520, 628, 512, 628, 504, 624, 1636, 624, 508, 632, 508, 628, 516, 628, 520, 628, 520, 632, 512, 624, 504, 628, 504, 628, 508, 628, 512, 628, 516, 628, 520, 628, 524, 624, 516, 628, 500, 628, 504, 628, 508, 628, 512, 628, 516, 628, 520, 628, 524, 624, 512, 628, 504, 624, 508, 628, 508, 628, 1640, 624, 516, 628, 520, 628, 524, 624, 516, 624, 504, 628, 504, 628, 508, 628, 512, 628, 516, 628, 520, 628, 524, 624, 512, 628, 504, 628, 1632, 624, 512, 628, 1640, 624, 516, 628, 520, 628, 524, 628, 492, 612};

IRsend irsend;

int khz = 38;

void send23()
{

//  const unsigned int irSignal23[] PROGMEM = {9048, 4496, 620, 1636, 620, 1636, 620, 520, 620, 520, 620, 524, 624, 524, 620, 532, 620, 1648, 620, 508, 620, 1640, 620, 1644, 620, 520, 620, 528, 616, 528, 620, 532, 624, 516, 620, 1636, 620, 516, 616, 520, 620, 520, 620, 524, 620, 528, 616, 536, 620, 520, 620, 508, 620, 1640, 620, 520, 620, 520, 620, 1648, 620, 1656, 620, 1656, 616, 524, 620, 508, 620, 516, 616, 520, 620, 520, 624, 520, 620, 528, 620, 532, 620, 520, 620, 508, 624, 508, 624, 516, 616, 520, 624, 524, 620, 524, 620, 532, 620, 504, 620, 7956, 616, 512, 620, 1640, 616, 520, 620, 520, 620, 524, 620, 528, 620, 528, 624, 1644, 620, 1636, 616, 1640, 624, 1640, 620, 1648, 616, 528, 620, 1652, 620, 532, 620, 520, 620, 512, 620, 512, 620, 516, 620, 524, 620, 524, 616, 528, 620, 532, 620, 520, 620, 508, 620, 512, 624, 512, 620, 520, 620, 520, 620, 528, 620, 532, 620, 520, 620, 508, 620, 516, 620, 516, 620, 520, 620, 524, 620, 524, 624, 528, 624, 516, 620, 508, 620, 512, 624, 512, 624, 516, 624, 520, 624, 524, 624, 528, 620, 520, 624, 504, 624, 512, 620, 516, 624, 516, 620, 524, 620, 524, 624, 528, 620, 520, 624, 504, 624, 1636, 624, 1640, 624, 1640, 624, 1648, 620, 524, 624, 1656, 624, 1624, 624, 7952, 616, 512, 624, 508, 624, 512, 624, 516, 624, 520, 624, 524, 624, 524, 624, 520, 624, 504, 624, 1636, 624, 512, 624, 516, 624, 520, 624, 524, 624, 524, 628, 516, 624, 504, 624, 508, 624, 512, 624, 516, 624, 520, 624, 524, 620, 528, 628, 512, 624, 508, 624, 508, 624, 512, 620, 520, 620, 524, 624, 520, 624, 528, 624, 516, 620, 508, 624, 508, 624, 512, 624, 1640, 624, 520, 624, 524, 624, 528, 624, 512, 628, 504, 624, 508, 624, 512, 624, 516, 624, 520, 624, 524, 624, 528, 624, 516, 620, 508, 624, 1632, 628, 508, 628, 1640, 624, 520, 624, 524, 620, 528, 624, 500, 608};
  irsend.sendRaw(irSignal23, sizeof(irSignal23) / sizeof(irSignal23[0]), khz); //Note the approach used to automatically calculate the size of the array.
}

void send22()
{
//  const unsigned int irSignal22[] PROGMEM = {8988, 4548, 572, 1688, 572, 1688, 600, 532, 572, 568, 572, 572, 576, 572, 572, 580, 572, 1724, 544, 556, 576, 1684, 600, 1660, 608, 532, 604, 540, 608, 540, 600, 548, 608, 536, 604, 1652, 608, 520, 616, 524, 608, 532, 612, 532, 612, 532, 620, 532, 616, 524, 620, 512, 616, 1644, 624, 508, 628, 516, 624, 520, 628, 1676, 596, 1648, 632, 508, 632, 500, 632, 500, 632, 504, 636, 504, 636, 512, 628, 516, 632, 524, 628, 508, 636, 496, 632, 504, 628, 508, 632, 508, 632, 512, 632, 516, 632, 516, 632, 496, 628, 7948, 628, 500, 632, 1656, 600, 508, 628, 508, 632, 512, 632, 516, 632, 524, 628, 1636, 632, 496, 632, 504, 632, 504, 632, 508, 632, 1672, 600, 1672, 600, 520, 632, 508, 632, 500, 652, 480, 632, 504, 632, 512, 628, 512, 632, 516, 632, 520, 632, 508, 632, 496, 632, 504, 632, 504, 632, 508, 632, 516, 628, 520, 628, 520, 656, 484, 632, 500, 656, 476, 656, 480, 632, 508, 632, 516, 632, 512, 656, 496, 632, 508, 632, 500, 652, 480, 632, 504, 656, 484, 656, 488, 632, 516, 632, 520, 632, 508, 632, 500, 656, 476, 632, 508, 656, 484, 656, 488, 656, 492, 632, 520, 656, 484, 656, 1632, 624, 476, 632, 508, 656, 484, 656, 1620, 652, 488, 656, 1656, 600, 1648, 604, 7948, 656, 472, 656, 476, 660, 480, 632, 508, 656, 488, 652, 496, 656, 492, 656, 484, 632, 500, 656, 1608, 628, 504, 656, 484, 656, 488, 656, 492, 656, 496, 656, 484, 632, 496, 656, 480, 632, 504, 656, 484, 656, 488, 632, 516, 656, 496, 628, 508, 660, 472, 656, 480, 656, 480, 652, 488, 656, 488, 656, 492, 652, 496, 660, 484, 656, 472, 632, 504, 652, 484, 652, 1644, 624, 488, 656, 492, 656, 492, 632, 512, 628, 500, 664, 468, 656, 480, 656, 488, 652, 488, 656, 492, 656, 492, 632, 512, 652, 476, 656, 1632, 624, 484, 652, 1644, 620, 492, 656, 488, 628, 524, 652, 472, 608};
  irsend.sendRaw(irSignal22, sizeof(irSignal22) / sizeof(irSignal22[0]), khz); //Note the approach used to automatically calculate the size of the array.
}

void send21()
{
//  const unsigned int irSignal21[] PROGMEM = {9044, 4496, 624, 1628, 628, 1592, 668, 508, 628, 512, 628, 516, 628, 520, 628, 524, 628, 1636, 632, 500, 628, 1632, 624, 1636, 628, 512, 628, 520, 628, 516, 628, 524, 628, 512, 628, 1628, 628, 512, 620, 512, 624, 516, 628, 516, 628, 520, 628, 524, 628, 512, 628, 500, 632, 1628, 628, 512, 628, 512, 628, 1644, 628, 520, 628, 1648, 628, 512, 628, 504, 624, 508, 628, 508, 632, 508, 628, 516, 632, 516, 628, 524, 628, 512, 628, 504, 628, 504, 628, 508, 628, 512, 628, 516, 628, 520, 628, 524, 624, 500, 624, 7948, 628, 504, 628, 1628, 628, 512, 624, 516, 624, 516, 628, 520, 628, 524, 628, 1636, 628, 504, 624, 1632, 628, 508, 628, 512, 628, 1640, 628, 1648, 628, 520, 628, 512, 628, 504, 628, 504, 628, 508, 628, 512, 628, 516, 628, 516, 628, 524, 628, 512, 628, 500, 628, 504, 628, 508, 628, 512, 628, 516, 628, 520, 628, 520, 628, 512, 628, 500, 632, 504, 628, 508, 628, 512, 624, 520, 624, 520, 628, 524, 624, 516, 624, 504, 628, 504, 628, 508, 628, 512, 628, 516, 628, 520, 628, 520, 628, 512, 628, 504, 628, 504, 628, 508, 624, 516, 628, 512, 628, 520, 628, 524, 624, 516, 628, 1624, 628, 1632, 628, 508, 628, 512, 628, 516, 628, 1644, 628, 1648, 628, 1620, 628, 7944, 628, 500, 628, 504, 628, 512, 624, 512, 628, 516, 628, 520, 628, 520, 628, 512, 628, 504, 624, 1636, 624, 508, 632, 508, 628, 516, 628, 520, 628, 520, 632, 512, 624, 504, 628, 504, 628, 508, 628, 512, 628, 516, 628, 520, 628, 524, 624, 516, 628, 500, 628, 504, 628, 508, 628, 512, 628, 516, 628, 520, 628, 524, 624, 512, 628, 504, 624, 508, 628, 508, 628, 1640, 624, 516, 628, 520, 628, 524, 624, 516, 624, 504, 628, 504, 628, 508, 628, 512, 628, 516, 628, 520, 628, 524, 624, 512, 628, 504, 628, 1632, 624, 512, 628, 1640, 624, 516, 628, 520, 628, 524, 628, 492, 612};
  irsend.sendRaw(irSignal21, sizeof(irSignal21) / sizeof(irSignal21[0]), khz); //Note the approach used to automatically calculate the size of the array.
}

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  send23();
  Serial.println("done");
  delay(4000);
  send22();
  Serial.println("done");
  delay(4000);
  send21();
  Serial.println("done");
}

void loop() {
}

, 👍4

Обсуждение

Компилятор, вероятно, не так-то просто обмануть. Я не знаю, как компилятор с этим справляется, возможно, кто-то другой знает ответ. Вам действительно нужны целые числа? Или это несколько разных таймингов, которые можно поместить в байт? Я думаю, вам нужна плата Arduino с большим объемом памяти. Массивы константных данных относятся к progmem: https://www.arduino.cc/reference/en/language/variables/utilities/progmem/, @Jot

используйте PROGMEM https://www.arduino.cc/reference/en/language/variables/utilities/progmem/, @Juraj

Я также пробовал использовать PROGMEM. Однако, если константная переменная PROGMEM объявлена внутри функции 'loop', она все равно занимает место в SRAM. Если константная переменная PROGMEM объявлена вне какой-либо функции (глобально), она больше не занимает место в SRAM, но irRemote "функция sendRaw больше не работает"., @ihish52

сделать массив PROGMEM глобальным и скопировать его в оперативную память в функции, @Juraj

Можете ли вы подсказать мне, как скопировать глобальный массив PROGMEM в оперативную память во время выполнения функций?, @ihish52

memArr[i] = pgm_read_word_near(progmemArr[i]);, @Juraj


2 ответа


6

Разве пространство, занимаемое локальной переменной, не должно быть освобождено? из SRAM после запуска функций, поскольку я объявил переменная локально?

Это правильно. Локальные массивы, которые у вас есть, занимают оперативную память только в то время как Соответствующая функция выполняется. Они не потребляют никакой статической оперативной памяти (т.е. .data и .bss, то, что Arduino IDE неправильно называет «глобальными переменные»).

Проблема не в самих массивах, а в данных, используемых для их создания. инициализируйте их. В качестве эксперимента можно попробовать изменить массив определения следующие:

unsigned int irSignal[343];

Вы увидите, что потребление памяти, о котором сообщает IDE, снизится 4×343 байта. Локальные массивы все еще там. Они используют оперативную память (из стек) при выполнении функций. Только вы удалили соответствующие инициализаторы.

Я дизассемблировал слегка измененную копию вашей программы, просто чтобы посмотреть, как компилятор справляется с этим. Я не буду размещать здесь ассемблерный код, так как я думаю, не многие здесь свободно владеют сборкой AVR. Вместо этого я буду попытка перевести сборку обратно на C самым простым способом образом. Компилятор интерпретировал функцию send23() следующим образом:

static const unsigned int anonymous_array_1[343] = {9048, ...};

void send23()
{
    unsigned int irSignal[343];
    for (int i = 0; i < 343; i++)
        irSignal[i] = anonymous_array_1[i];
    irsend.sendRaw(irSignal, 343, khz);
}

То, что занимает статическую оперативную память, — это не локальные массивы, а глобальные анонимные массивы, которые содержат данные инициализации. Вы можете заметить, что Создание локальных массивов на самом деле ухудшило проблему: в то время как send23() выполняется, у вас есть две копии данных в оперативной памяти.

Решение, как сказали в комментариях Йот и Юрай, состоит в том, чтобы поместить массивы в PROGMEM. Если не работает, значит у вас ошибка. Вам следует исправить ошибка вместо того, чтобы попытаться избежать PROGMEM.

,

Да, я пробовал подход progmem. Пожалуйста, посмотрите мою правку в посте. Я предполагаю, что мне нужно теперь выяснить, как копировать переменную progmem в оперативную память, когда функция выполняется? Возможно, именно поэтому функция send raw не работает., @ihish52

Это теперь сильно отличается от вашего первоначального вопроса. Вы должны задать его как новый вопрос., @Edgar Bonet


5

Вы должны объявить массив в глобальном пространстве или static и убедиться, что функция, которой вы передаете указатель на буфер, знает, что он находится в PROGMEM.

void send22()
{

  static unsigned int irSignal[] PROGMEM=  {8988, 4548, 572, 1688, 572, 1688, 600, 532, 572, 568, 572, 572, 576, 572, 572, 580, 572, 1724, 544, 556, 576, 1684, 600, 1660, 608, 532, 604, 540, 608, 540, 600, 548, 608, 536, 604, 1652, 608, 520, 616, 524, 608, 532, 612, 532, 612, 532, 620, 532, 616, 524, 620, 512, 616, 1644, 624, 508, 628, 516, 624, 520, 628, 1676, 596, 1648, 632, 508, 632, 500, 632, 500, 632, 504, 636, 504, 636, 512, 628, 516, 632, 524, 628, 508, 636, 496, 632, 504, 628, 508, 632, 508, 632, 512, 632, 516, 632, 516, 632, 496, 628, 7948, 628, 500, 632, 1656, 600, 508, 628, 508, 632, 512, 632, 516, 632, 524, 628, 1636, 632, 496, 632, 504, 632, 504, 632, 508, 632, 1672, 600, 1672, 600, 520, 632, 508, 632, 500, 652, 480, 632, 504, 632, 512, 628, 512, 632, 516, 632, 520, 632, 508, 632, 496, 632, 504, 632, 504, 632, 508, 632, 516, 628, 520, 628, 520, 656, 484, 632, 500, 656, 476, 656, 480, 632, 508, 632, 516, 632, 512, 656, 496, 632, 508, 632, 500, 652, 480, 632, 504, 656, 484, 656, 488, 632, 516, 632, 520, 632, 508, 632, 500, 656, 476, 632, 508, 656, 484, 656, 488, 656, 492, 632, 520, 656, 484, 656, 1632, 624, 476, 632, 508, 656, 484, 656, 1620, 652, 488, 656, 1656, 600, 1648, 604, 7948, 656, 472, 656, 476, 660, 480, 632, 508, 656, 488, 652, 496, 656, 492, 656, 484, 632, 500, 656, 1608, 628, 504, 656, 484, 656, 488, 656, 492, 656, 496, 656, 484, 632, 496, 656, 480, 632, 504, 656, 484, 656, 488, 632, 516, 656, 496, 628, 508, 660, 472, 656, 480, 656, 480, 652, 488, 656, 488, 656, 492, 652, 496, 660, 484, 656, 472, 632, 504, 652, 484, 652, 1644, 624, 488, 656, 492, 656, 492, 632, 512, 628, 500, 664, 468, 656, 480, 656, 488, 652, 488, 656, 492, 656, 492, 632, 512, 652, 476, 656, 1632, 624, 484, 652, 1644, 620, 492, 656, 488, 628, 524, 652, 472, 608};
  irsend.sendRaw_P(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz); 
  // Постфикс _P часто используется для обозначения функций, принимающих указатели PROGMEM
}

Вы можете настроить библиотеку так, чтобы она могла принимать буферы PROGMEM, выполнив быстрый поиск по реализации IRsend::sendRaw, и она мне выдала:

void  IRsend::sendRaw (const unsigned int buf[],  unsigned int len,  unsigned int hz)
{
    // Установить несущую частоту ИК-сигнала
    enableIROut(hz);

    for (unsigned int i = 0;  i < len;  i++) {
        if (i & 1)  space(buf[i]) ;
        else        mark (buf[i]) ;
    }

    space(0);  // Всегда заканчивать выключением светодиода
}

Чтобы заставить его работать с progmem, вы можете создать:

void  IRsend::sendRaw_P (const unsigned int buf[],  unsigned int len,  unsigned int hz)
{
    // Установить несущую частоту I R
    enableIROut(hz);

    for (unsigned int i = 0;  i < len;  i++) {
        unsigned int word = pgm_read_word_near(buf + i);
        if (i & 1)  space(word) ;
        else        mark (word) ;
    }

    space(0);  // Всегда заканчивать выключением светодиода
}
,

Как мне приступить к редактированию существующей библиотеки IRremote?, @ihish52