PROGMEM and Serial.Print

Hi

Lots of places online tell me, that if I want to print something from a constant in PROGMEM, then I have to do funky stuff with ‘pgm_read_word_near’ type functions to make it work [1].

But this seems to work:

  const char oGH[] PROGMEM = "onG_H() Send ";
  Serial1.println(oGH);

However, extending this, this example doesn’t seem to work for me:

const char string_0[] PROGMEM = "String 0"; 
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";

const char* const string_table[]  = { string_0, string_1, string_2, string_3, string_4, string_5 };

void setup() {
  Serial1.begin(9600);
}

void loop() {
  for (int i = 0; i < 6; i++)
  {
    Serial1.println( string_table[i] );
    delay( 800 );
  }
}

I am not sure what I am missing, and why one works but not the other?

Thanks very much
Kevin

[1]http://playground.arduino.cc/Main/PROGMEM

You could also put the pointers to PROGMEM

const char string_0[] PROGMEM = "String 0";
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";

const char* const string_table[] PROGMEM = { string_0, string_1, string_2, string_3, string_4, string_5 };

void setup() {
  Serial.begin(9600);
  for (int i = 0; i < 6; i++) {
    Serial.println( (__FlashStringHelper*)pgm_read_word(string_table + i));
  }
}
void loop() {}

What Arduino are you using? If the string addresses are ending up 'far', then you won't be able to initialize an array with them at build time. You'll have to do it at runtime using pgm_get_far_address().

jaholmes:
What Arduino are you using? If the string addresses are ending up 'far', then you won't be able to initialize an array with them at build time. You'll have to do it at runtime using pgm_get_far_address().

Using 1.8.1

Sorry the rest of your sentence doesn't mean a lot to me.

Thanks
Kevin

Whandall:
You could also put the pointers to PROGMEM

const char string_0[] PROGMEM = "String 0";

const char string_1 PROGMEM = “String 1”;
const char string_2 PROGMEM = “String 2”;
const char string_3 PROGMEM = “String 3”;
const char string_4 PROGMEM = “String 4”;
const char string_5 PROGMEM = “String 5”;

const char* const string_table PROGMEM = { string_0, string_1, string_2, string_3, string_4, string_5 };

void setup() {
 Serial.begin(9600);
 for (int i = 0; i < 6; i++) {
   Serial.println( (__FlashStringHelper*)pgm_read_word(string_table + i));
 }
}
void loop() {}

Yes, Sorry, I had been putting the pointers in Progmem, but I forgot to put it back in when I was proving the code worked when not in PROGMEM.

Thanks very much for the FlashStringHelper syntax, that seems to be working well.

For my future knowledge though, did something change in a recent Arduino version and various pages have not been updated yet?

Thanks
Kevin

What Arduinio is 1.8.1 ? :wink: I guess it's the IDE version number.
On Arduinos with more than 64k (like the Mega) it could be necessary to use a different approach.
What type of Arduino do you use?

The __FlashStringHelper type is used by/for the print functions to distinguish between RAM and PROGMEM.

Whandall:
What Arduinio is 1.8.1 ? :wink: I guess it's the IDE version number.
On Arduinos with more than 64k (like the Mega) it could be necessary to use a different approach.
What type of Arduino do you use?

The __FlashStringHelper type is used by/for the print functions to distinguish between RAM and PROGMEM.

Ahh, soz, Leonardo Eth - not more than 64k as I am finding out!

Cheers
Kev