Created Mon, 02 Jan 2012 01:59:27 +0000 by cobra18t
Mon, 02 Jan 2012 01:59:27 +0000
I have an Arduino sketch that puts an array of strings into program memory and then uses that array to print out the appropriate names on an LCD. I am essentially following the example given near the bottom of the Arduino PROGMEM reference page:
#include <avr/pgmspace.h>
prog_char string_0[] PROGMEM = "String 0"; // "String 0" etc are strings to store - change to suit.
prog_char string_1[] PROGMEM = "String 1";
prog_char string_2[] PROGMEM = "String 2";
prog_char string_3[] PROGMEM = "String 3";
prog_char string_4[] PROGMEM = "String 4";
prog_char string_5[] PROGMEM = "String 5";
// Then set up a table to refer to your strings.
PROGMEM const char *string_table[] = // change "string_table" name to suit
{
string_0,
string_1,
string_2,
string_3,
string_4,
string_5 };
char buffer[30]; // make sure this is large enough for the largest string it must hold
void setup()
{
Serial.begin(9600);
}
void loop()
{
/* Using the string table in program memory requires the use of special functions to retrieve the data.
The strcpy_P function copies a string from program space to a string in RAM ("buffer").
Make sure your receiving string in RAM is large enough to hold whatever
you are retrieving from program space. */
for (int i = 0; i < 6; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy.
Serial.println( buffer );
delay( 500 );
}
}
On chipKit, the program hangs on the line:
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i])));
What am I doing wrong? Is there a more appropriate way to implement a string array in program memory?
Mon, 02 Jan 2012 03:43:05 +0000
The "problem" is that on the chipKIT boards pointers are 32-bits, not a "word", or 16-bits, in length as they are on the Arduino's ATMEL processors.
So on the Arduino the following is an array of 16-bit address and on the chipKIT boards they are an array of 32-bit address.
PROGMEM const char* string_table[] = // change "string_table" name to suit
{
string_0
, string_1
, string_2
, string_3
, string_4
, string_5
};
so then this bit of code
(char*)pgm_read_word(&(string_table[i]))
says to read a WORD, 16-bits, when it should be reading an "address", or 32-bits, effectively throwing away the top 16 bit of the 32-bit address that was stored when compiled on the chipKIT board.