domingo, 14 de octubre de 2018

Introducción a la EEPROM, memoria interna de Arduino



En esta entrada vamos a introducirnos en un espacio poco empleado de nuestra arduino, su ROM; la ROM es una memoria interna no volatil ó permanente; esto puede resultar muy útil para guardar información y no perderla en caso de reinicio ó apagado y así poder acceder a ella en cualquier momento. Pero esta característica tan interesante tiene limitaciones; y es que disponemos de tan sólo 1024 bytes de espacio, y nótese que NO he dicho 1Kbyte, aunque sea lo mismo. La explicación está en la profundidad, resolución ó amplitud; Me explico, El Atmega 328 de Arduino dispone de 1024 espacios de un byte cada uno; esto significa que en cada uno de los 1024 espacios solo podemos guardar valores iguales ó inferiores a un byte; (valores de hasta 255 en cualquiera de sus representaciones; números decimales, binarios, Hexa, ASCII, etc.. ) Las aplicaciones del uso de la ROM ó EEPROM (para Arduino) pueden ser muy diversas, en mi caso concreto hago uso de ella en mi estación metereológica para guardar los datos recogidos así como la fecha y hora. Debido a las limitaciones comentadas se requiere cierto ingenio para poder guardar una fecha ó una hora, y este es uno de los motivos para introducir este tema ahora, junto con el posterior (Función definida MAP) puesto que mi objetivo final es mostraros como he construido mi estación metereológica (lectura de Temperatura, Humedad, Presión Atmosférica, Componente del viento, Intensidad del Viento y Pluviometría). Bueno, regresando al asunto, podemos observar alguna curiosidad, a partir de la posición del array 255, donde su valor es 256 y el valor escrito en la EEPROM es 0; como he comentado anteriormente la EEPROM solo puede almacenar valores de hasta 255 (1 byte). Cuando superamos este valor nótese que el programa le da la vuelta al valor y comienza desde cero y de ahí hacia arriba, este comportamiento es muy importante tenerlo en cuenta. Si pretendemos guardar en la EEPROM un valor superior a un byte tenemos varios caminos, os propondré dos (en posteriores entradas) que requerirán de una gestión adicional (usar tantos bytes como sean necesarios ) y otro mas elegante pero con pérdida de resolución (con la función MAP).

El uso ó manejo de la EEPROM requiere incluir la librería EEPROM al principio del Sktech (Linea 2 del adjunto). La gestión de la EEPROM se hace con dos instrucciones:
- PARA ESCRIBIR; EEPROM.write(posición,valor); línea 32. Requiere dos parámetros; el primero es la posición en la cual queremos escribir, va de 0 a 1023, si indicamos 1024 escribirá en la posición 0 y así sucesivamente. El segundo parámetro es el valor que pretendemos escribir o su ubicación.
- PARA LEER; EEPROM.read(posición); lógicamente sólo requiere un parámetro, la posición que queremos leer.

Y ya, ahí va el Sketch:

 #include <EEPROM.h>  // incluye la libreria EEPROM para poder hacer uso de la ROM en nuestro Sketch
// A continuacion se declara un array de tipo "int" con 360 posiciones y se da un valor a cada una de ellas
int valores[360]={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,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
                  64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,
                  94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,
                  118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,
                  141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,
                  164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,
                  187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
                  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,
                  233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
                  256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,
                  279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,
                  302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,
                  325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,
                  348,349,350,351,352,353,354,355,356,357,358,359,360};                

void setup() {
   Serial.begin(115200);// indicamos una velocidad de comunicacion superior a la habitual(9600), para que imprima mas rapido
   Serial.println(); 
   for(int i=0;i<360;i++){  // bucle para el control de la impresion
      Serial.print("Pos. array n");Serial.write(186);Serial.print(" ");//Serial.write()imprime caracteres especiales
      if(i<10){Serial.print("  ");}// rellena dos espacios en blanco si el valor leido tiene solo un caracter
      if(i<100 && i > 9){Serial.print(" ");}// rellena un espacio en blanco si el valor leido tiene solo dos caracteres
      Serial.print(i);Serial.print(" ");// imprime el valor de "i", dado por el bucle y usado como indice
      Serial.print(" valor ->  [ ");
      if(valores[i]<10){Serial.print("  ");}// rellena dos espacios en blanco si el valor leido tiene solo un caracter
      if(valores[i]<100 && valores[i] > 9){Serial.print(" ");}// rellena un espacio en blanco si el valor leido tiene solo dos caracteres
      Serial.print(valores[i]);Serial.print(" ] ");// imprime el valor del array en la posicion "i" dada por el bucle
      EEPROM.write(i,valores[i]);// Escribe en posicion "i" (dada por el bucle)
      Serial.print(" valor en EEPROM ->  | ");
      if(EEPROM.read(i)<10){Serial.print("  ");}// rellena dos espacios en blanco si el valor leido tiene solo un caracter
      if(EEPROM.read(i)<100 && EEPROM.read(i) > 9){Serial.print(" ");}// rellena un espacio en blanco si el valor leido tiene solo dos caracteres
      Serial.print(EEPROM.read(i));Serial.println(" |");// lee e imprime en la posicion "i" (dada por el bucle) de la EEPROM
   }
}

for(int i=0;i<102;i++){  // bucle para el control de la impresion
void loop() {}

No hay comentarios:

Publicar un comentario

Gracias por tu comentario, en breve lo revisaremos.