Introducción
Todos los controladores lógicos programables industriales basados en Arduino tienen 3 tipos diferentes de memorias:
Flash: no volátil, donde grabamos el sketch (incluyendo el gestor de arranque).
SRAM (Memoria estática de acceso aleatorio): volátil, donde las variables se almacenan durante su funcionamiento.
EEPROM: no volátil, que podemos usar para guardar información entre reinicios.
Si almacenamos valores en la memoria flash o SRAM, estos se perderan una vez que el controlador industrial PLC se reinicie, aunque a veces queramos que se mantengan determinados valores entre reinicios. Por ejemplo, identificadores únicos, valores de calibración, medidas y fechas o tiempos para hacer dataloggers (registrador de datos), guardar un contador, o saber cuál era el estado del procesador cuando se quedo sin energía, entre muchos otros.
En esta ocasión, guardaremos la dirección MAC en nuestro EEPROM, pero el proceso para guardar cualquier otro tipo de datos en el EEPROM es el mismo.
Requisitos
Requisitos de Hardware:
Requisitos de Software:
Características de las memorias en un PLC Arduino
La memoria flash (espacio de programa) es donde se almacena el boceto de Arduino.
SRAM (Memoria estática de acceso aleatorio) es donde el sketch crea y manipula variable cuando se está ejecutando.
La EEPROM es un espacio de memoria que los programadores pueden utilizar para almacenar información a largo plazo.
FlashLa memoria Flash y la memoria EEPROM son no volátiles (la información persiste después de apagar la alimentación). La memoria SRAM es volátil y se perderá cuando se apague la alimentación.
Para los modelos de la familia Ardbox:
Flash 32k bytes (of which 4k is used for the bootloader)SRAM 2,5k bytesEEPROM 1k byte
Para los modelos de la familia M-DuinoM-Duino Family Models:
Flash 256k bytes (of which 8k is used for the bootloader)SRAM 8k bytesEEPROM 4k bytes
Características principales de la EEPROM
La memoria EEPROM tiene sus propias características y peculiaridades que lo diferencian de las otras memorias. Principalmente, tal y como hemos visto antes, no es volátil, por lo tanto mantiene los valores almacenados cuando la energía se termina.
Una desventaja de la memoria EEPROM es que es mucho más lenta que la memoria SRAM. El proceso de escribir una celda (byte) cuesta alrededor de 3.3 ms. El proceso de lectura es mucho más rápido (aunque sigue siendo más lento que la SRAM), leer 1024 bytes cuesta alrededor de 0.3ms, es decir, 10,000 veces más rápido que escribir.
Otra peculiaridad de la memoria EEPROM es que tiene una vida limitada, que se reduce con cada operación de escritura. No hay límites para las operaciones de lectura.
Las especificaciones garantizan que cada celda tenga una vida útil de al menos 100,000. Aunque en la práctica puede ser mucho más alta, incluso hasta un millón de operaciones, alrededor de 100,000 de ellas no están garantizadas.
Cabe mencionar que la memoria EEPROM ha sido diseñada para escribir con tiempos prolongados entre cada operación, no para hacer un uso constante de ello.
El Arduino estándar IDE incorpora una biblioteca Librería EEPROM.h que contiene las funciones necesarias para manipular la memoria no volátil de Arduino.
Las funciones más senzillas son la función Leer y la función Escribir que, respectivamente, leer y escribir un byte en una dirección de memoria. La dirección de memoria puede tener valores de 0 a N-1, donde N es el número de bytes disponibles (de 0 a 1023 en los modelos de la familia Ardbox y de 0 a 4095 en los modelos de la familia M-Duino).
Las siguientes funciones registran un solo byte al EEPROM:
//Reads a unique byte from address "addr"
EEPROM.Read(addr);
//Writes a unique byte from address "addr"
EEPROM.Write(addr);
A menudo, necesitaremos guardar variables que sean más grandes que un byte. Para esto tenemos las funciones Put, Get y Update, que son las que utilizaremos con más frecuencia.
// Functions for complete variables (takes into account the size of the variable)
EEPROM.Put(address, variable)
// Read a variable in the address addr
EEPROM.Get(address, variable)
//Update the value of a variable, that is, read it first, and only save it if its value is different from the one we are going to save. This favors reducing the number of writes, and extending the useful life of the memory.
EEPROM.Update(addr,variable)
Ejemplo de programa
La dirección MAC aleatoria se genera en el primer arranque. En cada arranque subsiguiente, es decir, después del primero, se volverá a leer desde EEPROM para asegurar de que se mantiene igual.
#include <SPI.h> #include <Ethernet.h> #include <EEPROM.h> byte mac[6] = { 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x00 }; char macstr[18]; void setup() { Serial.begin(9600); // Random MAC address stored in EEPROM if (EEPROM.read(1) == '#') { for (int i = 2; i < 6; i++) { mac[i] = EEPROM.read(i); } } else { randomSeed(analogRead(0)); for (int i = 2; i < 6; i++) { mac[i] = random(0, 255); EEPROM.write(i, mac[i]); } EEPROM.write(1, '#'); } snprintf(macstr, 18, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); // Start up networking Serial.print("DHCP ("); Serial.print(macstr); Serial.print(")..."); Ethernet.begin(mac); Serial.print("success: "); Serial.println(Ethernet.localIP()); } void loop() {
}