insufficient memory

guys, i have a project to send the commands to activate the air conditioner via infrared.
however the IDE is not compiling because the code is consuming all memory (global variables are leaving little space for local variables ...)
this way, I created a function where this function saves the value of the code in a GLOBAL variable (string).
in other words, I have 900 ifs, and depending on the condition, 1 or other runs ...
but all of these ifs are consuming memory, even though only 1 will be executed at a time by the function.
I made a short version of the code, to facilitate the understanding.

boolean teste = true;
String cdIRTemp;
int Temp=18;

void setup() {
  Serial.begin(15200);
  FuncaoGravaCOdigoVariavelGlobal();
}

void loop() {
  // put your main code here, to run repeatedly:

}


void FuncaoGravaCOdigoVariavelGlobal(){
  if (teste){
    switch(Temp){
      case 16:{
          cdIRTemp="23CB26010064030F00000000800B";
        }
        break;
      case 17:{
          cdIRTemp="23CB26010064030F000000008001";
        }
        break;
      case 18:{
          cdIRTemp= "23CB26010064030D000000008002";
        }
        break;
      case 19:{
          cdIRTemp= "23CB26010064030D000000008003";
        }
        break;
      case 20:{
          cdIRTemp= "23CB26010064030D000000008004";
        }
        break;
      case 21:{
          cdIRTemp= "23CB26010064030D000000008005";
        }
        break;
      case 22:{
          cdIRTemp= "23CB26010064030D000000008006";
        }
        break;
    }
    Serial.println(cdIRTemp);
  }
}

in this case the function FuncaoGravaCOdigoVariavelGlobal checks the condition, and saves in the variable cdIRTemp the value that it must have, however, each of these cases is consuming memory ...
according to the images below, the difference in the use of memory when only 1 case assigns value and when everyone assigns value:

what can i do to decrease memory usage in this case?

remembering that the code above is the short version to exemplify the problem. in my complete code there are about 1000 ifs, and in this case there is not enough memory

Which Arduino?

900 ifs or 900 cases? Either way, it seems excessive.

Using String can consume a lot of memory and is not recommended. C strings would be better.

An array-based approach may be more appropriate.

I would prefer to see real code. The example does not exceed memory and repeats many of the same digits.

Storing and retrieving data from PROGMEM may be helpful.

Take a look in the reference at progmem. You can use it to store an array of your strings. Should make the code much simpler too.

Question about the text you are saving to cdIRTemp, is that text different every time, or is there a lot of repetition amount all your if and switch statements? Just in your example it appears that only the last character is changing, so writing out the entire text every time is very wasteful. Ideally all that text would be stored in PROGMEM.

vaj4088:
Which Arduino?

900 ifs or 900 cases? Either way, it seems excessive.

Using String can consume a lot of memory and is not recommended. C strings would be better.

An array-based approach may be more appropriate.

I would prefer to see real code. The example does not exceed memory and repeats many of the same digits.

Storing and retrieving data from PROGMEM may be helpful.

there are 180 ifs and within each if there are 16 cases. I don't understand why so much memory is consumed since only 1 variable is used. can progmem be used for variables that change value or just for constants?

david_2018:
Question about the text you are saving to cdIRTemp, is that text different every time, or is there a lot of repetition amount all your if and switch statements? Just in your example it appears that only the last character is changing, so writing out the entire text every time is very wasteful. Ideally all that text would be stored in PROGMEM.

the value is never the same. in the simplified code I changed only the last digit but in fact it always changes several (infrared hexadecinal code). I can't understand why the Arduino is reserving memory for each assignment since there can only be 1 assignment to the variable cdIRTemp at each function call

damyanhansen:
I don't understand why so much memory is consumed since only 1 variable is used. can progmem be used for variables that change value or just for constants?

Every string (like "23CB26010064030D000000008006") is copied into RAM when the program starts. Put it in PROGMEM and it will not be copied into RAM.

PROGMEM is only for constant values.

cdIRTemp= "23CB26010064030D000000008006";

This statement has a 28-character literal text. That will take 29 characters of dynamic memory to store (a null character is added to indicate the end of the text). The compiler will optimize the size of the code by only saving a single copy of the text if it is used in multiple places, but that still means that for each unique text you will need 29 bytes of memory.

The arduino has to save all the text, because it does not know which one it will need until the code is actually running. (actually it does trim out the unused ones, take your sample code and add the instruction Temp = random(23); at the top of your function, you will see the ram usage increase because the compiler is assuming that only case 18 will be used and removes the others);

I find it hard to believe that you have 180 x 16 different IR codes, that is a total of 2880 different codes - I would love to see the remote that comes with that air conditioner.

david_2018:

cdIRTemp= "23CB26010064030D000000008006";

This statement has a 28-character literal text. That will take 29 characters of dynamic memory to store (a null character is added to indicate the end of the text). The compiler will optimize the size of the code by only saving a single copy of the text if it is used in multiple places, but that still means that for each unique text you will need 29 bytes of memory.

The arduino has to save all the text, because it does not know which one it will need until the code is actually running. (actually it does trim out the unused ones, take your sample code and add the instruction Temp = random(23); at the top of your function, you will see the ram usage increase because the compiler is assuming that only case 18 will be used and removes the others);

I find it hard to believe that you have 180 x 16 different IR codes, that is a total of 2880 different codes - I would love to see the remote that comes with that air conditioner.

air conditioning. each key pressed is sent various information such as mode, temperature, fan, vertical swing, horizontal swing, light on or not .... all these combinations with each other generate this enormous amount of possibilities (cdIRTemp). so we got to that huge amount.

damyanhansen:
air conditioning. each key pressed is sent various information such as mode, temperature, fan, vertical swing, horizontal swing, light on or not .... all these combinations with each other generate this enormous amount of possibilities (cdIRTemp). so we got to that huge amount.

Can you post a reference to the air conditioner or the data format? If the various bits of information are coded into specific parts the the IR code, it seems that it would be possible to build up the code from the information instead of saving every possible combination separately.

Those strings look like hexadecimal values. Each 28 character string can be replaced by a unique 14 byte binary value (you can place it in an array). Bang, you just cut your memory usage in half.

I am also highly skeptical about your claim that there isn't any way you can synthesize a code from the parameters, rather than storing all the literal values. It's hard to imagine how you even discovered and indexed them all.

Progmen is the solution for storage of the infrared codes, but they can be store a lot more efficiently than they are now. 23CB 2601 0064 030F 0000 0000 800B B This is a hexadecimal representation of a value, that means that for every byte stored, your are using 2 bytes to represent them, that is wasteful. The conversion to String only needs to be done once and if you are only using it like you are now Serial.println(cdIRTemp);(probably not though) it hardly takes any effort (it hardly does anyway)

I used the PROGMEM and managed to compile the project with all the IR codes.
Thank you so much guys!

I would be AMAZED if the code allows for more than 8-12 unique bits for the function. The rest is just "ID" and redundancy, that is the same for ALL codes. Common IR formats have an ID code, and a button/function code, and each is typically sent twice - once normally, and once inverted. This is done because IR is VERY susceptible to ambient thermal noise. For example, the NEC format consists of 8-bits of '0', followed by 8-bits of '1', followed by an 8-bit function code, followed by the 8-bit function code inverted. So, once the full 32-bt code is validated, the specific button being pressed, or function being called, can be determined by looking at only 8 bits of the 32-bit code. Trying to decode using gigantic ASCII HEX strings is THE most wasteful possible way to go, short of ASCII binary.

Regards,
Ray L.