Found a solution, see my comment below!
I am trying to read data which is placed in structures and stored in the flash memory of an Arduino Mega (ATmega 2560) using PROGMEM. The structure objects manufacturer_1
and manufacturer_2
are accessed with pointers
.
Due to size of the sketch; I decided to create a (relative) small example which illustrates the problem. The following code shows how I define the structures and data.
typedef struct
{
char info[20];
} manufacturer_def;
typedef struct
{
unsigned int totalManufacturers;
const manufacturer_def* manufacturer[2];
} data_def;
const manufacturer_def manufacturer_1 PROGMEM =
{
"Manufacturer 1"
};
const manufacturer_def manufacturer_2 PROGMEM =
{
"Manufacturer 2"
};
const data_def data PROGMEM =
{
2,
{
&manufacturer_1,
&manufacturer_2
}
};
void setup()
{
// Serial monitor setup
Serial.begin(115200); // Begin serial monitor
}
void loop()
{
mainMenu();
}
The problem!
I would like to fill an array with strings using a loop. The following code is not working properly:
void mainMenu()
{
unsigned int i = 0;
unsigned int totalMenuItems = pgm_read_word(&data.totalManufacturers);
String menuItems[totalMenuItems];
char str_buf[20];
// Create array with items for menu
for (i = 0; i < totalMenuItems; i++)
{
strcpy_P(str_buf, data.manufacturer[i]->info);
menuItems[i] = str_buf;
Serial.println(menuItems[i]);
}
}
Output (section):
p�
p�
Strangely, when I place the strcpy_P
command outside the loop and specify the iteration variable by hand it works:
void mainMenu()
{
unsigned int i = 0;
unsigned int totalMenuItems = pgm_read_word(&data.totalManufacturers);
String menuItems[totalMenuItems];
char str_buf[20];
strcpy_P(str_buf, data.manufacturer[0]->info);
menuItems[0] = str_buf;
strcpy_P(str_buf, data.manufacturer[1]->info);
menuItems[1] = str_buf;
// Create array with items for menu
for (i = 0; i < totalMenuItems; i++)
{
Serial.println(menuItems[i]);
}
}
Output:
Manufacturer 1
Manufacturer 2
Why is this happening?
typedef struct
s for example, use of char buffers and C-strings). – tambre