-1

I am working on a project where I have to build an IR program that works with all of the AVR/Arduino boards to control the IR devices such as TV, DVD, etc. I am building a struct that can carry the Pronto code information and this is what I have so far:

struct Pronto {
    char* code;
public:
    Pronto(){}
    Pronto(char* code) {
        bool isValid = validateProntoCode(code);
        if(isValid)
            this->code = code;
    }
    Pronto toPronto(char* code) {
        Pronto cde(code);
        return cde;
    }
    void setPronto(char* code){
        bool isValid = validateProntoCode(code);
        if(isValid)
            this->code = code;
    }
    char* toString(){
        return code;
    }
    private:
    bool validateProntoCode(char* code) {
        if(!isInHex(code[strlen(code)-1]))
            return false;
        for (int i = 0; i < strlen(code); i++) {
            if (!isInHex(code[i]) && !(i % 5 == 4 ))
                return false;
            if (i % 5 == 4 && code[i] != ' ')
                return false;
            if (i % 5 == 0 && (!isInHex(code[i]) || !isInHex(code[i] + 1) || !isInHex(code[i] + 2) || !isInHex(code[i + 3])))
                return false;
        }
        return true;
    }
    bool isInHex(char c) {
        char list[22] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f'};
        for (int i = 0; i < 22; i++) {
            if (c == list[i])
                return true;
        }
        return false;
    }
};

This struct code I can set the Pronto code, validate it, and get the string value from it. Now, whenever I declare the struct inside the Arduino IDE:

pronto.setPronto("0000 006D 0000 00BF 009F 0031 0030 0010 0010 0031");

I get this following message:


Sketch uses 4082 bytes (12%) of program storage space. Maximum is 32256 bytes.

Global variables use 2137 bytes (104%) of dynamic memory, leaving -89 bytes for local variables. Maximum is 2048 bytes.

Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint.


Pictures:

https://prnt.sc/ohu4d9

https://prnt.sc/ohu4io

https://prnt.sc/ohu4m8

https://prnt.sc/ohu4pr

https://prnt.sc/ohu4tn

Basically, I just showed all my work on code I did. I commented out any global vars, nothing changed. BUT, when I comment "pronto.setPronto("0000 0000");", I get free space.


So, how can I modify this struct in-order for it not to take allot of space?


The char* code right? That's the problem. Now can you help me modify code or at least tell me how I can resolve this.

  • 2
    The struct itself does not use a lot of space, I see mainly the code itself with has 40 bytes. The message says, that your global variables take up 104% of the memory. There is the problem, but you didn't show us your global variables. Maybe you can reduce the number of global variables, when they don't really have to be declared the whole program runtime. – chrisl Jul 20 at 21:06
  • I did. When I comment out "pronto.setPronto("0000 0000");", I get allot more free space. But all the #define, #include and other global vars I commented out, nothing changed. I am going to add the url with pics on the post just to show you. – Alex Zhuravel Jul 20 at 22:00
  • Ehm, how long is the proto code there? It is definitely way longer than the one in your question – chrisl Jul 20 at 22:22
  • It shouldnt matter, the Pronto code can be as long as it can be. You know what it is right? All I did was to store the Pronto code string to char* variable. I couldn't use string nor its library since the header won't let me. I ended up using char*. – Alex Zhuravel Jul 20 at 23:59
  • You store the code in a global variable, so yes, it does matter, how big it is. You only have 2KB – chrisl Jul 21 at 6:41
1

In your screen shots you are using string literals that are waaaay longer than in your sample code. I suspect using PROGMEM could be a way to work around. But why bothering with constant strings and verify and convert them at run time and not store them as raw data instead? (Also the outcome of the verification for a constant string literal will be always the same. So consider removing verification of your production code.)

uint16_t myParsedProntoCode[] = {
    0x0000, 0x006D, 0x0000, 0x00BF, 0x009F, 0x0031, 0x0030, 0x0010, 0x0010, 0x0031
};

This is much more space efficient as storing a nibble (4 bits) requires only 4 bits instead of 8 bits. So just half the space, not even taking the pointless whitespaces into account.

  • Thank you so much, now it is saving up more space. – Alex Zhuravel Jul 29 at 2:37
0

Based on your question I prepared a fresh sketch (single file) to test the issue.

The code:

struct Pronto {
    char* code;
  public:
    Pronto() {}
    Pronto(char* code) {
      bool isValid = validateProntoCode(code);
      if (isValid)
        this->code = code;
    }
    Pronto toPronto(char* code) {
      Pronto cde(code);
      return cde;
    }
    void setPronto(char* code) {
      bool isValid = validateProntoCode(code);
      if (isValid)
        this->code = code;
    }
    char* toString() {
      return code;
    }
  private:
    bool validateProntoCode(char* code) {
      if (!isInHex(code[strlen(code) - 1]))
        return false;
      for (int i = 0; i < strlen(code); i++) {
        if (!isInHex(code[i]) && !(i % 5 == 4 ))
          return false;
        if (i % 5 == 4 && code[i] != ' ')
          return false;
        if (i % 5 == 0 && (!isInHex(code[i]) || !isInHex(code[i] + 1) || !isInHex(code[i] + 2) || !isInHex(code[i + 3])))
          return false;
      }
      return true;
    }
    bool isInHex(char c) {
      char list[22] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f'};
      for (int i = 0; i < 22; i++) {
        if (c == list[i])
          return true;
      }
      return false;
    }
};


Pronto pronto;

void setup() {
  pronto.setPronto("0000 006D 0000 00BF 009F 0031 0030 0010 0010 0031");
}

void loop() {}

The verification procedure for ATmega328P returns:

D:\Extra\Arduino\BatteryRestorer\BatteryRestorer.ino: In function 'void setup()':

D:\Extra\Arduino\BatteryRestorer\BatteryRestorer.ino:50:71: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

   pronto.setPronto("0000 006D 0000 00BF 009F 0031 0030 0010 0010 0031");

                                                                       ^
Sketch uses 844 bytes (2%) of program storage space. Maximum is 30720 bytes.
Global variables use 83 bytes (4%) of dynamic memory, leaving 1965 bytes for local variables. Maximum is 2048 bytes.

Can you check if this one file sketch is still experiencing the issue? Maybe you installed and linked a library that allocates a lot of global variables.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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