PROGMEM: How Do I Hate Thee? Let Me Count The Ways...

Every time I have to mess with PROGMEM, I end up wanting to smash my computer...

I'm trying to put an array of structures containing strings entirely into FLASH. Here's how I've tried to do it:

struct OilerCircuit
{
	const char PROGMEM *Name;
	uint8_t	Time;
};

const char RaysCircuit1Name[]  PROGMEM = "  X Front Top Way   ";
const char RaysCircuit2Name[]  PROGMEM = "  X Front Dovetail  ";
const char RaysCircuit3Name[]  PROGMEM = "    X Rear Ways     ";

const OilerDriver::OilerCircuit PROGMEM RaysSchedule[3] =
{
	{ RaysCircuit1Name, 10 },
	{ RaysCircuit2Name, 11 },
	{ RaysCircuit3Name, 12 },
};

/***********************************
 *  getCircuitName
 **********************************/
const char *RaysDriver::getCircuitName(uint8_t which)
{
	// Read Circuit name from FLASH
	return RaysSchedule[which].Name;
}

For reasons I cannot fathom, getCircuitName() always returns NULL. I can read the Time fields with no problems. I can read the strings themselves with no problems. But when I read the Name fields from the array, I always get NULL.

What am I doing wrong?

Regards,
Ray L.

You can't directly access data from program memory like that, you need to use specific routines or macros. I haven't tried using them with structures, so can't advise. Check the avrlibc documentation for full descriptions of all the macros. avr-libc: pgmspace.h File Reference

I'm not trying to directly access the string. I'm trying to get the address of the string, so I can use the PROGMEM functions to fetch the string.

Regards,
Ray L.

There are functions for getting the address from progmem, too.

jremington:
There are functions for getting the address from progmem, too.

Can you give a hint? Because I have been completely unable to make this work...

Regards,
Ray L.

OK, I found it. The solution is:

/***********************************
 *  getCircuitName
 **********************************/
const char *RaysDriver::getCircuitName(uint8_t which)
{
	// Read Circuit name from FLASH
	return (const char *)pgm_read_word(&RaysSchedule[which].Name);
}

Regards,
Ray L.