1

I'm working on a code that is able to send raw data as IR signal to IR transmitter, the memory of arduino Nano is not enough to store the array in SRAM storage,so i'm about to use PROGMEM to store arrays in flash memory.

these are arrays for IR signal raw command:

unsigned int irSignaloff[]={6060, 7420, 532, 1652, 544, 1668, 508, 1688, 508, 1688, 508, 1692, 532, 1664, 532, 1664, 532, 1664, 536, 604, 528, 588, 548, 580, 552, 580, 528, 636, 500, 600, 532, 588, 548, 580, 552, 1644, 552, 1644, 528, 1664, 532, 1668, 532, 1664, 532, 1668, 528, 1668, 528, 1668, 508, 624, 536, 600, 532, 600, 536, 576, 528, 600, 532, 604, 532, 604, 532, 580, 552, 1648, 548, 1648, 552, 1644, 552, 1648, 552, 1644, 552, 1640, 556, 1644, 528, 1668, 528, 600, 508, 624, 512, 620, 536, 600, 536, 604, 528, 576, 508, 624, 532, 604, 532, 1660, 536, 1660, 540, 596, 536, 1644, 552, 1648, 552, 1644, 552, 580, 524, 1672, 524, 604, 508, 624, 536, 1660, 536, 632, 504, 580, 552, 608, 500, 1668, 528, 600, 508, 1688, 512, 1684, 560, 1668, 504, 660, 500, 1660, 536, 604, 532, 1656, 540, 1660, 540, 584, 548, 580, 528, 596, 512, 1688, 508, 660, 500, 1660, 536, 596, 540, 584, 548, 604, 500, 1672, 528, 600, 512, 1684, 512, 620, 540, 1656, 540, 600, 536, 580, 552, 1644, 552, 576, 528, 1668, 532, 600, 508, 1688, 536, 596, 536, 1660, 540, 1660, 536, 7420, 536};



unsigned int irSignalon[]={6156, 7336, 592, 1588, 612, 1584, 612, 1588, 608, 1588, 608, 1588, 604, 1592, 604, 1592, 604, 1592, 604, 528, 504, 628, 588, 548, 588, 552, 580, 524, 608, 524, 572, 560, 592, 540, 588, 1608, 592, 1604, 592, 1604, 592, 1608, 592, 1604, 592, 1604, 592, 1604, 596, 1600, 596, 524, 608, 520, 584, 544, 596, 540, 596, 536, 596, 524, 608, 520, 604, 524, 588, 1608, 588, 1608, 588, 1608, 588, 1608, 588, 1612, 536, 1660, 572, 1624, 572, 1628, 564, 600, 504, 628, 504, 580, 528, 600, 636, 528, 540, 564, 532, 588, 548, 604, 504, 1664, 532, 604, 504, 624, 536, 1660, 532, 1664, 532, 1664, 532, 604, 532, 1660, 536, 584, 548, 1652, 548, 1644, 552, 580, 556, 572, 532, 604, 532, 1664, 532, 600, 532, 1668, 532, 1660, 536, 1688, 532, 600, 536, 1664, 532, 584, 620, 1576, 552, 1644, 552, 576, 532, 604, 608, 524, 532, 1664, 608, 512, 620, 1576, 548, 580, 556, 572, 600, 536, 604, 1588, 608, 528, 536, 1660, 536, 584, 620, 1580, 620, 508, 596, 532, 508, 1688, 512, 620, 536, 1660, 604, 532, 608, 1588, 604, 516, 620, 1576, 620, 1576, 624, 7308, 552}; 

and this is sending command uses IRemote.h library:

 irSend.sendRaw(irSignalon, sizeon, FREQ_KHZ, false);

so how can i use PROGMEM to store and read this int array in order to send them? thanks

7
  • Unless the IR library supports reading from PROGMEM you can't use PROGMEM.
    – Majenko
    Commented Jun 5, 2020 at 11:00
  • 1
    You are using 788 bytes there. Yes, that's a lot for a Nano, but way below the limit. Maybe you should be pruning your other RAM usage which must total more than just these two arrays if you are running out of memory.
    – Majenko
    Commented Jun 5, 2020 at 11:06
  • Understanding/decoding the IR signals and not using the raw timings would be also more space efficient.
    – Kwasmich
    Commented Jun 5, 2020 at 14:08
  • do not use raw .... convert the time intervals to actual data ... the first line is unsigned int irSignaloff[]={start, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, end} ..... that is same as hexadecimal 00ff 00ff 00ff 22dd 14eb ab54
    – jsotola
    Commented Jun 5, 2020 at 16:32
  • what is the make and model of the device that you are controlling?
    – jsotola
    Commented Jun 5, 2020 at 16:40

1 Answer 1

1

If your IR library does not support sending signals stored in PROGMEM, then you will have to provide the data in RAM. However, you do not have to keep both signals in RAM permanently: only the one you are about to send needs to be there.

I suggest you keep all the IR signal data in PROGMEM while not sending them. Whenever you want to send a signal, you copy it to a RAM-based buffer and give the address of that buffer to the library. The same buffer will be reused for any signal you are sending. This will cost you some CPU time for the copy, and save 394 bytes of RAM. The savings will scale up if you add more signals to your sketch.

const size_t signal_size = 197;

static PROGMEM const uint16_t irSignaloff[signal_size] = { ... };

static PROGMEM const uint16_t irSignalon[signal_size] = { ... };

/* Send an IR signal from PROGMEM. */
void send_signal(const uint16_t *signal) {
    static uint16_t signal_buffer[signal_size];
    memcpy_P(signal_buffer, signal, signal_size * sizeof *signal);
    irSend.sendRaw(signal_buffer, signal_size, FREQ_KHZ, false);
}

//...
send_signal(irSignalon);
send_signal(irSignaloff);

Here I am assuming that all your signals have the same length, which is true for the example you show, but may be false if you add more signals later. You may then need to size the buffer as the longest of all your signals, and provide the signal length as an extra parameter to send_signal().

Note that the RAM buffer does not need to be static. I chose to make it static here only in order for avr-size to give you a good estimate of the memory requirement of the program.

1
  • thank you so much, i just added the size of array as input of send_signal function to cover multiple commands and worked fine. void send_signal(const uint16_t *signal,const size_t size) { unsigned int signal_buffer[size]; memcpy_P(signal_buffer, signal, size * sizeof *signal); irsend.sendRaw(signal_buffer, size, khz); }
    – M sayeh
    Commented Jun 5, 2020 at 17:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.