PROGMEM VooDoo Needed

I have a large number of debug strings I would like to put into an array of structs, but the correct syntax is eluding me....

Here's what I'd like to do, but but with the strings, or better yet, the entire array of structs, in PROGMEM:

typedef struct DebugThingy {
    int SomeVal;
    char *SomeStr;
} t_DebugThingy;

char *s1 = "1234";
char *s2 = "5678";
...

t_DebugThingy DbgTbl[] = {
    { 22, s1 },
    { 33, s2 },
    ...
};

Serial.println(DbgTbl[i].SomeStr);

Given some time, I'm sure I could figure this out, but I'm hoping someone can save me some time...

Regards,
Ray L.

Putting the strings in PROGMEM is probably enough. Putting the array of structs into PROGMEM is probably not necessary.

The struct definition should declare that the pointers are in PROGMEM.

PaulS:
Putting the strings in PROGMEM is probably enough. Putting the array of structs into PROGMEM is probably not necessary.

The struct definition should declare that the pointers are in PROGMEM.

Yes, but how? Here is my latest of several attempts, all of which printed garbage:

typedef enum PDBStates {
    STATE_IDLE,
    ...
} t_PDBStates;

typedef struct t_StateTrace {
	t_PDBStates	State;              // current state enum
	PROGMEM const char *Str;        // current state message
};

prog_char StateStr0[] PROGMEM = "IDLE";

t_StateTrace StateStrTbl[] =
{
	{ STATE_IDLE,			StateStr0 }
};

char buffer[16];
strcpy_P(buffer, (char*)pgm_read_word(&(StateStrTbl[0].Str)));
Serial.println( buffer );

Regards,
Ray L.

strcpy_P(buffer, (char*)pgm_read_word(&(StateStrTbl[0].Str)));

First off, I HATE the idea of calling a string a Str. Second, is pgm_read_word() the correct function to read a string pointer? It looks like you are putting the string and the pointer in PROGMEM. I don't think that that is the proper thing to do.

Mind you, I've never actually written any code that uses PROGMEM, so take my comments with a grain (or bushel) of salt.

RayLivingston:
Here is my latest of several attempts, all of which printed garbage:

Here is my attempt:

// put strings in PROGMEM
const char s1[] PROGMEM = "1234";
const char s2[] PROGMEM = "5678";
const char s3[] PROGMEM = "The quick brown fox jumps over the lazy dog";
const char s4[] PROGMEM = "Lorem ipsum dolor sit amet";

// define struct
typedef struct t_debug {
    const int SomeVal;
    const char* SomeStr;
};

// put array of structs in PROGMEM
const t_debug DbgTbl[] PROGMEM= {
  { 22, s1},
  { 32, s2},
  { 33, s3},
  { 42, s4},
  
};
#define NUMTHINGIES (sizeof(DbgTbl)/sizeof(DbgTbl[0]))

void printOneThingy(int num)
{ // print directly from PROGMEM, without copying the string into a buffer
  int val=pgm_read_word(&(DbgTbl[num].SomeVal));
  Serial.print(val);
  Serial.print('\t');
  const char* tmp= (const char*)pgm_read_word(&(DbgTbl[num].SomeStr));
  while(1)
  {
    char c= pgm_read_byte(tmp);
    if (c=='\0') break;
    Serial.print(c);
    tmp++;
  }
}

void setup() {
  Serial.begin(9600);
  for (int i=0;i<NUMTHINGIES;i++)
  {
    printOneThingy(i);
    Serial.println();
  }
}

void loop() {
}

PaulS, the PROGMEM is a single segment of maximum 64kbyte. A pointer to it is always 16-bit. No more, no less.
[EDIT] wrong, sorry.

jurs:
Here is my attempt:

// put strings in PROGMEM

const char s1 PROGMEM = “1234”;
const char s2 PROGMEM = “5678”;
const char s3 PROGMEM = “The quick brown fox jumps over the lazy dog”;
const char s4 PROGMEM = “Lorem ipsum dolor sit amet”;

// define struct
typedef struct t_debug {
   const int SomeVal;
   const char* SomeStr;
};

// put array of structs in PROGMEM
const t_debug DbgTbl PROGMEM= {
 { 22, s1},
 { 32, s2},
 { 33, s3},
 { 42, s4},
 
};
#define NUMTHINGIES (sizeof(DbgTbl)/sizeof(DbgTbl[0]))

void printOneThingy(int num)
{ // print directly from PROGMEM, without copying the string into a buffer
 int val=pgm_read_word(&(DbgTbl[num].SomeVal));
 Serial.print(val);
 Serial.print(’\t’);
 const char* tmp= (const char*)pgm_read_word(&(DbgTbl[num].SomeStr));
 while(1)
 {
   char c= pgm_read_byte(tmp);
   if (c==’\0’) break;
   Serial.print(c);
   tmp++;
 }
}

void setup() {
 Serial.begin(9600);
 for (int i=0;i<NUMTHINGIES;i++)
 {
   printOneThingy(i);
   Serial.println();
 }
}

void loop() {
}

That does appear to work! Thanks! Some days, I just don’t want to have to learn anything new…

Regards,
Ray L.

http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html

http://www.nongnu.org/avr-libc/user-manual/pgmspace.html