Ya explique en anteriores entradas como hacer uso de las estructuras UNION y STRUCT, también como usar la memoria EEPROM de Arduino para poder guardar de forma permanente los datos que queramos.
En esta ocasión toca ver como guardar todos los datos que queramos en la memoria EEPROM de forma muy cómoda, y no un solo dato como la otra vez. Muy útil para guardar la configuración de nuestro programa y cargarla cada vez que encendamos el Arduino.
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 |
/* Author: Alberto Gil Tesa WebSite: http://giltesa.com License: CC BY-NC-SA 3.0 Date: 26/06/2013 Description: Ejemplo de uso de una estructura STRUCT y UNION combinadas para almacenar varios datos de forma comoda en la memoria EEPROM del Arduino. Cada vez que se reinicia el Arduino con el boton de RESET, o se conecte a la corriente, aumentaran los datos y se imprimiran los nuevos. Solo es un ejemplo, lo ideal seria guardar la configuracion de nuestro programa al encender el Arduino, y modificarla desde un menu con un LCD y unos botones, etc. Recomiendo leer las entradas: Estructuras UNION: http://giltesa.com/?p=13666 Uso de las estructuras: http://giltesa.com/?p=13693 */ struct DATOS{ float temperatura; float humedad; int luz; boolean usable; }; union MEMORIA{ DATOS dato; byte b[sizeof(DATOS)]; } miMemoria; #include <EEPROM.h> #define address 0 void setup() { // Se recuperan los datos de la memoria EEPROM: for( int i=0 ; i<sizeof(DATOS) ; i++ ) miMemoria.b[i] = EEPROM.read( address+i ); // Se comprueba que se hayan podido leer los datos (que no se haya leido basura) // No es la forma mas elegante de hacerlo pero funciona: if( miMemoria.dato.usable == true ) { miMemoria.dato.temperatura += 0.5; miMemoria.dato.humedad += 0.1; miMemoria.dato.luz += 1; } // Si nunca se habian usado se inicializan todos los datos: else { miMemoria.dato.temperatura = 0.0; miMemoria.dato.humedad = 0.0; miMemoria.dato.luz = 0; miMemoria.dato.usable = true; } // Se guardan los datos en la memoria EEPROM: for( int i=0 ; i<sizeof(DATOS) ; i++ ) EEPROM.write( address+i , miMemoria.b[i] ); // Se imprime por pantalla los datos: delay(1000); Serial.begin(9600); Serial.print("Temperatura = "); Serial.println(miMemoria.dato.temperatura); Serial.print("Humedad = "); Serial.println(miMemoria.dato.humedad); Serial.print("Luz = "); Serial.println(miMemoria.dato.luz); pinMode(13, OUTPUT); digitalWrite(13, HIGH); } void loop() { // Una vez cargamos los datos en el SETUP ya podemos hacer uso de ellos desde nuestro programa. // ... } |
Para probarlo no hace falta nada mas que el Arduino. Se conecta, se graba el código y se abre el monitor Serial del IDE, después cada vez que pulsemos el botón RESET de la placa veremos que se imprimen nuevos datos, y si desconectamos y conectamos el Arduino veremos que se acuerda de los últimos datos y que imprime los siguientes.
Hola, gracias por enseñar con tus post y tutoriales.
Me ha surgido una idea-duda, si necesitara guardar una hora de encendido de la luz , con sus minutos y horas por ejemplo en byte 0 y byte1 y una hora de apagado de las luces en byte 3 hora y los minutos en byte 4, se podrian al dia siguiente, de alguna manera leer esos byte y hacer que se encienda la luz 30 minutos antes y se apagara 30 despues.?? como se escribiria esa parte. Este codigo seria buena para simular presencia en una casa sin estar viviendo en ella, y que no cogieran rutina. Un saludo
Hola Luis,
Se puede hacer perfectamente, simplemente cuando llegue la hora guardada en la EEPROM ejecuta la tarea y además cambia los datos para que la próxima ejecución se realice 30 minutos antes.
También podrías generar números aleatorios para generar las horas de encendido y apagado.
Saludos.
Hola, y gracias por contestar.
Solo me haria falta la simulacion de 30 minutos antes y 30 minutos despues para los fines de semana. Me podrias orientar un poco en el codigo, porque estoy algo perdido?
Un saludo y muchas gracias
union {
DATOS dato;
byte b[sizeof(DATOS)];
} miMemoria, miMemoria2, miMemoria3, etc;
Así hombre. Haz las cosas bien. Saludos
Me explicas la utilidad de tu comentario teniendo en cuenta que en mi código sólo uso una estructura…
Saludos.
Buenas Giltesa, gracias por el tuto. Tengo una pregunta si ya tengo una librería que guarda unos datos de configuración que esta desarrollada por otra persona. Pero a mi me interesa guardar otros datos de configuración con el método que has explicado, mi problema es que no me quiero cargar los datos que guarda la librería, ¿eso como lo puedo solucionar?
Un saludo y gracias
Hola Tarjeks,
Pues tendrás que averiguar en qué dirección de memoria empieza a guardar los datos y en cuál termina, y si queda espacio libre entonces empezar a grabar a partir de la dirección de memoria libre.
En este ejemplo se empieza desde la dirección 0, solo tienes que cambiarlo para que empiece a partir de la dirección libre.
Saludos.
Gracias es lo que suponía, para averiguarlo la única forma es mirando el código de la librería no?, tal vez me ponga en contacto con el desorrallador. La librería es wifimanager para esp8266 por si te interesa o me puedes echar un mano.
Un saludo y gracias.
Hola GILTESA perdona que comente esque necesito ayuda, tengo un proyecto de un robot-carro que detecta objetos pero esto lo hace automaticamente, quisiera que me puedas ayudar necesito aplicar las estructuras de datos nodos de un arbol para que cuando mi robot detecte un objeto/obstaculo guarde esa informacion y cuando lo heche andar otra vez por el mismo camino evite ese objeto que ya ha registrado anteriormente, me podrias ayudar porfavor ando perdido con el codigo lo que ya he hecho no eh usado estructuras ni uniones 🙁 ayuda porfavor
Hola Eduardo,
Tienes muchos ejemplos en internet: Google
Aquí tienes info también: Dropbox
Saludos.
Buenas ….
GILTESA …
soy nuevo en este ambiente del arduino …ya e montado algunos sketch… pero e estado algo pegado con el asunto de guardar datos en la eepron …
Explico ….
Me di a la tarea de hacer un velocimetro con displey para mi carro el cual se daño y por el modelo del carro me sale algo costoso …
Ya tengo el codigo a utilizar para ( mas tarde puedo subirlo ahora no tengo la pc) pero al ser para el carro y por requerimientos de la inspeccion necesito guardar el » ODOMETRO » de tal manera que no se borre al apagar el carro y se actualice cuando va en marcha … el roblema surge al tener que guardar en arias direcciones en la eeprom ya que tengo claro que no se puede pasar de 250…..
Agradeseria algun ejemplo de como guardar ese dato en la eeprom…. que deveria tener un alcance de aproximadamente » 999 999″ grasias de antemano al que tenga el gusto en ayudar…
Hola,
Sólo tienes que cambiar las variables de la estructura por unas con el tipo que necesites, en principio float o double.
Saludos.
Hola, tengo una duda utilice tu programa pero quiero almacenar un string y me arroja un error de copilacion no se si es porque debo pasar esa informacion string a tipo byte para poder almacenarla, ayudame pls es un proyecto para almacenar informacion de configuracion para conectar a la red GSM tales como apn, pass etc.
Hola Tomas,
Sólo se pueden usar tipos primitivos, nada de objetos. Tendrás que guardarlo en un array de caracteres de tamaño fijo o en varias variables numéricas.
Saludos.
Hola Giltesa,
Tengo una duda ojala me puedas resolver. Mi duda es respecto a la durabilidad de la EEPROM lei que obviamente tiene una vida util de X cantidad de Ciclos de Lectura y escritura, a mi me interesa almacenar datos grandes que van a ser el TIEMPO DE USO, del equipo, de una LUZ, etc… los datos los estoy almacenando en variables tipo LONG, queria saber si habria algun problema en ese esquema? Si hay un tamaño maximo que pueda guardar en un bloque de memoria de la EEPROM? si el ciclo de vida es corto? si recomendas hacer algun waving para distribuir la carga a lo largo de la EEPROM? o si simplemente no pasa nada :P. La idea es que el equipo que estoy haciendo es factible que trabaje al menos 12 o 18 horas al dia durante muchos años y quiero saber si alguna vez voy a encontrar algun problema… Mi idea es guardar los datos en la EEPROM 1 vez cada 10 o 15 minutos. Desde ya muchisimas gracias!
Hola Mauro,
Teóricamente permite unas 100.000 escrituras cada celda de memoria de la EEPROM, por lo que grabando 24 horas diarias con una frecuencia de 10 minutos te duraría cada celda algo menos de 2 años (grabando una variable LONG nada mas), si fueras cambiando la zona de memoria en la que se guarda esa información podrías aumentar a 475 años… claro que de alguna forma el programa debe saber dónde están los datos actuales en la EEPROM y dónde se deben de guardar los siguientes… eso requerirá más memoria para guardar la dirección de memoria en la que se encuentran esos datos y dónde guardes esa dirección también deberá ir rotando ya que si no también se gastara esa celda.
Otra forma seria guardar una estructura con los datos y algún flag que indique que es el ultimo bloque de memoria, o borrar el último y grabar el siguiente de modo que nunca haya mas de una estructura guardada en la memoria aunque eso implica la operación de escritura dos veces: rellenar datos y borrar datos.
Todo esto lo tengo muy pensado porque quise fabricarme un contador de tiempo, empece el código pero aun da algunos errores, te lo pego igualmente por si te sirve:
https://gist.github.com/giltesa/813d6b47a7dcade751df
También podrías usar un lector de tarjetas y una SD/MicroSD, es lo que use en una estación meteorológica y lleva desde le 2012 grabando datos, le añades un reloj DS3231 y grabas los datos cada día/mes en un fichero distinto, veo imposible que estropees la tarjeta de ese modo.
Saludos.