Reference   Language (extended) | Libraries | Comparison | Changes

PROGMEM

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:

#include <avr/pgmspace.h>

Sintaxis

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

  • 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

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

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.

#include <avr/pgmspace.h>

// guardar enteros sin signo
PROGMEM  prog_uint16_t charSet[]  = { 65000, 32796, 16843, 10, 11234};

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

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

// leer entero de 2 bytes
 displayInt = pgm_read_word_near(charSet + k)

// leer carácter
myChar =  pgm_read_byte_near(signMessage + k); 


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:


/*
 PROGMEM string demo
 Cómo guardar una tabla de strings en la memoria de programa (flash) y cargarla.

 Información resumida de:
 http://www.nongnu.org/avr-libc/user-manual/pgmspace.html (inglés)

 Primero, definir los strings.

*/

#include <avr/pgmspace.h>
prog_char string_0[] PROGMEM = "String 0";   // "String 0" etc. son strings a guardar.
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";


// Definir una tabla para guardar los strings

PROGMEM const char *string_table[] = 	 
{   
  string_0,
  string_1,
  string_2,
  string_3,
  string_4,
  string_5 };

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

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


void loop()			  
{
  /* 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. */

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

Ver también

Página principal Referencia

Correcciones, sugerencias, y nueva documentación deberán ser publicadas en el Foro (castellano) o en el Foro (inglés).

El texto de la referencia de Arduino está publicado bajo la licencia Creative Commons Reconocimiento-Compartir bajo la misma licencia 3.0. Los ejemplos de código de la referencia están liberados al dominio público.

Share