Reference.PROGMEM History

Hide minor edits - Show changes to markup

June 02, 2010, at 09:41 AM by Equipo Traduccion -
June 02, 2010, at 09:37 AM by Equipo Traduccion -
Changed lines 3-7 from:

Store data in flash (program) memory instead of SRAM. There's a description of the various types of memory available on an Arduino board.

The PROGMEM keyword is a variable modifier, it should be used only with the datatypes defined in pgmspace.h. It tells the compiler "put this information into flash memory", instead of into SRAM, where it would normally go.

PROGMEM is part of the pgmspace.h library. So you first need to include the library at the top your sketch, like this:

to:

Guarda datos en la memoria flash (la de programa) en vez de en la SRAM. Hay una descripción de los tipos de memoria disponible en una placa Arduino.

La palabra PROGMEM es un modificador de variable. Debería usarse sólo con los tipos de datos definidos en pgmspace.h. Le dice al compilador que ponga la información en la memoria flash en vez de en la SRAM, que es donde normalmente se guarda.

PROGMEM es parte de la librería pgmspace.h, por ello hay que incluir la librería al principio del sketch, de esta forma:

Changed line 11 from:

Syntax

to:

Sintaxis

Changed lines 15-19 from:
  • program memory dataType - any program memory variable type (see below)
  • variableName - the name for your array of data

Note that because PROGMEM is a variable modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts all of the definitions below, which are also synonymous. However experiments have indicated that, in various versions of Arduino (having to do with GCC version), PROGMEM may work in one location and not in another. The "string table" example below has been tested to work with Arduino 13. Earlier versions of the IDE may work better if PROGMEM is included after the variable name.

to:
  • dataType: tipo de datos en la memoria de programa: cualquier tipo de datos de variables
  • variableName - el nombre de la variable matriz.

Hay que tener en cuenta que PROGMEM es un modificador de variable por lo que no hay reglas escritas sobre dónde debería ir, por lo que el compilador acepta cualquiera de las definiciones siguientes, que son sinónimas. Aun así, se han llevado a cabo experimentos que han concluído que en varias versiones de Arduino (relacionado con la versión de GCC), PROGMEM puede funcionar en una posición y no en otra. La tabla siguiente ha sido probada con Arduino 13. En versiones anteriores del IDE es posible que funcione mejor si PROGMEM se incluye después del nombre de la variable

Changed lines 21-23 from:

dataType variableName[] PROGMEM = {}; // use this form dataType PROGMEM variableName[] = {}; // not this one PROGMEM dataType variableName[] = {}; // use this form

to:

dataType variableName[] PROGMEM = {}; // usar esta dataType PROGMEM variableName[] = {}; // no esta PROGMEM dataType variableName[] = {}; // usar esta

Changed lines 26-42 from:

While PROGMEM could be used on a single variable, it is really only worth the fuss if you have a larger block of data that needs to be stored, which is usually easiest in an array, (or another C data structure beyond our present discussion).

Using PROGMEM is also a two-step procedure. After getting the data into Flash memory, it requires special methods (functions), also defined in the pgmspace.h library, to read the data from program memory back into SRAM, so we can do something useful with it.

As mentioned above, it is important to use the datatypes outlined in pgmspace.h. Some cryptic bugs are generated by using ordinary datatypes for program memory calls. Below is a list of variable types to use. Floating point numbers in program memory do not appear to be supported.

 prog_char      - a signed char (1 byte) -127 to 128
 prog_uchar     - an unsigned char (1 byte) 0 to 255
 prog_int16_t   - a signed int (2 bytes) -32,767 to 32,768
 prog_uint16_t  - an unsigned int (2 bytes) 0 to 65,535
 prog_int32_t   - a signed long (4 bytes) -2,147,483,648 to * 2,147,483,647.
 prog_uint32_t  - an unsigned long (4 bytes) 0 to 4,294,967,295

Example

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

to:

PROGMEM puede usarse en una sola variable pero sólo merece la pena su uso en bloques más largos de datos que necesiten ser guardados, generalmente en un array aunque puede ser otro tipo de estructura.

PROGMEM se usa en dos pasos. Después de guardar los datos en la memoria Flash, requiere métodos especiales (funciones), definidas también en la librería pgmspace.h, para leer los datos de la memoria de programa y ponerla en SRAM, para poder usarla.

Es importante usar los tipos de datos definidos en pgmspace.h. Pueden aparecer fallos crípticos si se usan tipos comunes para llamadas a la memoria de código. Ésta es una lista de tipos disponibles. No están soportados los números en coma flotante.

 prog_char      - carácter con signo (1 byte) -127 a 128
 prog_uchar     - carácter sin signo (1 byte) 0 a 255
 prog_int16_t   - entero con signo (2 bytes) -32.767 a 32.768
 prog_uint16_t  - entero sin signo (2 bytes) 0 a 65.535
 prog_int32_t   - entero largo con signo(4 bytes) -2.147.483,648 a * 2.147.483.647.
 prog_uint32_t  - entero largo sin signo (4 bytes) 0 a 4.294.967.295

Ejemplo

En el siguiente código se indica cómo leer y escribir caracteres sin signo (bytes) y enteros (2 bytes) en PROGMEM.

Changed lines 45-46 from:

// save some unsigned ints

to:

// guardar enteros sin signo

Changed line 48 from:

// save some chars

to:

// guardar caracteres

Changed line 52 from:

int k; // counter variable

to:

int k; // variable contador

Changed line 55 from:

// read back a 2-byte int

to:

// leer entero de 2 bytes

Changed line 58 from:

// read back a char

to:

// leer carácter

Changed lines 63-68 from:

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.

to:

Matrices de cadenas de caracteres (arrays de strings)

Muchas veces es conveniente, al trabajar con cantidades grandes de texto como por ejemplo en un proyecto con un LCD, definir matrices de strings. Como los strings son matrices, en realidad son matrices bidimensionales.

Éstas tienden a ser estructuras grandes por lo que ponerlas en memoeria de programa es algo a evitar. Este código ilustra la idea:

Changed lines 72-73 from:
 How to store a table of strings in program memory (flash), 
 and retrieve them.
to:
 Cómo guardar una tabla de strings en la memoria de programa (flash) y cargarla.
Changed lines 74-75 from:
 Information summarized from:
 http://www.nongnu.org/avr-libc/user-manual/pgmspace.html
to:
 Información resumida de:
 http://www.nongnu.org/avr-libc/user-manual/pgmspace.html (inglés)
Changed lines 77-80 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.
to:
 Primero, definir los strings.
Changed line 82 from:

prog_char string_0[] PROGMEM = "String 0"; // "String 0" etc are strings to store - change to suit.

to:

prog_char string_0[] PROGMEM = "String 0"; // "String 0" etc. son strings a guardar.

Changed lines 90-92 from:

// Then set up a table to refer to your strings.

PROGMEM const char *string_table[] = // change "string_table" name to suit

to:

// Definir una tabla para guardar los strings

PROGMEM const char *string_table[] =

Changed lines 101-102 from:

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

to:

char buffer[30]; // debe ser tan grande como el string más grande.

Changed lines 111-114 from:
  /* 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. */
to:
  /* La función strcpy_P copia un string del espacio de programa a un string en RAM ("buffer").
  Hay que asegurarse de que el string en RAM es suficientemente grande para recibir el dato. */
Deleted line 113:
Changed line 116 from:
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy. 
to:
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Casts necesarios e inferencia
Changed lines 122-124 from:

See also

  • Types of memory available on an Arduino board
to:

Ver también

March 08, 2009, at 04:28 AM by Paul Badger -
Changed lines 18-19 from:

Note that because PROGMEM is a variable modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts both of the definitions below, which are also synonymous. However experiments have indicated that, in various versions of Arduino (having to do with GCC version), PROGMEM may work in one location and not in another. The "string table" example below has been tested to work with Arduino 13. Earlier versions of the IDE may work better if PROGMEM is included after the variable name.

to:

Note that because PROGMEM is a variable modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts all of the definitions below, which are also synonymous. However experiments have indicated that, in various versions of Arduino (having to do with GCC version), PROGMEM may work in one location and not in another. The "string table" example below has been tested to work with Arduino 13. Earlier versions of the IDE may work better if PROGMEM is included after the variable name.

Changed line 23 from:

PROGMEM dataType variableName[] = {};

to:

PROGMEM dataType variableName[] = {}; // use this form

February 27, 2009, at 06:40 PM by Paul Badger -
Changed lines 18-19 from:

Note that because PROGMEM is a variable modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts both of the definitions below, which are also synonymous. However experiments have indicated that, although the compiler doesn't complain, PROGMEM only works successfully if included after the variable name.

to:

Note that because PROGMEM is a variable modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts both of the definitions below, which are also synonymous. However experiments have indicated that, in various versions of Arduino (having to do with GCC version), PROGMEM may work in one location and not in another. The "string table" example below has been tested to work with Arduino 13. Earlier versions of the IDE may work better if PROGMEM is included after the variable name.

Added line 23:

PROGMEM dataType variableName[] = {};

Changed line 99 from:

PGM_P string_table[] PROGMEM = // change "string_table" name to suit

to:

PROGMEM const char *string_table[] = // change "string_table" name to suit

January 26, 2009, at 08:09 PM by Paul Badger -
Changed lines 18-19 from:

Note that because PROGMEM is a variable modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts all of the definitions below, which are also synonymous.

to:

Note that because PROGMEM is a variable modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts both of the definitions below, which are also synonymous. However experiments have indicated that, although the compiler doesn't complain, PROGMEM only works successfully if included after the variable name.

Changed lines 21-25 from:

dataType variableName[] PROGMEM = {}; dataType PROGMEM variableName[] = {}; PROGMEM dataType variableName[] = {};@] Common programming styles favor one of the first two however.

to:

dataType variableName[] PROGMEM = {}; // use this form dataType PROGMEM variableName[] = {}; // not this one @]

October 25, 2008, at 10:09 AM by David A. Mellis -
Changed line 98 from:

PGM_P PROGMEM string_table[] = // change "string_table" name to suit

to:

PGM_P string_table[] PROGMEM = // change "string_table" name to suit

April 07, 2008, at 02:27 PM by Paul Badger -
Changed lines 18-19 from:

Note that because PROGMEM is a modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts all of the definitions below, which are also synonymous.

to:

Note that because PROGMEM is a variable modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts all of the definitions below, which are also synonymous.

April 07, 2008, at 02:26 PM by Paul Badger -
Changed line 83 from:
 Setting up the strings is  a two-step process. First define the strings.
to:
 Setting up the strings is a two-step process. First define the strings.
April 07, 2008, at 02:25 PM by Paul Badger -
Changed line 85 from:
 */
to:
  • /
April 07, 2008, at 02:25 PM by Paul Badger -
Changed line 83 from:

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

to:
 Setting up the strings is  a two-step process. First define the strings.
April 07, 2008, at 02:21 PM by Paul Badger -
Changed lines 5-6 from:

The PROGMEM keyword is a variable modifier, it should be used only with the datatypes defined in pgmspace.h, and it tells the compiler "put this information into flash memory", instead of into SRAM, where it would normally go.

to:

The PROGMEM keyword is a variable modifier, it should be used only with the datatypes defined in pgmspace.h. It tells the compiler "put this information into flash memory", instead of into SRAM, where it would normally go.

April 07, 2008, at 02:15 PM by Paul Badger -
Changed lines 81-82 from:
 here is a good template to follow. Setting up the strings is  a two-step process. 
 First define the strings.
to:
 here is a good template to follow. 

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

April 07, 2008, at 02:13 PM by Paul Badger -
Changed lines 16-17 from:
  • varialbeName - the name for your array of data
to:
  • variableName - the name for your array of data
January 11, 2008, at 06:20 PM by David A. Mellis -
Added line 132:
  • Types of memory available on an Arduino board
January 11, 2008, at 06:18 PM by David A. Mellis - moving the descriptive text to a separate tutorial, keeping this as a reference.
Changed lines 3-9 from:

Write data to flash memory.

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory (program space), is where the Arduino sketch is stored. SRAM (static random access memory) is where the sketch creates and manipulates variables when it runs. EEPROM is memory space that programmers can set up to have a program store long-term information.

Flash memory and EEPROM memory are not volatile (the information persists after the power is turned off). RAM is volatile and will be lost when the power is cycled.

The Atemga168 chip, which is now the default Arduino chip, has the following amounts of memory.

to:

Store data in flash (program) memory instead of SRAM. There's a description of the various types of memory available on an Arduino board.

The PROGMEM keyword is a variable modifier, it should be used only with the datatypes defined in pgmspace.h, and it tells the compiler "put this information into flash memory", instead of into SRAM, where it would normally go.

PROGMEM is part of the pgmspace.h library. So you first need to include the library at the top your sketch, like this:

Changed lines 9-11 from:

Flash 14k bytes minus about 1k for the bootloader SRAM 1024 bytes EEPROM 512 bytes

to:
  1. include <avr/pgmspace.h>
Changed lines 11-12 from:

One thing you will notice in the chart above is that there is a lot more Flash (program) memory than SRAM available. When you create variables with the Arduino language such as:

to:

Syntax

Deleted lines 12-23:

char[] = {"I support the Cape Wind project."} @]

You are putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot of memory in a pool of 1024 bytes, but if the sketch requires some large data structures - such as a large amount of text to send to a display, or a large lookup table, for example - using flash memory (program memory) for storage may be the only option.

The PROGMEM keyword is a variable modifier, it should be used only with the datatypes defined in pgmspace.h, and it tells the compiler "put this information into flash memory", instead of into SRAM, where it would normally go.

PROGMEM is part of the pgmspace.h library. So you first need to include the library at the top your sketch, like this:

#include <avr/pgmspace.h>

Syntax

[@

November 06, 2007, at 10:31 PM by Paul Badger -
Changed lines 47-48 from:

As mentioned above, it is important to use the datatypes outlined in pgmspace.h. Some cryptic bugs are generated by using ordinary datatypes for program memory calls. Below is a list of variable types to use. Floating point numbers in program memory do not appear to be supported.

to:

As mentioned above, it is important to use the datatypes outlined in pgmspace.h. Some cryptic bugs are generated by using ordinary datatypes for program memory calls. Below is a list of variable types to use. Floating point numbers in program memory do not appear to be supported.

November 06, 2007, at 10:29 PM by Paul Badger -
November 06, 2007, at 10:28 PM by Paul Badger -
Changed lines 30-31 from:

variableType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...}; @]

to:

dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...}; @]

Deleted lines 55-59:

November 06, 2007, at 10:27 PM by Paul Badger -
Changed line 32 from:
  • program memory variableType - any program memory variable type (see below)
to:
  • program memory dataType - any program memory variable type (see below)
Changed lines 38-40 from:

variableType variableName[] PROGMEM = {}; variableType PROGMEM variableName[] = {}; PROGMEM variableType variableName[] = {};@]

to:

dataType variableName[] PROGMEM = {}; dataType PROGMEM variableName[] = {}; PROGMEM dataType variableName[] = {};@]

October 29, 2007, at 03:51 AM by Paul Badger -
Changed lines 139-140 from:
   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. */

to:
     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. */
October 29, 2007, at 03:49 AM by Paul Badger -
Changed lines 139-140 from:
   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. */
to:
   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. */

October 29, 2007, at 03:49 AM by Paul Badger -
Changed lines 5-6 from:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory (Program space), is where the Arduino sketch is stored. SRAM (static random access memory) is where the sketch creates and manipulates variables when it runs. EEPROM is memory space that programmers can set up to have a program store long-term information.

to:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory (program space), is where the Arduino sketch is stored. SRAM (static random access memory) is where the sketch creates and manipulates variables when it runs. EEPROM is memory space that programmers can set up to have a program store long-term information.

Changed lines 139-140 from:
   The strcpy_P function copies a string from program space to a string in RAM. Make sure your receiving string
   in RAM is large enough to hold whatever you are retrieving from Program space. */
to:
   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. */
October 29, 2007, at 03:45 AM by Paul Badger -
Changed line 119 from:

PGM_P PROGMEM string_table[] = // change "string_table" to suit

to:

PGM_P PROGMEM string_table[] = // change "string_table" name to suit

October 29, 2007, at 03:44 AM by Paul Badger -
Changed line 119 from:

PGM_P PROGMEM string_table[] = // change string_table to anything you wish

to:

PGM_P PROGMEM string_table[] = // change "string_table" to suit

October 29, 2007, at 03:38 AM by Paul Badger -
Changed line 109 from:

prog_char string_0[] PROGMEM = "String 0"; // "String 0" etc are the strings to store - change them to your text.

to:

prog_char string_0[] PROGMEM = "String 0"; // "String 0" etc are strings to store - change to suit.

October 29, 2007, at 03:37 AM by Paul Badger -
Changed lines 109-110 from:

char string_0[] PROGMEM = "String 0"; // "String 0" etc are the strings to store - change them to your text.

to:

prog_char string_0[] PROGMEM = "String 0"; // "String 0" etc are the strings to store - change them to your text.

October 29, 2007, at 03:35 AM by Paul Badger -
Changed lines 5-6 from:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, (Program space) is where the Arduino sketch is stored. SRAM (static random access memory) is where variables are created and manipulated. EEPROM is memory space that programmers can be set up to store long term information, while the program is running.

to:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory (Program space), is where the Arduino sketch is stored. SRAM (static random access memory) is where the sketch creates and manipulates variables when it runs. EEPROM is memory space that programmers can set up to have a program store long-term information.

October 29, 2007, at 03:33 AM by Paul Badger -
Changed lines 5-6 from:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, is where the Arduino sketch is stored. SRAM (static random access memory) is where variables are created and manipulated. EEPROM is memory space that programmers can be set up to store long term information, while the program is running.

to:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, (Program space) is where the Arduino sketch is stored. SRAM (static random access memory) is where variables are created and manipulated. EEPROM is memory space that programmers can be set up to store long term information, while the program is running.

October 29, 2007, at 03:32 AM by Paul Badger -
Changed line 146 from:
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i])));  // Necessary casts and dereferencing just copy the template. 
to:
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy. 
October 29, 2007, at 03:31 AM by Paul Badger -
Changed line 146 from:
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i])));    // Necessary casts and dereferencing going on, follow the template. 
to:
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i])));  // Necessary casts and dereferencing just copy the template. 
October 29, 2007, at 03:30 AM by Paul Badger -
Changed lines 47-48 from:

As mentioned above it is important to use the datatypes outlined in pgmspace.h. Some cryptic bugs are generated by using ordinary datatypes for program memory calls. Below is a list of variable types to use. Floating point numbers in program memory do not appear to be supported.

to:

As mentioned above, it is important to use the datatypes outlined in pgmspace.h. Some cryptic bugs are generated by using ordinary datatypes for program memory calls. Below is a list of variable types to use. Floating point numbers in program memory do not appear to be supported.

Changed lines 111-117 from:

char string_1[] PROGMEM = "String 1"; char string_2[] PROGMEM = "String 2"; char string_3[] PROGMEM = "String 3"; char string_4[] PROGMEM = "String 4"; char string_5[] PROGMEM = "String 5";

to:

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

Changed lines 141-143 from:
   in RAM is large enough to hold whatever you are retrieving from Program space. 
   There is some necessary casts and dereferencing going on, just follow the template.  */
to:
   in RAM is large enough to hold whatever you are retrieving from Program space. */

Changed line 146 from:
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i])));
to:
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i])));    // Necessary casts and dereferencing going on, follow the template. 
October 29, 2007, at 03:25 AM by Paul Badger -
Changed line 139 from:
  /* Using the string table in program memory requires the use of special functions to retreive the data.
to:
  /* Using the string table in program memory requires the use of special functions to retrieve the data.
Changed lines 141-143 from:
   in RAM is large enough to hold whatever you are retreiving from Program space. 
   There is some neccessary casts and dereferencing going on, just follow the template.  */
to:
   in RAM is large enough to hold whatever you are retrieving from Program space. 
   There is some necessary casts and dereferencing going on, just follow the template.  */
October 29, 2007, at 03:14 AM by Paul Badger -
Deleted lines 149-150:

}

Deleted lines 151-152:
October 29, 2007, at 03:13 AM by Paul Badger -
Changed lines 90-91 from:

These tend to be large structures so putting them into program memory is often desirable. The code fragments below illustrate the idea. Although the retrieval method does not use the functions defined in the AVR library, it seems to work fine.

to:

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

Changed lines 94-98 from:

const prog_char* PROGMEM myStrings[]={"This is string 1", "This is string 2", "This is string 3", "This is string 4", "This is string 5","This is string 6"};

void setup(){ Serial.begin(9600);

to:

/*

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

 Information summarized from:
 http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

 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.

 */

  1. include <avr/pgmspace.h>

char string_0[] PROGMEM = "String 0"; // "String 0" etc are the strings to store - change them to your text. char string_1[] PROGMEM = "String 1"; char string_2[] PROGMEM = "String 2"; char string_3[] PROGMEM = "String 3"; char string_4[] PROGMEM = "String 4"; char string_5[] PROGMEM = "String 5";

// Then set up a table to refer to your strings.

PGM_P PROGMEM string_table[] = // change string_table to anything you wish {

  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);
Changed lines 136-140 from:

void loop(){ for (int i = 0; i < 6; i++){

   Serial.println(myStrings[i]);
   delay(500);
   }
to:

void loop() {

  /* Using the string table in program memory requires the use of special functions to retreive the data.
   The strcpy_P function copies a string from program space to a string in RAM. Make sure your receiving string
   in RAM is large enough to hold whatever you are retreiving from Program space. 
   There is some neccessary casts and dereferencing going on, just follow the template.  */

  for (int i = 0; i < 6; i++)
  {
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i])));
    Serial.println( buffer );
    delay( 500 );
  }

}

October 28, 2007, at 03:50 AM by Paul Badger -
Changed line 103 from:
   Serial.print(myStrings[i]);
to:
   Serial.println(myStrings[i]);
October 28, 2007, at 03:48 AM by Paul Badger -
Changed lines 20-21 from:

You are putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot of memory in a pool of 1024 bytes, but if the sketch requires some large data structures - such as a large amount of text you want to send out to a display, or a large lookup table, for example - using Flash (program memory) for storage may be the only option.

to:

You are putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot of memory in a pool of 1024 bytes, but if the sketch requires some large data structures - such as a large amount of text to send to a display, or a large lookup table, for example - using flash memory (program memory) for storage may be the only option.

Changed lines 90-91 from:

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

to:

These tend to be large structures so putting them into program memory is often desirable. The code fragments below illustrate the idea. Although the retrieval method does not use the functions defined in the AVR library, it seems to work fine.

October 28, 2007, at 03:43 AM by Paul Badger -
Added lines 86-109:

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 fragments below illustrate the idea.


const prog_char* PROGMEM myStrings[]={"This is string 1", "This is string 2", "This is string 3",
"This is string 4", "This is string 5","This is string 6"};

void setup(){
Serial.begin(9600);
}

void loop(){
for (int i = 0; i < 6; i++){
   Serial.print(myStrings[i]);
   delay(500);
   }
}

August 30, 2007, at 03:56 PM by Paul Badger -
August 30, 2007, at 03:54 PM by Paul Badger -
Changed lines 5-6 from:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, is where the Arduino sketch is stored. SRAM (static random access memory) is where variables are created and manipulated. EEPROM is memory space that programmers can set up to store long term information, while the program is running.

to:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, is where the Arduino sketch is stored. SRAM (static random access memory) is where variables are created and manipulated. EEPROM is memory space that programmers can be set up to store long term information, while the program is running.

August 23, 2007, at 09:16 PM by Paul Badger -
Changed lines 43-44 from:

While PROGMEM could be used on a single variable, it is really only worth the fuss, if you have a larger block of data that needs to be stored, which is usually easiest in an array, (or another C data structure beyond our present discussion).

to:

While PROGMEM could be used on a single variable, it is really only worth the fuss if you have a larger block of data that needs to be stored, which is usually easiest in an array, (or another C data structure beyond our present discussion).

August 23, 2007, at 09:16 PM by Paul Badger -
Changed lines 40-41 from:

PROGMEM variableType variableName[] = {}; @]

to:

PROGMEM variableType variableName[] = {};@]

August 23, 2007, at 09:15 PM by Paul Badger -
Deleted line 41:
August 23, 2007, at 09:14 PM by Paul Badger -
Changed line 32 from:
  • variableType - any variable type
to:
  • program memory variableType - any program memory variable type (see below)
August 23, 2007, at 09:13 PM by Paul Badger -
Changed lines 22-23 from:

The PROGMEM keyword is a variable modifier, it should be used only with the datatypes defined in pgmspace.h, and it tells the compiler "put this information into flash memory, instead of into SRAM, where it would normally go."

to:

The PROGMEM keyword is a variable modifier, it should be used only with the datatypes defined in pgmspace.h, and it tells the compiler "put this information into flash memory", instead of into SRAM, where it would normally go.

August 23, 2007, at 09:11 PM by Paul Badger -
Changed lines 20-21 from:

You are putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot of memory in a pool of 1024 bytes, but if the sketch requires some large data structures - such as a large amount of text you want to send out to a display, or a large lookup table, for example, using Flash (program memory - hence PROGMEM) for storage may be the only option.

to:

You are putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot of memory in a pool of 1024 bytes, but if the sketch requires some large data structures - such as a large amount of text you want to send out to a display, or a large lookup table, for example - using Flash (program memory) for storage may be the only option.

August 23, 2007, at 09:08 PM by Paul Badger -
Changed lines 91-92 from:
to:
August 23, 2007, at 09:06 PM by Paul Badger -
Changed lines 56-61 from:
 prog_uint32_t  - an unsigned long (4 bytes)

to:
 prog_uint32_t  - an unsigned long (4 bytes) 0 to 4,294,967,295

August 23, 2007, at 09:04 PM by Paul Badger -
Changed lines 51-61 from:
 prog_char      - a signed char -127 to 128
 prog_uchar     - an unsigned char 0 to 255
 prog_int16_t   - a signed int -32,767 to 32,768
 prog_uint16_t  - an unsigned int 0 to 65,535
 prog_int32_t   - a signed long -2,147,483,648 to * 2,147,483,647.
 prog_uint32_t  - an unsigned long 

to:
 prog_char      - a signed char (1 byte) -127 to 128
 prog_uchar     - an unsigned char (1 byte) 0 to 255
 prog_int16_t   - a signed int (2 bytes) -32,767 to 32,768
 prog_uint16_t  - an unsigned int (2 bytes) 0 to 65,535
 prog_int32_t   - a signed long (4 bytes) -2,147,483,648 to * 2,147,483,647.
 prog_uint32_t  - an unsigned long (4 bytes)

August 23, 2007, at 09:03 PM by Paul Badger -
Changed lines 53-55 from:
 prog_int16_t   - a signed int -32767 to 32768
 prog_uint16_t  - an unsigned int 0 to 65535
 prog_int32_t    - a signed long -2,147,483,648 to * 2,147,483,647.
to:
 prog_int16_t   - a signed int -32,767 to 32,768
 prog_uint16_t  - an unsigned int 0 to 65,535
 prog_int32_t   - a signed long -2,147,483,648 to * 2,147,483,647.
August 23, 2007, at 09:02 PM by Paul Badger -
Changed lines 51-61 from:
 * prog_char      - a signed char -127 to 128
 * prog_uchar     - an unsigned char 0 to 255
 * prog_int16_t   - a signed int -32767 to 32768
  • prog_uint16_t - an unsigned int 0 to 65535
  • prog_int32_t - a signed long -2,147,483,648 to * 2,147,483,647.
  • prog_uint32_t - an unsigned long

to:
 prog_char      - a signed char -127 to 128
 prog_uchar     - an unsigned char 0 to 255
 prog_int16_t   - a signed int -32767 to 32768
 prog_uint16_t  - an unsigned int 0 to 65535
 prog_int32_t    - a signed long -2,147,483,648 to * 2,147,483,647.
 prog_uint32_t  - an unsigned long 

August 23, 2007, at 09:01 PM by Paul Badger -
Changed lines 51-53 from:
  • prog_char - a signed char -127 to 128
  • prog_uchar - an unsigned char 0 to 255
  • prog_int16_t - a signed int -32767 to 32768
to:
 * prog_char      - a signed char -127 to 128
 * prog_uchar     - an unsigned char 0 to 255
 * prog_int16_t   - a signed int -32767 to 32768
August 23, 2007, at 08:59 PM by Paul Badger -
Changed lines 51-61 from:
  • prog_char - a signed char -127 to 128
  • prog_uchar - an unsigned char 0 to 255
  • prog_int16_t - a signed int -32767 to 32768
  • prog_uint16_t - an unsigned int 0 to 65535
  • prog_int32_t - a signed long -2,147,483,648 to * 2,147,483,647.
  • prog_uint32_t - an unsigned long

to:
  • prog_char - a signed char -127 to 128
  • prog_uchar - an unsigned char 0 to 255
  • prog_int16_t - a signed int -32767 to 32768
  • prog_uint16_t - an unsigned int 0 to 65535
  • prog_int32_t - a signed long -2,147,483,648 to * 2,147,483,647.
  • prog_uint32_t - an unsigned long

August 23, 2007, at 08:58 PM by Paul Badger -
Changed lines 51-61 from:

prog_char - a signed char -127 to 128 prog_uchar - an unsigned char 0 to 255 prog_int16_t - a signed int -32767 to 32768 prog_uint16_t - an unsigned int 0 to 65535 prog_int32_t - a signed long -2,147,483,648 to 2,147,483,647. prog_uint32_t - an unsigned long

to:
  • prog_char - a signed char -127 to 128
  • prog_uchar - an unsigned char 0 to 255
  • prog_int16_t - a signed int -32767 to 32768
  • prog_uint16_t - an unsigned int 0 to 65535
  • prog_int32_t - a signed long -2,147,483,648 to * 2,147,483,647.
  • prog_uint32_t - an unsigned long

August 23, 2007, at 08:47 PM by Paul Badger -
Changed lines 55-61 from:

prog_int32_t - a signed double prog_uint32_t

to:

prog_int32_t - a signed long -2,147,483,648 to 2,147,483,647. prog_uint32_t - an unsigned long

August 23, 2007, at 08:45 PM by Paul Badger -
Changed lines 49-52 from:

As mentioned above it is important to use the datatypes outlined in pgmspace.h. Some cryptic bugs are generated by using ordinary datatypes for program memory calls.

to:

As mentioned above it is important to use the datatypes outlined in pgmspace.h. Some cryptic bugs are generated by using ordinary datatypes for program memory calls. Below is a list of variable types to use. Floating point numbers in program memory do not appear to be supported.

prog_char - a signed char -127 to 128 prog_uchar - an unsigned char 0 to 255 prog_int16_t - a signed int -32767 to 32768 prog_uint16_t - an unsigned int 0 to 65535 prog_int32_t - a signed double prog_uint32_t

August 23, 2007, at 08:35 PM by Paul Badger -
Changed lines 5-6 from:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, where the Arduino sketch is stored. SRAM (static random access memory) which is where variables are created and manipulated and EEPROM, which is memory space that programmers can set up to store long term information. Flash memory and EEPROM memory is not volatile (the information persists after the power is turned off). RAM is volatile and will be lost when the power is cycled.

to:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, is where the Arduino sketch is stored. SRAM (static random access memory) is where variables are created and manipulated. EEPROM is memory space that programmers can set up to store long term information, while the program is running.

Flash memory and EEPROM memory are not volatile (the information persists after the power is turned off). RAM is volatile and will be lost when the power is cycled.

Changed lines 20-23 from:

You are putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot of memory in a pool of 1024 bytes, but if the sketch requires some large data structures - such as a large amount of text you want to send out to a display for example, using Flash (program memory - hence PROGMEM) for storage may be the only option.

The PROGMEM keyword is a variable modifier, it can be used with any datatype, and it tells the compiler "put this information into flash memory, instead of into SRAM, where it would normally go."

to:

You are putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot of memory in a pool of 1024 bytes, but if the sketch requires some large data structures - such as a large amount of text you want to send out to a display, or a large lookup table, for example, using Flash (program memory - hence PROGMEM) for storage may be the only option.

The PROGMEM keyword is a variable modifier, it should be used only with the datatypes defined in pgmspace.h, and it tells the compiler "put this information into flash memory, instead of into SRAM, where it would normally go."

Added lines 49-52:

As mentioned above it is important to use the datatypes outlined in pgmspace.h. Some cryptic bugs are generated by using ordinary datatypes for program memory calls.

June 22, 2007, at 02:10 PM by Paul Badger -
Changed lines 74-76 from:
to:
June 22, 2007, at 02:08 PM by Paul Badger -
Changed lines 45-46 from:

Using, PROGMEM is also a two-step procedure. After getting the data into Flash memory, it requires special methods (functions), also defined in the pgmspace.h library, to read the data from program memory back into SRAM, so we can do something useful with it.

to:

Using PROGMEM is also a two-step procedure. After getting the data into Flash memory, it requires special methods (functions), also defined in the pgmspace.h library, to read the data from program memory back into SRAM, so we can do something useful with it.

June 12, 2007, at 06:25 AM by Paul Badger -
Changed lines 45-46 from:

Using, PROGMEM is also a two-step procedure. After getting the data into Flash memory, it requires special methods (functions), also defined in the pgmspace.h library, to read the data from program memory, back into SRAM so we can do something useful with it.

to:

Using, PROGMEM is also a two-step procedure. After getting the data into Flash memory, it requires special methods (functions), also defined in the pgmspace.h library, to read the data from program memory back into SRAM, so we can do something useful with it.

June 12, 2007, at 06:24 AM by Paul Badger -
Changed lines 45-46 from:

Using, PROGMEM is also a two-step procedure. After getting the data into Flash memory, it requires special methods (functions), also defined in the pgmspace.h library, to read the data from program memory, back into SRAM so we can do something useful with it.

to:

Using, PROGMEM is also a two-step procedure. After getting the data into Flash memory, it requires special methods (functions), also defined in the pgmspace.h library, to read the data from program memory, back into SRAM so we can do something useful with it.

June 12, 2007, at 06:23 AM by Paul Badger -
Changed lines 58-59 from:

prog_uchar signMessage[] PROGMEM = {"I AM PREDATOR, UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPARTMENT OF DEFENSE TO ..."};

to:

prog_uchar signMessage[] PROGMEM = {"I AM PREDATOR, UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"};

June 12, 2007, at 06:22 AM by Paul Badger -
Changed lines 18-19 from:

You are putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot of memory when one has 1024 bytes to work with, but if you have some large data structures - such as a large amount of text you want to send out to a display for example, using Flash (program memory - hence PROGMEM) for storage may be your only option.

to:

You are putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot of memory in a pool of 1024 bytes, but if the sketch requires some large data structures - such as a large amount of text you want to send out to a display for example, using Flash (program memory - hence PROGMEM) for storage may be the only option.

Changed lines 49-52 from:

The following example illustrates how to read and write unsigned chars (bytes) and ints (2 bytes) to PROGMEM.

to:

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

#include <avr/pgmspace.h>


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

// save some chars
prog_uchar signMessage[] PROGMEM  = {"I AM PREDATOR,  UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPARTMENT OF DEFENSE  TO ..."};

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


See also

June 12, 2007, at 05:50 AM by Paul Badger -
Changed line 14 from:

One thing you will notice in the chart above is that there is a lot more Flash (program) memory than SRAM available. When one creates variables with the Arduino language such as:

to:

One thing you will notice in the chart above is that there is a lot more Flash (program) memory than SRAM available. When you create variables with the Arduino language such as:

Changed lines 18-19 from:

One is putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot when one has 1024 bytes to work with, but if you have some large data structures - such as a large amount of text you want to send out to a display, using Flash (program memory - hence PROGMEM) for storage may be your only option.

to:

You are putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot of memory when one has 1024 bytes to work with, but if you have some large data structures - such as a large amount of text you want to send out to a display for example, using Flash (program memory - hence PROGMEM) for storage may be your only option.

Changed line 22 from:

PROGMEM is part of the pgmspace.h library. So you first need to include the library:

to:

PROGMEM is part of the pgmspace.h library. So you first need to include the library at the top your sketch, like this:

Changed lines 27-29 from:

variableType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...}

to:
variableType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...}; 
Changed lines 33-37 from:

While PROGMEM could be used on a single variable, it is really only worth the fuss, is you have a larger block of data that needs to be stored.

to:

Note that because PROGMEM is a modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts all of the definitions below, which are also synonymous.

variableType variableName[] PROGMEM = {};
variableType PROGMEM variableName[] = {};
PROGMEM variableType variableName[] = {};

Common programming styles favor one of the first two however.

While PROGMEM could be used on a single variable, it is really only worth the fuss, if you have a larger block of data that needs to be stored, which is usually easiest in an array, (or another C data structure beyond our present discussion).

Using, PROGMEM is also a two-step procedure. After getting the data into Flash memory, it requires special methods (functions), also defined in the pgmspace.h library, to read the data from program memory, back into SRAM so we can do something useful with it.

Example

The following example illustrates how to read and write unsigned chars (bytes) and ints (2 bytes) to PROGMEM.

June 12, 2007, at 05:29 AM by Paul Badger -
Changed lines 25-26 from:

@]!!!! Syntax

to:

@]

Syntax

June 12, 2007, at 05:29 AM by Paul Badger -
Changed lines 25-28 from:

@]

Syntax

to:

@]!!!! Syntax

June 12, 2007, at 05:26 AM by Paul Badger -
Changed lines 22-23 from:

PROGMEM is part of the library.

to:

PROGMEM is part of the pgmspace.h library. So you first need to include the library: [@

Changed lines 25-26 from:
to:

@]

Added lines 29-38:

variableType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...}

  • variableType - any variable type
  • varialbeName - the name for your array of data

While PROGMEM could be used on a single variable, it is really only worth the fuss, is you have a larger block of data that needs to be stored.

June 12, 2007, at 05:19 AM by Paul Badger -
Changed lines 18-27 from:

One is putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot when one has 1024 bytes to work with, but if you have some large data structures - such as a large amount of text you want to send out to a display, using Flash (program memory - hence PROGMEM) for storage may be your only option.

to:

One is putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot when one has 1024 bytes to work with, but if you have some large data structures - such as a large amount of text you want to send out to a display, using Flash (program memory - hence PROGMEM) for storage may be your only option.

The PROGMEM keyword is a variable modifier, it can be used with any datatype, and it tells the compiler "put this information into flash memory, instead of into SRAM, where it would normally go."

PROGMEM is part of the library.

  1. include <avr/pgmspace.h>

Syntax

June 12, 2007, at 05:13 AM by Paul Badger -
Changed lines 3-4 from:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, where the Arduino sketch is stored. RAM which is where variables are stored and manipulated and EEPROM, which is memory space that programmers can set up to store long term information. Flash memory and EEPROM memory is not volatile (the infromation persists after the power is turned off). RAM is volatile and will be lost when the power is cycled.

to:

Write data to flash memory.

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, where the Arduino sketch is stored. SRAM (static random access memory) which is where variables are created and manipulated and EEPROM, which is memory space that programmers can set up to store long term information. Flash memory and EEPROM memory is not volatile (the information persists after the power is turned off). RAM is volatile and will be lost when the power is cycled.

Changed line 10 from:

RAM 1024 bytes

to:

SRAM 1024 bytes

Changed lines 12-18 from:

@]

to:

@]

One thing you will notice in the chart above is that there is a lot more Flash (program) memory than SRAM available. When one creates variables with the Arduino language such as:

char[] = {"I support the Cape Wind project."} 

One is putting 32 bytes (1 char = 1 byte) into SRAM. 32 bytes isn't a lot when one has 1024 bytes to work with, but if you have some large data structures - such as a large amount of text you want to send out to a display, using Flash (program memory - hence PROGMEM) for storage may be your only option.

June 12, 2007, at 04:59 AM by Paul Badger -
Changed lines 3-10 from:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, where the Arduino sketch is stored. RAM which is where variables are stored and manipulated and EEPROM, which a space that programmers can set up to store long term information.

to:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, where the Arduino sketch is stored. RAM which is where variables are stored and manipulated and EEPROM, which is memory space that programmers can set up to store long term information. Flash memory and EEPROM memory is not volatile (the infromation persists after the power is turned off). RAM is volatile and will be lost when the power is cycled.

The Atemga168 chip, which is now the default Arduino chip, has the following amounts of memory.

Flash  14k bytes minus about 1k for the bootloader
RAM   1024 bytes
EEPROM 512 bytes

June 12, 2007, at 02:00 AM by Paul Badger -
Changed line 3 from:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, where the Arduino sketch is stored. RAM which is where variables are stored and manipulated and EEPROM, which a space that programmers can set up to store long term information.

to:

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, where the Arduino sketch is stored. RAM which is where variables are stored and manipulated and EEPROM, which a space that programmers can set up to store long term information.

June 12, 2007, at 02:00 AM by Paul Badger -
Added lines 1-3:

PROGMEM

There are three pools of memory in an Atmega168 (Arduino) chip. Flash memory, where the Arduino sketch is stored. RAM which is where variables are stored and manipulated and EEPROM, which a space that programmers can set up to store long term information.

Share