Programando la EEPROM de Arduino

Programar la EEPROM de Arduino es una tarea sencilla. Aun así, les dejaré algunas explicaciones y códigos de ejemplo para que empiecen a experimentar. Las placas Arduino dependiendo del modelo poseen una cierta cantidad de EEPROM. Por ejemplo el Arduino UNO posee 1024 bytes (1Kb) y el Arduino MEGA 2560 posee 4096 bytes (4Kb). Esta memoria tiene una particularidad muy especial y es la de mantener los datos que allí escribimos aun si la energía se interrumpe (cosa que no pasa con la memoria interna SRAM).

¿Cómo se escribe en la EEPROM de Arduino?

Hay dos maneras simples de escribir en la memoria EEPROM de Arduino y veremos ambas. Ambas maneras hacen uso de la librería del proyecto Arduino que viene incorporada con el Arduino IDE. La primera manera es haciendo uso de funciones específicas de la librería para leer y escribir. Para leer nuestra EEPROM usaremos la función EEPROM.read() que es simple y lee solo 1 byte de la memoria. El siguiente Sketch lee el byte en la dirección 10 de la memoría EEPROM de Arduino:

// Agregamos la librería EEPROM
#include <EEPROM.h>

void setup() {
  // Inicializamos el Monitor Serial para mostrar el contenido de la memoria EEPROM
  Serial.begin(9600);
  
  // Leemos un byte de la direccion 10 de la EEPROM
  byte dato = EEPROM.read(10);
  
  // Mostramos el dato leido
  Serial.println(String("El byte leido de la direccion 10 de la EEPROM es: ") + dato);
}

void loop() {
  // Aqui no ponemos nada ya que solo necesitamos mostrar el contenido una vez
}

Y si carga el Sketch en su Arduino y abre el Monitor Serial, deberá ver algo similar a lo siguiente:

Leyendo un dato de la memoria EEPROM de Arduino

y el valor del dato en mi caso es de 255 ya que el Arduino UNO con el que estoy probando es nuevo, y las EEPROM en los Arduino nuevos vienen con todos los datos en 255.

Escribiendo en la EEPROM de Arduino

El siguiente paso es escribir en la memoria EEPROM. El Sketch para escribir es muy simple y similar al anterior y en lugar de la funcion EEPROM.read() usaremos EEPROM.write(). En este caso escribiremos el numero 123. Cargue el siguiente Sketch en su Arduino:

// Agregamos la librería EEPROM
#include <EEPROM.h>

void setup() {
  // Inicializamos el Monitor Serial para mostrar el contenido de la memoria EEPROM
  Serial.begin(9600);
  
  // Escribimos 123 en la direccion 10 de la EEPROM
  EEPROM.write(10, 123);
  
  // Leemos el byte de la direccion 10 de la EEPROM
  byte dato = EEPROM.read(10);
  
  // Mostramos el dato leido
  if (dato == 123) {
    Serial.println("El dato 123 se ha escrito en la direccion 10 correctamente!");
  }
  else {
    Serial.println("Error escribiendo en la EEPROM");
  }
}

void loop() {
  // Aqui no ponemos nada ya que solo necesitamos mostrar el contenido una vez
}

Luego abra el Monitor Serial y verifique que el programa ha escrito en la memoria EEPROM. Deberá ver algo asi:

Escribiendo en la memoria EEPROM de Arduino

Y luego puede cargar el Sketch anterior para leer la dirección 10 de la EEPROM de Arduino y deberá ver algo asi:

Leyendo el dato recien escrito

Un método más simple

Hay una manera mucho más simple de leer la EEPROM de Arduino de a un byte a la vez, y es tratándola como si fuera un vector, arreglo o array mediante el nombre EEPROM[] (los corchetes denotan que es un array o vector de C/C++). El Sketch para leer el dato de la dirección 10 usando el método simplificado se verá así:

// Agregamos la librería EEPROM
#include <EEPROM.h>

void setup() {
  // Inicializamos el Monitor Serial para mostrar el contenido de la memoria EEPROM
  Serial.begin(9600);
  
  // Leemos un byte de la direccion 10 de la EEPROM
  byte dato = EEPROM[10];
  
  // Mostramos el dato leido
  Serial.println(String("El byte leido de la direccion 10 de la EEPROM es: ") + dato);
}

void loop() {
  // Aqui no ponemos nada ya que solo necesitamos mostrar el contenido una vez
}

Si desea escribir en la dirección 10 debe hacer algo asi:

EEPROM[10] = 123;

¿Y si quiero escribir más de 1 byte?

Para escribir más de un byte con los métodos explicados deberá hacerlo de a 1 byte a la vez. Por suerte, la librería EEPROM del proyecto Arduino posee 2 métodos que nos simplifican la tarea enormemente. Son los métodos EEPROM.put() y EEPROM.get()

EEPROM.put() sirve para escribir un dato de un tipo diferente a un byte. La sintaxis para escribir un double sería:

// Inicializamos la variable dato de tipo flotante con el numero 123,45
float dato = 123.45;

// Escribimos el dato en la direccion 10
EEPROM.put(10, dato);

y además puede escribir cualquier tipo de dato, incluyendo uno creado por usted mediante el uso de struct. Para leer el dato simplemente use la función EEPROM.get() de forma similar a como usaba EEPROM.read():

// Inicializo una variable de tipo flotante
float dato;

// Leo la variable de la direccion 10 de la EEPROM
EEPROM.get(10, dato);

Les dejo un último dato interesante. Como les dije, las memoria EEPROM tienen una limitada cantidad de escrituras y luego comienzan a fallar. Por ello, es importante no confiar a largo plazo en ellas al menos para escribir (puede confiar para leer sin limitación particular).

Debido a ello, la librería EEPROM provista por el proyecto Arduino implementó una función alternativa a EEPROM.write() que se llama EEPROM.update() y que yo la recomiendo siempre en lugar de la primera. La diferencia radica en que EEPROM.update() leerá la dirección antes de escribir, y solo escribirá si el dato leído es diferente al que se debe escribir, ahorrando escrituras ocacionalmente. Debido a la operación extra de lectura, esta función puede demora un poco más que la de escritura original (solo si efectivamente termina escribiendo).

Algunos extras

La librería interna EEPROM del proyecto Arduino posee algunas funciones más de las que se encuentran documentadas en la página, algunas de las cuales pueden tener una utilidad para sus proyectos. Les dejo las 2 que a mi parecer tienen sentido tener en cuenta.

EEPROM.ready(), esta funcion (o método ya que le pertenece a una clase) nos avisa si la EEPROM está lista para ser usada. Parece no tener sentido consultar si la EEPROM puede ser usada, pero en operaciones críticas, cuando el uso de la EEPROM se ha vuelto crítico, sería bueno hacer esta simple comprobacion antes de comenzar.

EEPROM.length(), nos da la longitud de la EEPROM en un entero. Puede ser un recurso muy util a la hora de hacer proyectos que funcionen en varios modelos de Arduino y que usen mucha EEPROM, ya que el recurso va desde 512 bytes en algunos modelos hasta 4096 en otros, por lo que saber la capacidad es muy util.

Les dejo un último Sketch que les muestra estas dos funciones:

// Incluimos la libreria EEPROM
#include <EEPROM.h>

void setup() {
  // Inicializamos el Monitor Serial para las pruebas
  Serial.begin(9600);
  
  // EEPROM.ready()
  Serial.println(String("EEPROM lista: ") + EEPROM.ready());
  
  if (EEPROM.ready()) {
    // EEPROM.length()
    Serial.println(String("Capacidad: ") + EEPROM.length() + " bytes");
    
    // EEPROM.end()
    Serial.println(String("Capacidad (end): ") + EEPROM.end());
  }
}

void loop() {
  // No ponemos nada por ahora aqui
}

4 comentarios en “Programando la EEPROM de Arduino”

  1. cordial saludo, me sale este error al compilar el ultimo sketch,
    “struct EEPROM class has no member named ready”
    que podria estar sucediendo, gracias.

    • Esas son funciones “ocultas”. EEPROM.h es una librería interna de Arduino y son funciones que no estan documentadas. ¿Será que no estan presentes en tu versión de Arduino? Luego reviso bien y agrego comentarios.

  2. Muy interesante y bien explicado, espero poder aplicarlo en un proyecto con varias variables de tipo char, que tiene que comprobar si son similares a las variables guardadas en la eeprom.
    Gracias

Deja un comentario