How To "Stringify" Messages in FLASH

I would like to put all of my messages strings into Flash, but it seems you can't create a pointer to a String defined using F(). Is there a way to do this?

Regards,
Ray L.

You might need some time to study that, it is not easy to understand.
Can you give an example of what string or String class you want to put in flash memory ?

Thanks, that's straight-forward enough. I will have a large number of string messages that will eventually go to a serial port (using Serial.print), an LCD (using LCD.print), or an Ethernet telnet connection. I just want to be able to define all the strings in one place, and store them FLASH, to conserve RAM. PROGMEM will do it.

Regards,
Ray L.

RayLivingston:
create a pointer to a String defined using F()

Note that there is a very big difference between String (capital 'S') which refers to the String class, and string (lower case 's') which refers to null terminated char arrays. You should almost certainly be using strings (lowercase).

I've been trying to get PROGMEM to work here, but with little luck so far. I've tried numerous approaches, based on examples I've found, including what's on the Arduino library PROGMEM page, but all give the same result - gibberish is printed out. Different examples seem to have "const" littered throughout the code in different places, but they all behave exactly the same, and seem to print the same gibberish, which suggests all end up pointing to the same place in memory.

Here is where I define the strings, and the array of pointers:

#ifndef STRINGS_H
#define STRINGS_H

#include <avr/pgmspace.h>

/**************************************************
 * Strings - Define all message strings here.
 *
 *	Define Strings as:
 *		prog_char ThisMsg[] PROGMEM = "This is a FLASH string";
 *
 *	Use as: 
 *		Serial.print(PSTR(ThisMsg));
 *************************************************/	
	
const char ATCError0[] PROGMEM			= "No Error";

const prog_char ATCCarouselError0[] PROGMEM	= "Carousel Bad State";
const prog_char ATCCarouselError1[] PROGMEM	= "Carousel Home Fail";
const prog_char ATCCarouselError2[] PROGMEM	= "Carousel Not Homed";
const prog_char ATCCarouselError3[] PROGMEM	= "Carousel Home Sense Fail";
const prog_char ATCCarouselError4[] PROGMEM	= "Carousel Tool Sense Fail";
const prog_char ATCCarouselError5[] PROGMEM	= "Carousel Seek Fail";
const prog_char ATCCarouselError6[] PROGMEM	= "Carousel Deadband Fail";

const prog_char ATCErrorUnknown[] PROGMEM		= "Unknown Error";

const char * const ErrorMessageStrings[] PROGMEM =
{
	ATCError0,			// 00
	ATCErrorUnknown,	// 01
	ATCErrorUnknown,	// 02
	ATCErrorUnknown,	// 03
	ATCErrorUnknown,	// 04
	ATCErrorUnknown,	// 05
	ATCErrorUnknown,	// 06
	ATCErrorUnknown,	// 07
	ATCErrorUnknown,	// 08
	ATCErrorUnknown,	// 09
	ATCErrorUnknown,	// 10
	ATCErrorUnknown,	// 11
	ATCErrorUnknown,	// 12
	ATCErrorUnknown,	// 13
	ATCErrorUnknown,	// 14
	ATCErrorUnknown,	// 15
	ATCErrorUnknown,	// 16
	ATCErrorUnknown,	// 17
	ATCErrorUnknown,	// 18
	ATCErrorUnknown,	// 19
	ATCErrorUnknown,	// 20
	ATCErrorUnknown,	// 21
	ATCErrorUnknown,	// 22
	ATCErrorUnknown,	// 23
	ATCErrorUnknown,	// 24
	ATCErrorUnknown,	// 25
	ATCErrorUnknown,	// 26
	ATCErrorUnknown,	// 27
	ATCErrorUnknown,	// 28
	ATCErrorUnknown,	// 29
	ATCErrorUnknown,	// 30
	ATCErrorUnknown,	// 31
};

#endif

I reference the pointers in loop() as follows:

char buffer[80];

Serial.println(PSTR(ATCError0));	
strcpy_P(buffer, (char*)pgm_read_word(&(ErrorMessageStrings[0])));
Serial.println(buffer);

The first println prints the correct string, so the strings themselves are fine. The second one prints garbage, so it seems the pointer is not getting returner properly.

What am I doing wrong? This is on a Due, using Arduino 1.5.6.

Regards,
Ray L.

The Due is different, but I don't know how.
A message in italics was added here : http://arduino.cc/en/Tutorial/Memory

Peter_n:
The Due is different, but I don't know how.
A message in italics was added here : http://arduino.cc/en/Tutorial/Memory

Oh, that is soooo nice! Don't need all the PROGMEM voodoo at all. Just declare something as const, and it goes into FLASH, and can be directly referenced there.

Thanks!

Regards,
Ray L.