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:
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í.
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!