En el diseño de sistemas embebidos e instrumentación electrónica, retener información tras una pérdida de energía es indispensable. Si estás desarrollando un termostato o un registrador de datos y el microcontrolador se apaga por mantenimiento, perderás todas las configuraciones del usuario si no cuentas con persistencia. En mi práctica técnica diseñando automatizaciones en Ecuador, sé que buscar almacenar datos Arduino sin memoria SD es la solución ideal para ahorrar costos de hardware y evitar dependencias de módulos lectores. En este tutorial aprenderás a dominar la memoria EEPROM interna paso a paso.
¿Qué es la EEPROM de Arduino y cuántos bytes tiene?
La memoria EEPROM (Electrically Erasable Programmable Read-Only Memory) es un tipo de memoria no volátil integrada en el microcontrolador Atmel de las placas de Arduino. A diferencia de las memorias RAM comunes, la EEPROM retiene los datos de forma permanente aunque la placa se desconecte por completo de su fuente de alimentación eléctrica, comportándose de forma similar a un disco duro miniatura.
La capacidad de almacenamiento de la EEPROM es bastante pequeña y varía según el chip exacto de la placa de desarrollo. En el microcontrolador ATmega328P (cerebro del Arduino UNO, Nano y Pro Mini) contamos únicamente con 1024 bytes (1 KB) de espacio de almacenamiento. En placas mayores como la Arduino Mega 2560 (basada en el chip ATmega2560) disponemos de 4096 bytes (4 KB), mientras que en placas de 32 bits de gama superior la capacidad se expande significativamente.
Diferencia estructural entre EEPROM, SRAM y Flash
Para programar de forma profesional, es indispensable comprender la diferencia entre las tres memorias del microcontrolador. La memoria Flash es donde se almacena el firmware binario compilado de la aplicación; es no volátil y de solo lectura durante la ejecución del programa. La memoria SRAM (Static Random-Access Memory) es la memoria de trabajo temporal donde se declaran las variables del loop y de las funciones lógicas, perdiendo toda su información en cuanto la placa pierde energía.
La memoria EEPROM complementa este ecosistema actuando como un puente no volátil de lectura y escritura. Mientras que la memoria Flash se programa solo durante la fase de carga desde la computadora y la SRAM cambia constantemente en microsegundos, la EEPROM permite ser leída y modificada dinámicamente por el propio programa en tiempo de ejecución para guardar configuraciones persistentes.
Leer y escribir bytes básicos con la librería EEPROM.h
Para interactuar con la memoria no volátil, el entorno de desarrollo oficial de Arduino provee la librería nativa EEPROM.h. Esta librería contiene funciones optimizadas para leer y escribir celdas individuales de memoria de un byte de longitud (valores numéricos de 0 a 255). La función básica de escritura es EEPROM.write(direccion, valor) y la de lectura es EEPROM.read(direccion).
Las direcciones de memoria se referencian mediante índices enteros secuenciales en base cero (desde la celda 0 hasta la 1023 en Arduino UNO). Es indispensable recordar que intentar escribir un valor mayor a 255 utilizando la función de escritura básica de un byte provocará un error de desbordamiento (overflow), escribiendo únicamente el residuo de la operación aritmética.
Guardar tipos de datos complejos (float, struct) de forma robusta
En aplicaciones reales de ingeniería, rara vez nos limitamos a guardar números enteros pequeños de un byte. Frecuentemente requerimos almacenar tipos de datos compuestos como números con decimales de punto flotante (float que consumen 4 bytes), enteros largos (long de 4 bytes) o estructuras completas (struct) que agrupan variables lógicas diversas.
Para solucionar esto, la librería moderna de Arduino expone las funciones avanzadas basadas en plantillas: EEPROM.put(direccion, variable) para guardar y EEPROM.get(direccion, variable) para recuperar la información. Estas funciones calculan automáticamente el tamaño en bytes de la variable o estructura de datos y ocupan de forma transparente las celdas de memoria contiguas necesarias en la EEPROM.
Ciclos de escritura: límites físicos y cómo prevenir el desgaste
La memoria EEPROM tiene un límite de ciclos de escritura física. Cada celda de memoria soporta aproximadamente 100,000 ciclos de borrado y escritura antes de desgastarse físicamente y perder la capacidad de retener información de forma confiable. Cabe destacar que las operaciones de lectura son ilimitadas y no causan ningún desgaste físico.
Si programas un bucle loop() que escriba lecturas en la EEPROM cada 100 milisegundos, destruirás la celda de memoria afectada en menos de tres horas de funcionamiento continuo. Para prevenir esto, implementaremos la función EEPROM.update(). Esta función lee previamente el valor guardado en la celda y solo realiza la escritura si el nuevo dato es diferente al existente, minimizando drásticamente el desgaste.
Caso de uso: guardar la calibración de un sensor analógico
En sistemas de sensado, los sensores analógicos (como sensores de gas o de peso con celdas de carga) requieren un proceso de calibración inicial tras su montaje. Podemos diseñar una interfaz en la placa de Arduino de modo que, al pulsar un botón de calibración física, el sistema capture el valor actual de desfase (offset) del sensor analógico y lo grabe permanentemente en la memoria EEPROM.
Al reiniciar el microcontrolador (o tras un corte de energía por apagón), la función setup() buscará inmediatamente el dato de desfase calibrado guardado en la dirección de la EEPROM y reconfigurará la lógica de conversión matemática, garantizando que el equipo mantenga la calibración precisa de forma totalmente autónoma.
Código completo para Arduino
A continuación se presenta un sketch práctico para almacenar una estructura de calibración completa en la EEPROM:
#include
// Estructura de datos para guardar la calibracion del sensor
struct Configuracion {
float offsetSensor;
int umbralAlerta;
char IDDispositivo[8];
};
// Direccion inicial en la memoria EEPROM
const int direccionEeprom = 0;
void setup() {
Serial.begin(9600);
Serial.println("Iniciando pruebas de EEPROM...");
Configuracion miConfig;
// Intentamos leer la configuracion previa guardada
EEPROM.get(direccionEeprom, miConfig);
// Si la lectura retorna datos corruptos o vacios, inicializamos valores por defecto
if (isnan(miConfig.offsetSensor)) {
Serial.println("No se detecto calibracion previa. Grabando valores iniciales...");
miConfig.offsetSensor = 0.0345;
miConfig.umbralAlerta = 450;
strcpy(miConfig.IDDispositivo, "SENS-01");
// Guardamos de forma segura en la EEPROM
EEPROM.put(direccionEeprom, miConfig);
} else {
Serial.println("Calibracion leida exitosamente desde la EEPROM!");
Serial.print("ID: "); Serial.println(miConfig.IDDispositivo);
Serial.print("Offset: "); Serial.println(miConfig.offsetSensor, 4);
Serial.print("Umbral: "); Serial.println(miConfig.umbralAlerta);
}
}
void loop() {
// En tu logica puedes disparar un recalibrado y guardar usando:
// EEPROM.put(direccionEeprom, nuevaConfig);
}
La librería EEPROM.h se incluye por defecto en el gestor de compilación de Arduino, por lo que no requiere descargas complementarias en tu IDE.
Errores comunes y cómo solucionarlos
El error más grave es el desgaste acelerado por escritura repetitiva dentro del loop() sin controles temporales. Si necesitas registrar datos continuamente, nunca uses la EEPROM interna; opta por conectar una tarjeta microSD externa o un chip de memoria no volátil de tipo FRAM (ferroeléctrica), que soporta billones de ciclos de escritura y está diseñada para logs rápidos en tiempo real.
Otro fallo común es que al modificar la estructura de datos en tu firmware (por ejemplo, añadiendo un campo de configuración nuevo), el programa lea datos corruptos en la inicialización. Esto se debe a que la estructura nueva desplaza la longitud de bytes leídos y lee celdas escritas con el formato anterior. Soluciona esto escribiendo un valor de firma o versión (ej. un byte con número de versión del firmware) al inicio de la EEPROM para validar su correspondencia.
Conclusión
Guardar datos de calibración en la EEPROM de Arduino es una técnica de optimización de hardware sumamente elegante y económica que garantiza la estabilidad del sistema ante apagones. Si deseas integrar estas lecturas de forma profesional en interfaces IoT o bases de datos en la nube, te sugiero conocer mis servicios.
¿Necesitas implementar esto en un proyecto real? Revisa mis servicios de desarrollo o contáctame directamente.