Go Down

Topic: Writing data to flash memory; a practical solution? (Read 1 time) previous topic - next topic


I'm confused about the PROGMEM library and how to use it.

site search on the word progmem, top link:

Don't just look, work with the last example to make it do something else till you are clear.



The following code fragments illustrate how to read and write unsigned chars (bytes) and ints (2 bytes) to PROGMEM.

Code: [Select]

#include <avr/pgmspace.h>

// save some unsigned ints
PROGMEM  prog_uint16_t charSet[]  = { 65000, 32796, 16843, 10, 11234};

// save some chars

unsigned int displayInt;
int k;    // counter variable
char myChar; 

// read back a 2-byte int
displayInt = pgm_read_word_near(charSet + k)

// read back a char
myChar =  pgm_read_byte_near(signMessage + k);

Arrays of strings

It is often convenient when working with large amounts of text, such as a project with an LCD display, to setup an array of strings. Because strings themselves are arrays, this is in actually an example of a two-dimensional array.

These tend to be large structures so putting them into program memory is often desirable. The code below illustrates the idea.

Code: [Select]

PROGMEM string demo
How to store a table of strings in program memory (flash),
and retrieve them.

Information summarized from:

Setting up a table (array) of strings in program memory is slightly complicated, but
here is a good template to follow.

Setting up the strings is a two-step process. First define the strings.


#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_5 };

char buffer[30];    // make sure this is large enough for the largest string it must hold

void setup()  

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 );

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.


Originally, I had the following definition:

Which is a 2D array of pointers to longs, NOT a 2D array of longs.

Why are you creating a 2D array of pointers?


And everything seemed to work fine for small arrays - e.g. with i = 2 and j = 2 or etc. Of course, in the actual application, I want i = 4 and j = 720, which is too big for the SRAM, of course.

Depends on the board of course.
A '1284P with 16K SRAM would not be a problem. Here's one that's Duemilanove/Uno- like, 32 IO, shield compatible. Offboard FTDI, or will take an onboard MIKROE483 FTDI module from Mouser ($11)
$5 for a bare board, build it up as you like
http://www.crossroadsfencing.com/BobuinoRev17/  PL listed here
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.


Why are you creating a 2D array of pointers?

Out of ignorance? Like I said I'm in the beginning stages of planning this code and initially I was needing to swap columns. It was suggested that I work with pointers instead so I could just change pointers and not have to actually move the data entries.


I found a number of program examples showing how to store character strings and vectors of integers in AVR program memory but no good example of how to put a const struct into program memory. After playing around I came up with a design pattern for this. It uses a number C++ tricks to hide the details. Typically the struct data type need to be defined with a program memory reference version. There is also a need for member data access functions and a copy function to move the whole data structure from program memory to data memory.

Please see https://github.com/mikaelpatel/Sketchbook/tree/master/ProgramMemory for more details.

I hope this can be of some aid.

Cheers, Mikael

Go Up