Cannot put large data in PROGMEM

Hi, everyone. i'm recently using a TFT screen to do some work. I need to put several image,which are converted to arrays in forms like(prog_uint16_t image_baby[0x6E4] PROGMEM ={...}),into flash memory.
The size of arrays vary from 3kByte to 46kByte, and there are 12 of them. The total size is less than 100kB.

When i put about 8 of them into my sketch, everything works fine.
However, if i put one more array into the program, strange thing happens.The sketch would compile and upload, but arduino does not act as expected. I note that the LED on arduino(pin 13?) is blinking at about 2Hz.

Why does this happen and How to fix this?

I am using 1.0.5 ,OSX and Mega2560,display uses UTFT library

Later i tried the 1.5.x version,but it seems to change the way of putting things into PROGMEM. the old sketch would not compile, and the comments in avr/progmem.h says the method of prog_uint16_t image_baby[0x6E4] PROGMEM ={...} is deprecated. But what is the new way? i seem not to find much useful data.

thanks to pyro_65,now i can compile on 1.5.8. Now the sketch would compile and run. If i only try to display 8 pictures, everything works fine. However,if i try to display exactly one more, all the display function does not work. but other function like Serial.println works fine.

here is part of my code.The whole program is a little complicated and large to be put here,but if they are needed i shall post as well.
Thank everyone in advance!!

project.ino

//numerous images...
#include "baby.h"
#include "dad.h"
#include "eat.h"
#include "name.h"

#include "one.h"
#include "two.h"
#include "three.h"
#include "four.h"
#include "five.h"
#include "six.h"
#include "seven.h"
#include "eight.h"

baby.h

// Generated by  : ImageConverter 565 v2.1
// Generated from: (4).bmp
// Time generated: 2014/12/28 19:41:34
// Dimensions    : 54x67 pixels
// Size          : 7,236 Bytes

#include <avr/pgmspace.h>

prog_uint16_t wrd_baby [0xE22] PROGMEM ={
0xFFFF, 0xFFFF, 0xFFFF, ....... };

looks like you are running out of memory...

When you compile your sketch, the IDE should show you the size of the compiled program. Does it exceed 248kB? Or getting very close to it?

In 1.5.7 and above, you'll need to make the declaration 'const'. Also just use uint16_t, not prog_uint16_t (all it does is add PROGMEM, which you do manually.)

const uint16_t wrd_baby [0xE22] PROGMEM ={0xFFFF, 0xFFFF, 0xFFFF, ... };

Might not be your only error, but its a start.

riesens:
looks like you are running out of memory...

When you compile your sketch, the IDE should show you the size of the compiled program. Does it exceed 248kB? Or getting very close to it?

Thank you for your reply. The sketch is 89kB. I updated the post,similar problem remains.

pYro_65:
In 1.5.7 and above, you'll need to make the declaration 'const'. Also just use uint16_t, not prog_uint16_t (all it does is add PROGMEM, which you do manually.)

const uint16_t wrd_baby [0xE22] PROGMEM ={0xFFFF, 0xFFFF, 0xFFFF, ... };

Might not be your only error, but its a start.

Thank you for your help,now i can compile and upload in 1.5.8,but still can't get arduino to work. I realize if i do not use a certain function, it is not included in the ultimate .hex file uploaded to arduino, is that true?

If so , than certain pictures just can't be put into flash.I'm really frustrating.

As I recall there is a 64k byte upper limit on PROGMEM.

Mark

holmes4:
As I recall there is a 64k byte upper limit on PROGMEM.

Mark

I now removed the largest picture (64k).

Is it a restrict on sum or individual? Where can i find more detailed information on this? data sheet of mega2560?

Where can i find more detailed information on this? data sheet of mega2560?

for arduino mega board detail go here

you can find datasheet of atmega2560 here

pYro_65:
In 1.5.7 and above, you'll need to make the declaration 'const'. Also just use uint16_t, not prog_uint16_t (all it does is add PROGMEM, which you do manually.)

const uint16_t wrd_baby [0xE22] PROGMEM ={0xFFFF, 0xFFFF, 0xFFFF, ... };

Might not be your only error, but its a start.

Hi again. i read your posts in Just a newby asking the 64k question again - Arduino Mega2560 - Programming Questions - Arduino Forum very inspiring,but sadly i still could not fully understand.
I did some calculation and I believe crossing the 64K gap is exactly the problem i'm facing now.
i located the lines that read from PROGMEM in UTFT and attempt to change them, here is an example

if (orient==PORTRAIT)
		{
			cbi(P_CS, B_CS);
			setXY(x, y, x+sx-1, y+sy-1);
			for (tc=0; tc<(sx*sy); tc++)
			{
				//col=pgm_read_word(&data[tc]);
                                  col=pgm_read_word_far(pgm_get_far_address(data[tc]));
				LCD_Write_DATA(col>>8,col & 0xff);
			}
			sbi(P_CS, B_CS);
		}

trying to compile i get error

UTFT/UTFT.cpp.o: In function `UTFT::drawBitmap(int, int, int, int, unsigned int*, int)':
/Volumes/Macintosh HD/Nick/Arduino/Programs/libraries/UTFT/UTFT.cpp:1257: undefined reference to `r30'
/Volumes/Macintosh HD/Nick/Arduino/Programs/libraries/UTFT/UTFT.cpp:1257: undefined reference to `r30'
/Volumes/Macintosh HD/Nick/Arduino/Programs/libraries/UTFT/UTFT.cpp:1257: undefined reference to `r30'

I find such reference in pgmspace.h. it seems to be an address?or register? anyway the assemble language is too much for me now.

here's one example of reference to r30

#define __LPM_word_classic__(addr)          \
(__extension__({                            \
    uint16_t __addr16 = (uint16_t)(addr);   \
    uint16_t __result;                      \
    __asm__ __volatile__                    \
    (                                       \
        "lpm"           "\n\t"              \
        "mov %A0, r0"   "\n\t"              \
        "adiw r30, 1"   "\n\t"              \
        "lpm"           "\n\t"              \
        "mov %B0, r0"   "\n\t"              \
        : "=r" (__result), "=z" (__addr16)  \
        : "1" (__addr16)                    \
        : "r0"                              \
    );                                      \
    __result;                               \
}))

plz help me to fix this. Any guidance will be much welcomed.

Nick

I did some more research and was able to get over the r30 problem. But the 64kB restrictions is still not solved whatsoever.

I find this on avrgeeks?

GET_FAR_ADDRESS macro has many limitations. It requires a compile-time known constant address (that's the reason to fail when the array element is accesed using a variable index) and operates at run-time (that's the reason why GET_FAR_ADDRESS it's not allowed to be used in variable initializations for const, flash, and generally for any static storage).

Keeping this in mind, i modified the UTFT library again.
i have the drawBitmap routine to take uint_farptr_t variable data. and changed the original

col=pgm_read_word(&data[tc]);

to

col=pgm_read_word_far(data+tc*2);

where data denotes: get_far_address(bitmap_data_array),since bitmap_data_arrays are known at compile time, the macro works fine
data was originally uint16_t* (so every data[] takes 2byte)

with a little modification on my .ino file(changing the parameter send to drawBitmap()),the program runs. However, the same issue remains. And the size stuck is about 64kb.

Now i'm really confused and have nothing to work with.because
1 now the addresses,pointers are all 32bit,why still 64kb gap?
2 i have Serial.print() before and after drawBitMap(),and they work properly, so there seems no trouble finding function entrance,despite their being in the lower 64kb or not

Desperately needs help!

sincerely(Is it a custom to append this and my name at the end of a post?)
Nick

Is there an example of using PROGMEM larger than 64kB?

sincerely(Is it a custom to append this and my name at the end of a post?)

No, your name is displayed on the left.

If I may suggest, for a few dollars (around $15) get a SD-card interface board. Then you can store 8 Gb of pictures or whatever on it. Don't store huge amounts of data in PROGMEM.