chipKIT® Development Platform

Inspired by Arduino™

Array of Strings in PROGMEM

Created Mon, 02 Jan 2012 01:59:27 +0000 by cobra18t


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?


lloyddean

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.