Ram vs Flash - Using large arrays

I have a question about RAM vs ROM.

I have a pretty simple program running on my 'Core. A few lines of code really. The problem however is that these few lines of code require a fairly huge byte array.

static unsigned char image[] PROGMEM = 

image is 5929 bytes large. When I compile I get the following error:
region `RAM' overflowed by 5096 bytes
which obviously indicates that my image is to blame. My question is, how do I fix this? I ask because the exact same code runs on a Arduino MEGA without problems. The mega has the same amount of Flash and significantly less SRAM (8KB vs 20KB). So I know this can be done, I’m just not sure how. Would it be possible to save the image file to flash somehow?

Thanks for the help.

So PROGMEM does nothing in the core compiler, I think. Try declaring your array as a global constant:

const unsigned char image[] = 
          { 0xFF, ...
1 Like

@harrisonhjones, @bko, PROGMEM is defined as nothing since there is no equivalency in in the Core. The use of “const” place the array in flash instead of RAM. :smile:

1 Like

Thanks @bko and @peekay123.

I was able to compile my code and place it on the core but the result was not the same as what I got on the mega. Instead of displaying a picture of a person I get what looks like random vertical lines

I’ve narrowed it down to what I imagine is the problem. The following command is used to read the image data:

pixels = pgm_read_byte_near(data + b -1) & 0xaa;

I imagine the use of pgm_read_byte_near is my problem. Suggestions?

[Edit] And NEVERMIND. The library’s functions are flexible enough to not use pgm_read_byte_* but the library itself didn’t expose this feature. Wrapped it in a #ifdef (SPARK) and it works now. Thanks both of you!

[Edit 2] I would like to be able to update the data in memory in runtime. Is that possible? For example, I’d like to download a file over TCP and replace the image in flash. Pointers?

1 Like

@harrisonhjones, you might already be aware, but since this seems to be a common issue when porting Arduino libs some macros have been widely used to work around that

// just two to start with
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr))

// These can be defined for the xxx_near versions, too

// There are also some prog_xxx var types that ca be treated similarly

Unfortunately there seems to be no such ease dropin and forget macro for PROGMEM, there you have to have two versions for Arduino and Spark, I think.
But if the var is already declared as const it’s - as @peekay123 already said - placed in flash on the Core, so PROGMEM can just be #define PROGMEM and on Arduino PROGMEM will do its job for const vars just as well.