Indexing arrays of structures

My sketch:

#include <Arduino.h>
typedef struct CONTROL_T
{
__ char controlName;__
** uint8_t msgParam1;
*
** uint8_t msgParam2;**
** uint8_t msgParam3;**
}control_t;
const PROGMEM control_t controls[8] =
{
** { "Bob", 0,0,0 }, // 0**
** { "Tom", 0,0,0 }, // 1**
** { "Dick", 0,0,0 }, // 2**
** { "Harry",0,0,0 }, // 3**
** { "Steve",0,0,0 }, // 4**
** { "Phil", 0,0,0 }, // 5**
** { "Dom", 0,0,0 }, // 6**
** { "Mark", 0,0,0 } // 7**
};
void setup()
{
** int cnt;**
** Serial.begin( 57600 );**

** Serial.print( 0 );**
** Serial.print( ": " );**
** Serial.println( controls[0].controlName );**
** Serial.print( 1 );**
** Serial.print( ": " );**
** Serial.println( controls[1].controlName );**
** Serial.print( 2 );**
** Serial.print( ": " );**
** Serial.println( controls[2].controlName );**
** for( cnt=0 ; cnt<3 ; cnt++ )**
** {**
** Serial.print( cnt );**
** Serial.print( ": " );**
** Serial.println( controls[cnt].controlName );**
** }**
}
void loop()
{
}

The output is:

13:00:43.995 -> 0: Bob
13:00:43.995 -> 1: Tom
13:00:43.995 -> 2: Dick
13:00:43.995 -> 0:
13:00:43.995 -> 1:
13:00:43.995 -> 2:

Why does indexing the array of structures work with literal values but not the integer variable cnt ???

TIA

Hint : PROGMEM.

Thanks for the quick reply, but why does the fact that the array is in PROGMEM affect how the members can be accessed ? (Genuine question !)

Yes, it absolutely does.
PROGMEM occupies a separate address space, and requires special instructions to access it.

OK, many thanks !

When you code:

Serial.println( controls[0].controlName );

The element that you want is known at compile-time. Apparently, the compiler is smart enough to generate the special code required to pull it from PROGMEM for you.

When you code:

Serial.println( controls[cnt].controlName );

The element that you want is not known at compile-time. So, you need to be smart enough to write the special code required to pull it from PROGMEM.

Also, please read the very cleverly titled post: Read this before posting a programming question .... Pay particular attention to Item #6 which will show you how to properly post your code. If you want meaningful help from the Forum, you need to follow the procedures.

Something else to note, the actual strings are not being stored in PROGMEM, only the pointers.. If you change the type definition to the following, you can see that the amount of dynamic memory used will decrease.

typedef struct CONTROL_T
{
  char controlName[6];
  uint8_t msgParam1;
  uint8_t msgParam2;
  uint8_t msgParam3;
} control_t;

Alternately, you can define the strings separately so that they can be explicitly stored in PROGMEM, then reference them in the array, although this makes accessing the string a bit more complicated.

typedef struct CONTROL_T
{
  const char *controlName;
  uint8_t msgParam1;
  uint8_t msgParam2;
  uint8_t msgParam3;
} control_t;

const char _Bob[] PROGMEM = "Bob";
const char _Tom[] PROGMEM = "Tom";
const char _Dick[] PROGMEM = "Dick";
const char _Harry[] PROGMEM = "Harry";
const char _Steve[] PROGMEM = "Steve";
const char _Phil[] PROGMEM = "Phil";
const char _Dom[] PROGMEM = "Dom";
const char _Mark[] PROGMEM = "Mark";

const PROGMEM control_t controls[8] =
{
  { _Bob,  0, 0, 0 }, // 0
  { _Tom,  0, 0, 0 }, // 1
  { _Dick, 0, 0, 0 }, // 2
  { _Harry, 0, 0, 0 }, // 3
  { _Steve, 0, 0, 0 }, // 4
  { _Phil, 0, 0, 0 }, // 5
  { _Dom,  0, 0, 0 }, // 6
  { _Mark, 0, 0, 0 } // 7
};