Los que han utilizado Arduino se habrán dado cuenta que cuando se reinicia el micro controlador utilizando el botón «reset» o bien, encendiendo y apagando el Arduino, el programa que esté colocado la memoria se reiniciará y no será posible utilizar cualquier dato que se haya tenido antes del reinicio. Si se tiene por ejemplo los datos de un sensor, todo lo que se haya leído se perderá en el reinicio.
Se dice que la memoria de Arduino, donde se almacena el código es una memoria volátil, cuyo contenido se borra cuando se interrumpe el flujo eléctrico. Sin embargo, Arduino al igual que muchos otros micro controladores posee una memoria no volátil, con un espacio de almacenamiento más reducido que la memoria volátil, pero aún así muy útil para nuestros propósitos.
Me estoy refiriendo a la memoria EEPROM (Electrically Erasable Programmable Read-Only Memory, o ROM programable y borrada eléctricamente).
Casi todos los modelos de Arduino tienen una EEPROM disponible, con diferentes capacidades dependiendo del modelo.
La información que se guarde en la memoria EEPROM podrá ser recuperada aún después de reiniciarse el micro controlador. Para lograr esto Arduino incluye la librería EEPROM que viene junto con Arduino IDE en el paquete que se descarga directamente desde la página oficial de Arduino. Consta básicamente de dos métodos:
- read()
- write()
Con el método read() se lee los valores que se hayan guardado en determinada posición de memoria, mientras que con el método write() se guarda la información en las posiciones de memoria. Las posiciones de memoria son el equivalentes a «casillas» donde se guarda la información. La cantidad de «casillas» disponibles depende del modelo. La cantidad de bytes equivale a la cantidad de casillas, por lo que un modelo de 512 bytes tendrá disponibles 512 «casillas» disponibles para guardar datos. Para escribir datos se utiliza: write(posición, valor) Ejemplo:
1 2 3 4 5 6 7 8 9 10 11 |
#include <EEPROM.h> //Se implementa la librería EEPROM void setup() { for (int i = 0; i < 512; i++) EEPROM.write(i, i); } void loop() { } |
Para leer los datos se utiliza: read(posición) Ejemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include <EEPROM.h> // empieza en el primer byte (dirección 0) de la EEPROM int direccion = 0; byte valor; void setup() { Serial.begin(9600); } void loop() { while (dirección>=0){ // Lee un byte de cada direccion de la EEPROM valor = EEPROM.read(direccion); Serial.print(direccion); Serial.print("t"); Serial.print(valor, DEC); Serial.println(); // incrementa "direccion" en 1 para avanzar a la siguiente dirección de la EEPROM direccion = direccion++; // Solamente hay 512 bytes de EEPROM, desde 0 hasta 511 // Si estamos en la direccion 512, volvemos a la dirección 0 if (direccion == 512){ direccion = -1; } delay(500); } } |
Aplicaciones prácticas de la memoria EEPROM
En esta sección, exploraremos diversas aplicaciones prácticas de la memoria EEPROM, desde la configuración de dispositivos y la seguridad mediante contraseñas hasta la calibración de sensores y el registro de eventos esenciales. Veamos:
- Configuración de Dispositivos: La memoria EEPROM es ideal para almacenar configuraciones personalizadas de dispositivos. Por ejemplo, en un termostato inteligente, puedes utilizar la memoria EEPROM para almacenar la temperatura deseada por el usuario, las horas de encendido y apagado programadas, y otras preferencias.
- Contraseñas y Seguridad: Para proyectos que requieran acceso seguro, puedes almacenar contraseñas o claves de cifrado en la memoria EEPROM. Esto puede ser útil en sistemas de seguridad o control de acceso.
- Datos de Calibración: En sensores y dispositivos de medición, es común necesitar datos de calibración para garantizar mediciones precisas. La memoria EEPROM puede almacenar estos valores calibrados para su uso posterior.
- Registros de Eventos: Para proyectos de registro de datos o eventos, como un registrador de datos de temperatura, puedes utilizar la memoria EEPROM para almacenar registros históricos de eventos, como fechas y tiempos de mediciones.
- Historial de Configuración: En proyectos con interfaces de usuario, como pantallas LCD, puedes guardar el historial de configuración, como las últimas configuraciones realizadas por el usuario, para que sean restauradas después de un reinicio.
- Contadores y Temporizadores: Para aplicaciones que requieran contadores o temporizadores, puedes usar la memoria EEPROM para almacenar valores actuales y continuar desde donde se dejó después de un reinicio.
- Actualización de Firmware: Algunos proyectos pueden utilizar la memoria EEPROM para almacenar datos de actualización de firmware, lo que permite la actualización del software sin perder configuraciones o datos importantes.
- Datos de Usuarios: En aplicaciones interactivas, como juegos o dispositivos de control remoto, puedes usar la memoria EEPROM para almacenar perfiles de usuarios, niveles de juego alcanzados, puntuaciones altas, etc.
- Registro de Errores: En sistemas críticos, puedes registrar errores o fallos en la memoria EEPROM para facilitar el diagnóstico de problemas y el mantenimiento.
- Configuración de Redes: En proyectos de IoT (Internet de las cosas), la memoria EEPROM puede almacenar credenciales de red, como nombres de usuario y contraseñas de Wi-Fi, para conectarse automáticamente a la red cuando se reinicia el dispositivo.
Estos ejemplos muestran cómo la memoria EEPROM puede ser una herramienta poderosa para mantener y utilizar datos importantes en una variedad de proyectos de Arduino y electrónica. Su capacidad para conservar datos incluso después de reinicios o apagones eléctricos la convierte en una opción valiosa para la persistencia de datos en sistemas embebidos.
Precauciones y Límites de la Memoria EEPROM
Aunque la memoria EEPROM es una herramienta poderosa, tiene sus propias limitaciones que debes tener en cuenta al diseñar tus proyectos:
- Ciclos de Escritura/Lectura Limitados: La EEPROM tiene un número limitado de ciclos de escritura y lectura antes de que sus celdas de memoria comiencen a degradarse. Esto significa que no debes escribir datos en ella de manera excesiva o innecesaria. Si necesitas realizar actualizaciones frecuentes, considera otras alternativas, como una memoria flash externa.
- Tamaño Limitado: como ya mencionamos antes, la memoria EEPROM tiene un tamaño limitado, generalmente entre 512 bytes y 4 KB. Asegúrate de gestionar eficazmente el espacio disponible y no sobrecargar la memoria con datos innecesarios.
- Almacenamiento de Datos Sensibles: Si estás almacenando datos sensibles, como contraseñas o claves de cifrado, asegúrate de implementar medidas adicionales de seguridad. La EEPROM no es segura por sí sola, y un acceso no autorizado a la placa Arduino podría comprometer la información almacenada en ella.
- Respaldo de Datos Importantes: Dado que la EEPROM puede fallar con el tiempo o debido a circunstancias imprevistas, considera respaldar datos importantes en otras ubicaciones, como una tarjeta SD o un servidor remoto.
- Monitoreo de Uso: Si planeas usar la EEPROM de manera intensiva, monitorea el número de ciclos de escritura para estar al tanto de su vida útil restante. Puedes usar técnicas de conteo para rastrear el uso y tomar medidas preventivas cuando sea necesario.
Siguiendo estas precauciones y entendiendo sus limitaciones, puedes aprovechar al máximo la memoria EEPROM de Arduino de manera efectiva y prolongar su vida útil mientras garantizas la integridad de tus datos almacenados.
Conclusión
La memoria EEPROM en Arduino representa un recurso invaluable para aquellos que desean conservar datos de manera persistente, incluso después de reinicios o cortes de energía. A lo largo de este artículo, hemos explorado su utilidad y aplicaciones prácticas en una amplia variedad de proyectos, desde el almacenamiento de configuraciones de dispositivos hasta la seguridad de contraseñas y la calibración de sensores.
Sin embargo, es crucial recordar que la EEPROM tiene limitaciones, como un número finito de ciclos de escritura/lectura y un tamaño de memoria limitado. Para aprovechar al máximo este recurso, debemos usarlo de manera consciente y responsable, evitando escrituras innecesarias y respaldando datos importantes.
En última instancia, la memoria EEPROM de Arduino nos brinda una herramienta poderosa para crear proyectos más versátiles y confiables, enriqueciendo nuestro mundo de la electrónica y la programación.
Gracias por el tiempo que dedicas a estos asuntos.
Me gusta seguir tus publicaciones.
Gracias por los comentarios
Muestras una gran profesionalidad y una pedagogía excelente para explicar tus proyectos. Muchas gracias, me estoy iniciando en Arduino y tu página es muy buena, te seguiré en Facebook, saludos desde España.
Gracias.
Hola que tal, antes que nada te felicito por tu profesionalismo y gran entusiasmo en el mundo de los microcontroladores ya que gracias a este espacio me haz salvado de grandes problemas… bueno mira quiero manejar numeros negativos con arduino usando la EEPROM, entonces quisiera saber que me recomiendas hacer para solucionar este problema ya que el momento de escribir por ejemplo -1 en algun espacio de memoria lo guarda con el valor 254, por lo que utiliza complemento a 2 para guardarlo peor para leerlo no lo lee como -1, sino como 254. EL problema está al leer el valor.
Gracias.
Coloca el código que estas ejecutando, necesito saber el tipo de variable que estas usando.
este es mi programa:
if(led1==HIGH){
long t0=millis();
}
if(led1==LOW){
long t1=millis();
tiempoleds=t1-t0
EEPROM.write(1,tiempoleds);
}
como le hago para que sea un ciclo y que cada que se prenda y se apague durante el dia ese led , me guarde los tiempos en la variable tiempoleds?
No estoy seguro. Debe ser 0 o 255. Lo ideal es escribir las posiciones vacías en 0 antes de empezar a usar la EEPROM
Agrega registros del estado del proceso a la memoria EEPROM
Puedes usar módulos microSD o SD. Hay modelos de Arduino que los traen integrados
Saludos desde Venezuela, hice unas pruebas con un simulador de arduino para no cargar tantas veces el programa al micro y no acortar tanto la vida util del mismo. El objetivo es que al encender o apagar una salida, yo pueda guardar ese dato en la EEPROM pero al hacerlo siempre me queda en uno el ultimo estado. El motivo es que con arduino tengo un controlador de luminarias horario y con variables no puedo hacerlo por razones mas que obvias, con esto quiero controlar el hecho de que al llegar la noche (hora de encendido) si se interrumpe el servicio eléctrico y/o se reinicia la tarjeta, se mantenga encendido hasta que llegue la hora de apagado. He intentado esto por rangos de tiempo u horas pero no funciona al 100% . ¿qué me recomiendas hacer? gracias.
Puedes utilizar una memoria más grande, como una microSD o una EEPROM externa
Añade dentro de tu mismo proyecto el proyecto de reloj de tiempo real con respaldo con una batería, o 1 pequeño no-break,para tu ardui,,por si hay apagón de luz o reseteo de la tarjeta,,.O al estarlo alimentando con eliminador,de la pared,pues le pones un capacitor de buen faradiaje, paralelo a gnd y vcc de arduino,y al desactivarse la polarización de un relevador,le mandas voltaje de otra fuente como 1 pila,por ejemplo……obviamente el Arduino lo estás alimentando en el normalmente abierto pero al desactivar la bobina ahora el Arduino se alimente por el normalmente cerrado,de una batería,al irse la luz el capacitor lo mantendra mientras el relevador conmuta,a la bobina del relay le pones diodo y capacitor ya que suelen resetear el ardui, al conmutar..una batería ácido plomo de 6v de no-break te lo mantendra muchas gracias,encendido y no perdera las cuentas y valores…
Saludos, disculpen si es tarde la respuesta pero la EEPROM de arduino al escribir un dato, este queda registrado sin posibilidad de borrarlo, solo reescribir la posición de memoria que almacena el dato, si esta vacía e intentas escribir un dato en alguna salida, pues no hará absolutamente nada, si la salida estaba en HIGH permanecerá así y viceversa.
Estás manejando led1 como entrada ,por que preguntas «if»,(osea; si led1 está recibiendo voltaje o no lo está recibiendo,hago tal cosa)..deberías manejar led1 como salida»output»,sí quieres grabar el tiempo de encendido de tu luminaria es por que no sabes cuántas hrs durara encendida, Ya que Supongo no enciendes la luminaria con 1 botón.
https://www.electronicamain.com/un-sensor-de-luz-arduino-mediante-ldr/
Ejem; lees en pin A0,determinado voltaje que cae,en la ldr o en la resist.,te dará 1 valor entre 0 y 1024,en el monitor serial,por ejem,si está leyendo 2.5volts,te leera 512, y así proporcionalmente.ya depende en qué valor te bases tu. Eso,
Si estás,alimentando por vcc los 5v,exactos o a RAW,»regulador»,y quieres tener la referencia a 5v,y que prenda a 2.5v…
Void Setup ()//hago var.,entrada/salidas
{ Serial.begin(9600); A0= input; d5=input;
d1=Output; }
int grabo = 0;. int dirEEPROM =0;
int mins;. int minsSobra;
void loop()
if(digitalread d5==high)//botónresetfuera
{ int grabo = 0; int dirEEPROM = 0;
for (int i =0; i <=511; i++ )
{ EEPROM.write(i, 0); } //limpiaEEPROM }
while( AnalogRead A0 <= 512 )
//para2.5v o menos que prenda.
{
if(digitalread d5==high)//botónresetdentro
{ int grabo = 0; int dirEEPROM = 0; for (int i =0; i <=511; i++ )
{ EEPROM.write(i, 0); } //limpiaEEPROM }
digitalwrite d1=high; //encender Led
mins = millis() / 60000; grabo = 1;
//Al salir da permiso de grabar..
}//Fin while
digitalWrite d1=low; // apagó ilumina.. mins = (millis()/60000) – (mins);
//a minutos,Redondea x ser variable int..
if ( grabo ==1)//si prendió luminaria..
{ If ( mins 255)
{
minsSobra = mins – 255;
EEPROM.write(dirEEPROM, 255);
direEPROM++;
EEPROM.write(dirEEPROM, minsSobra);
}//do while
}//Else
grabo = 0; }//If grabo..
//Agregar despliegue en Moni.serial
//Si se quiere acumular los datos aún desconectando arduino,grabar el valor de dirEEPROM x ejem. En la dirección 511 o 1023 según la EEPROM de tu tarjeta,
Y al principio del prog. Le asignas el valor leido de dicha dirección a dirEEPROM
//Debe tener varios errores de sintaxis..
//Mins son los nuevos, – la anterior mins.
// ÷ 60000 para convertir de ms a minutos…
//255 es el # máximo que cabe en cada espacio de memoria de EEPROM,osea cada byte..
En la línea…….. If ( mins 255)….era mins <= 255…
Además me faltaron las llaves principales del void loop { },,,,, y seguramente tiene algunos errores de sintaxis ,pero lo escribí sin copy paste a manera de idea,y teniendo años sin manejar "ide"……
También la variable mins bien podria ser cambiada por una tipo unsigned long o una double ya que estaría cachando valores de los minutos,y la int maneja números de hasta 32 767,,(alcanzaría para unos 20 o 22 días,continuos de conteo,, solamente).. y ya poniéndonos más exigentes la variable "grabo" debe ser tipo byte ya que solo tomara el valor de 1 o 0,,,más aparte grabarle las líneas de despliegue en monitor serial(si no,no tiene mucho sentido),,y unas líneas más para grabar en 1 espacio de la EEPROM en que dirección se quedó grabando y que no sobre escriba al desenergizarse la tarjeta o al resetearla,,solamente que lo haga al darle a nuestro botón de reseteo " d5 "..
Más interesante aún mostrarlo en una LCD o algún tipo de pantalla..