Print string defined in PROGMEM

Hi. I have the following code:

typedef struct TEST
{
  char          Item[30];
  unsigned char Type;  
  long*         Value;
};

long Value1 = 7;
long Value2 = 1;
long Value3 = 4;

const PROGMEM TEST Test[] =
{  
  {"Value 1", 5,   &Value1},
  {"Value 2", 6,   &Value2},
  {"Value 3", 5,   &Value3},
  {"",        4,   NULL}, // Termination
};

void setup() 
{
  Serial.begin(9600);
  delay(1000);
}

void loop() 
{
  Serial.println(Test[0].Item);
  Serial.println((*Test[0].Value), DEC);
}

When I run the code the following is printed:

áááá
7

The number 7 is expected, but the string just shows garbage. If I remove the PROGMEM declaration the following is printed as expected:

Value 1
7

Is there a way to solve this? I would like to keep the structs in PROGMEM, since I will be creating many of them, and they contain char arrays, so they would consume a lot of SRAM.

The problem is that you’ve got a char array, but the char array is in flash. When you try to print it, the Serial.println() function has no idea that it’s in progmem not ram. So it looks at that part of ram and prints the contents of that.

Take a look at how they do the __FlashStringHelper for the F() macro (which puts a string literal in flash - and then tells it to be treated as a __FlashStringHelper - and when Serial.print() is called with a __FlashStringHelper as the argument, it knows to read from flash, not ram.

You might be able to do:

Serial.println(reinterpret_cast<const __FlashStringHelper *>Test[0].Item);

or something similar to that - the idea being to get the pointer into a __FlashStringHelper * so that Serial will know to get it from flash.