I am #define-ing a huge but constant 800-byte array of configuration commands for a doodad called an EZ-Radio. The goal is to keep this array in program memory then load it into local memory the exactly one time I need to. I absolutely do NOT want to reserve 1/3 of my 2560 bytes of memory for this array. I have tried many many things, here is how I am accessing the array right now:
#define MY_DEFINED_ARRAY {0x08, 0x04, 0x21 ... ~800 more bytes ... 0x13, 0x15, 0x1B}
uint8_t getIndex(int i) {
uint8_t my_huge_array[] = MY_DEFINED_ARRAY; //the only place this huge array is mentioned or used
return my_huge_array[i];
}
Despite reading everywhere that variables defined in functions will be local and not global, doing it this way still reserves 1/3 of my memory. Is it because I #define-ed the array? If that's the case, how can I access a #define-ed array without creating a global variable and reserving way too much memory?
Whether or not you leave the array in memory you still need to leave room for it or this function will overflow the stack and crash your code. The fact that it's only needed once doesn't do anything for letting you use that memory elsewhere.
It would be better to just put the array in progmem if it isn't changing. Then it lives in flash and never takes any of your 2K of ram.
PROGMEM occurred to me, I could absolutely do it like that. Unfortunately I am importing the array from headers generated by another program, so redoing the headers every time i generate one to use PROGMEM would kind of suck. Also I believe that #define will cause the array to be essentially copy/pasted into the right spot of program memory, then loaded into dynamic memory when the time comes. If I'm wrong about that.... well, I know what the problem is.
No it means you always need at least 800 bytes on the stack for when you use the function but other functions not called at the same time could also require 800 bytes too.
If the platform is AVR - the reason is due to the way the compiler places data in RAM and not flash unless told so (would happen too for const char* text) contrary to an ESP32 for example. This has to do with the Harvard architecture.
So +1 on the idea of using PROGMEM if it’s an AVR based arduino.
This makes sense. I was mistaken in believing that the #define would cause "my_huge_array[] = {0x08, 0x04, 0x21 ... ~800 more bytes ... 0x13, 0x15, 0x1B}" to be stored in program memory. It seems like that was wishful thinking. I'm now doing it like this:
Well, since you already marked this as "resolved". I just want to point out a beautiful and powerful feature of C family programming languages.
It's called "Pointer". Tadah!
They make an inexpensive part called FRAM which is Nov-volatile that is driven by I2C, works the same as EEPROM but does not have the life or speed problems. They can be gotten in I2C or SPI, 32Kx8 is just a few $$$