dougp:
One of my failed attempts did include placing a literal behind the dot *&turretPosnTextP[trtPosition].1 * but that didn't work either. I can only presume it was broken some other way.
It failed because '1' is not a member of struct stationlist.
Because your struct only contains one field, "&turretPosnTextP[trtPosition]" and "&turretPosnTextP[trtPosition].stationtext" are the same address and either should work. Because your struct only has one field, there is no reason to have a struct. You could declare your table as:
const char turretPosnTextP[][17] PROGMEM =
dougp:
To wrap up, the way I read it; FlashStringHelper* is a pointer to the address of &turretPosnTextP[trtPosition].stationtext).
Not quite. It is not a pointer to the address of a table element. It is a pointer CONTAINING the address of a table element. The 'address of' operator (&) creates a pointer. The cast operation "(__FlashStringHelper*)" tells the compiler that the pointer is to be treated as a pointer to a __FlashStringHelper.
johnwasser:
Because your struct only contains one field, "&turretPosnTextP[trtPosition]" and "&turretPosnTextP[trtPosition].stationtext" are the same address and either should work. Because your struct only has one field, there is no reason to have a struct. You could declare your table as:
const char turretPosnTextP[][17] PROGMEM =
That did raise an eyebrow as I copied the skeleton from the Gammon Forum but it solved my immediate problem, getting stuff into progmem, so I didn't question it.
johnwasser:
It is not a pointer to the address of a table element. It is a pointer CONTAINING the address of a table element. The 'address of' operator (&) creates a pointer. The cast operation "(__FlashStringHelper*)" tells the compiler that the pointer is to be treated as a pointer to a __FlashStringHelper.
I've become comfortable with many aspects of programming the Arduino during this project but this progmem business is still baffling.
dougp:
I've become comfortable with many aspects of programming the Arduino during this project but this progmem business is still baffling.
The thing to remember is that RAM and FLASH (PROGMEM) are two separate address spaces and the compiler doesn't keep track of which variables are in which address space. That's left up to you. Any address or pointer you don't explicitly treat as a PROGMEM address (by passing it to a function that expects a PROGMEM address) the compiler will treat as a RAM address. In cases where you are just calculating an address and not fetching data there is no difference between RAM and PROGMEM so you can do things like get the address of an array or structure element. That's why "&laserMsg*.errorText" works whether laserMsg[] is in PROGMEM or RAM (as long as 'i' is in RAM since the value is fetched).* If you treat a pointer the wrong way you will be fetching from the wrong address space and will get the wrong data.