PROGMEM does not seem to be working.

Hi all,

I’ve got a sketch I wrote that has LOTS of static text in it (menu items and sprintf() format strings).

Suspecting that PROGMEM is not working for me, I tried an experiment: I made a little function just filled with a lot of text:

// yes of course #include <avr/pgmspace.h> is loaded....
void zzz(void)
{
	prog_uchar test_message[] PROGMEM = {
        	"A is for apple, J is for jacks. Cinnamon Toasty Apple Jacks. Dig-Um!\r\n"
                // LOTS more of the same line.......
        	"A is for apple, J is for jacks. Cinnamon Toasty Apple Jacks. Dig-Um!\r\n"
	};
}

This layout is directly from the Arduino “PROGMEM” reference: http://www.arduino.cc/en/Reference/PROGMEM

If I compile this code, the IDE says it’s 19,000 bytes out of 258,048 (a MEGA2560 R3 board).

These formats also result in exactly the same code (and 19,000 byte size):

const char *test_message = “A is for apple…”;
const char test_message = { “A is for apple…” };

If, however, I use the “FLASH_STRING” syntax from the “Flash” library - http://arduiniana.org/libraries/flash

void zzz(void)
{
	FLASH_STRING(test_message,
        	"A is for apple, J is for jacks. Cinnamon Toasty Apple Jacks. Dig-Um!\r\n"
                // LOTS more of the same line.......
        	"A is for apple, J is for jacks. Cinnamon Toasty Apple Jacks. Dig-Um!\r\n"
	);
}

…the code is now 46,094 out of 258,048, which tells me that FLASH_STRING is working but PROGMEM is not.

So, the question is, HOW to make PROGMEM work? I would appreciate a code sample, not a link since of course the info at the link DOESN’T WORK!

Also, if this means anything, when I use PROGMEM (or if I don’t), the code complies to 19,000 bytes and the string gets put at the BOTTOM of the block of binary (I examined the .HEX file). However, if I use FLASH_STRING, the string is placed near the TOP of the binary block.

I’ve GOT to make this work because I have LOTS of strings and it simply won’t fit unless it’s in flash.

Any help will be appreciated. Thanks!

– Roger

I think you need to look at the lower part of the tutorial http://www.arduino.cc/en/Reference/PROGMEM specifically at 'Arrays of strings'. To have arrays like this you need to also have an array of pointers to the strings for it to work. Not sure if it will help in your case but if these are Serial.Print strings then there is an F modifier to place the string in PROGMEM. I'm not sure if it's part of the .print class and may also works for LCD.Print etc.

Serial.print(F("A is for apple, J is for jacks. Cinnamon Toasty Apple Jacks. Dig-Um!\r\n"));

Riva: To have arrays like this you need to also have an array of pointers to the strings for it to work.

Actually I finally found out what's going on. It seems the Arduino example is depreciated (specifically, the "prog_char" and "prog_int", etc.. type of declaration).

I found that THIS works:

    char buffer[64];
    const char *template[] = PSTR("Hi my name is %s and I am %d years old!\r\n");
    sprintf_P(buffer, template, "Roger", 55);
    Serial.print(buffer);
    lcd.print(buffer);
    whatever.print(buffer);

The "template" string is stored in flash with this method.

Actually I finally found out what's going on. It seems the Arduino example is depreciated (specifically, the "prog_char" and "prog_int", etc.. type of declaration).

They still work in Arduino 1.0.1 as I use them (see below excerpts)

// Day Strings
prog_uchar Day01[] PROGMEM = {
    "Sunday \0"};
prog_uchar Day02[] PROGMEM = {
    "Monday \0"};
prog_uchar Day03[] PROGMEM = {
    "Tuesday \0"};
prog_uchar Day04[] PROGMEM = {
    "Wednesday \0"};
prog_uchar Day05[] PROGMEM = {
    "Thursday \0"};
prog_uchar Day06[] PROGMEM = {
    "Friday \0"};
prog_uchar Day07[] PROGMEM = {
    "Saturday \0"};
//Day String Pointer Table
prog_uchar *day_table[] PROGMEM ={
    Day01,
    Day02,
    Day03,
    Day04,
    Day05,
    Day06,
    Day07,
};
    int x = RTC.getDayOfWeek();
    chrBuffer[0] = ' ';
    chrBuffer[1] = ' ';
    strlcpy_P(chrBuffer+2, (char*)pgm_read_word(&(day_table[x-1])), sizeof(chrBuffer));