Can't build a table of FLASH string pointers

Trying to print a string from an array in flash. The array seems to compile without error

const char alarm_msgs[][6] PROGMEM = {
"Sump Pump Failed    ", 
"Shop Floor Wet      ",
"Studio Bath Wet     ",
"Sump is Full        ",
"Sump is High        ",	
"Sump Sensor Error   " } ;

Almost all posts regarding printing from PROGMEM require a table of pointers for each string in the array. I’ve tried a jillion different ways to say “put these pointers in the table” but none worked. Here’s one of my kludges:

const char *const alarm_table[] PROGMEM = (char *){&(alarm_msgs[0][0]), &(alarm_msgs[0][1]), 
&(alarm_msgs[0][2]), &(alarm_msgs[0][3]), &(alarm_msgs[0][4]), &(alarm_msgs[0][5])};

But I’ve also seen a few posts that declare victory without using an intermediate table, eg,

char *addr = (char *)pgm_read_word(&(alarm_msgs[0][2])) ;
lcd.print( (__FlashStringHelper*) addr);   // prints garbage
lcd.print(addr) ;                          // prints blanks or spaces

I am obviously missing the point of “&” and “*” (I do know what a “pointer” is versus a “variable” and the difference between “address of” and “contents of address”). So I don’t know how $alarm_msgs[0][1] doesn’t mean “the address of the first byte of the second string in the array.”

Anyway, I just want to print these fixed length strings on an LCD. There are 26 of these strings (so far) and there has got to be a more elegant way to do this than

const char string[0] PROGMEM = "string 1" ;
const char string[1] PROGMEM = "string 2" ;
const char string[2] PROGMEM = "string 3" ;
const char string[3] PROGMEM = "string 4" ;
...

I know AWOL is just itching to help, here.

To begin with, you have the array dimensions incorrect, if you have the IDE set to show all compiler warnings you should be seeing a warning.

const char alarm_msgs[][21] PROGMEM = {
  "Sump Pump Failed    ",
  "Shop Floor Wet      ",
  "Studio Bath Wet     ",
  "Sump is Full        ",
  "Sump is High        ",
  "Sump Sensor Error   "
};

To print the text, assuming the lcd library supports printing from flash memory (most do because they inherit from the print class, but I have seem some that do their own implementation of print):

    lcd.print((__FlashStringHelper*)alarm_msgs[i]);

The cast to __FlashStringHelper* tells the compiler to use the proper overload of the print function, otherwise alarm_msgs is seen as a char* which references RAM.

1 Like

Works! Holy cats, talk about looking way past the problem that should have hit me in the face. Thanks.