Una de las cosas que todos ignoramos muchas veces (confieso que yo la he ignorado hasta ahora), es la memoria EEPROM de nuestro Arduino. Esta memoria no es muy grande, pero tiene la ventaja de que sobrevive a los apagados de nuestro microcontrolador. Es por eso que en este artículo os enseñaré cómo leer y escribir datos persistentes en la EEPROM de Arduino.

Este método es también compatible con otros chips AVR como por ejemplo la familia ATTiny como ATTiny85 y ATTiny45, y también es compatible con otros como el ESP8266.

Lo primero dos apuntes en relación a esta memoria:

  • El tamaño de esta memoria es de 1 kilobyte para atmega328
  • Tiene más o menos 100.000 ciclos de escritura por byte

Por lo que tendremos que tener cuidado de no andar escribiendo cada minuto en ella y dispondremos de sólo 1k. Si escribimos por ejemplo 10 veces al día tendremos memoria para 27 años, lo que es bastante.

Mi recomendación es que cada vez que escribas, leas para verificar. En el caso de que no coincida lo puedes gestionar encendiendo un led o cambiando de dirección de memoria. Un ejemplo sería tener un control de escritura de datos, y en el caso de que cambie moverlo a otra posición en la memoria. Puedes incluso tener un índice al más puro estilo HDD, en el cual guardes la ubicación de memoria donde guardas los datos.

Bueno, terminando con la introducción que seguramente aburrirá a las ovejas :P, voy a continuar explicando las funciones de las que disponemos.

EEPROM Write

La primera función que tendremos en cuenta será la de escritura, por supuesto. Esta función nos permite escribir bytes en la EEPROM y su funcionamiento es muy fácil.

EEPROM.write(addr, val);

Donde indicaremos la dirección donde escribiremos (addr), y el byte a escribir (0 a 255). Se recomienda no utilizar este método salvo que sea muy importante el tiempo de escritura, ya que disponemos de otros métodos como update, que antes verifica si ha cambiado.

Más información al respecto en la web de arduino: https://www.arduino.cc/en/Tutorial/EEPROMWrite

EEPROM Read

Otra función a tener en cuenta es la de recuperación de datos por supuesto. Para ello usaremos la función EEPROM.read, la cual nos permitirá leer bytes de la memoria EEPROM.

int value = EEPROM.read(addr);

Al igual que con la función write, tendremos que indicarle la dirección a leer (addr), y el dato será guardado en la variable value. Esta función no daña la memoria, por lo que la podremos utilizar tantas veces deseemos de forma segura.

Más información al respecto en la web de arduino: https://www.arduino.cc/en/Tutorial/EEPROMRead

EEPROM length

Esta función no tiene mucho misterio y lo que hace es devolvernos la longitud de la memoria EEPROM. Nos puede servir para tener un control sobre el tamaño de lo memoria, lo que nos puede servir para ajustar nuestro programa a distintos tipos de microcontrolador.

 unsigned int size = EEPROM.length();

EEPROM Update

Su funcionamiento es el mismo que el de la función EEPROM.write, con la diferencia de que primero realiza una operación de lectura para confirmar si ha cambiado. En el caso de que los valores coincidan, esta función no realizará la escritura sobre el bloque, así que ahorraremos en operaciones de escritura.

EEPROM.update(addr, val);

Más información al respecto en la web de arduino:
https://www.arduino.cc/en/Tutorial/EEPROMUpdate

EEPROM Put

Y ya comenzamos con las funciones interesantes. Esta función nos permite guardar cualquier tipo de variable en la memoria EEPROM, por lo que no nos tendremos que preocupar de partirlas en bytes. Además podremos guardar también variables personalizadas tipo struct.

La principal ventaja (o desventaja según se mire), es que esta función usa EEPROM.update para guardar los datos, así que ayuda a preservar la EEPROM si no hay cambios.

EEPROM.put(addr, val);

Su uso es como el de Write o Update, por lo que tendremos que indicarle la dirección donde escribiremos y que valor guardar.

Más información al respecto en la web de arduino:
https://www.arduino.cc/en/Tutorial/EEPROMPut

EEPROM get

Esta función es la complementaria a EEPROM.put, por lo que nos permitrá recuperar los datos guardados sin importar el tipo.
La función utiliza el tipo de la variable que le indiques, por lo que primero habrá que crear una variable para guardar los datos.

float val = 0.00f;
EEPROM.get( eeAddress, f );

Esta función es segura al igual que EEPROM.read, ya que las operaciones de lectura no desgastan la memoria de nuestro microcontrolador.

Más información al respecto en la web de arduino:
https://www.arduino.cc/en/Tutorial/EEPROMGet

Ejemplo de uso

No podía terminar sin poner une ejemplo de cómo usarlo, ya que no se vosotros, pero yo muchas veces entiendo mejor las cosas con uno.

#include <EEPROM.h> // Incluimos la librería para poder usarla

// Creamos un tipo de objeto personalizado
struct customObj{
  float field1;
  byte field2;
  char name[10];
};

void setup(){
  float f = 0.00f;   // Variable to store data read from EEPROM.
  int eeAddress = 0; // Dirección EEPROM donde leer/Escribir

  Serial.begin(9600);

  // Datos a guardar.
  customObj customVarW = {
    3.14f,
    65,
    "Working!"
  };

  // Escribiendo datos
  EEPROM.put(eeAddress, customVarW);
  Serial.print("¡Datos escritos!");

  // Recuperamos los datos
  customObj customVarR;
  EEPROM.get(eeAddress, customVarR);

  // Mostramos los datos leídos, los cuales deben coincidir
  Serial.println("Leído objeto personalizado desde la EEPROM: ");
  Serial.println(customVarR.field1);
  Serial.println(customVarR.field2);
  Serial.println(customVarR.name);
}

void loop(){ /* Empty loop */ }

Lo que nos da como resultado:

Resultado de ejecutar la función de arriba, en el cual se observa cómo guarda y recupera los datos.

Si procedemos a eliminar el código que escribe los datos en la EEPROM para verificar su funcionamiento, podremos observar cómo los datos siguen estando ahí.

Resultado de ejecutar la función de arriba quitando las líneas de escritura, en el cual se observa cómo los datos se mantienen tras el reinicio.

Espero que os haya servido esta guía de cómo leer y escribir datos en la EEPROM de Arduino.

Como siempre, espero que os haya servido y ¡un saludo!

Daniel Carrasco

DevOps con varios años de experiencia, y arquitecto cloud con experiencia en Google Cloud Platform y Amazon Web Services. En sus ratos libres experimenta con Arduino y electrónica.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.