Secuencia escritura de una Struct en EEPROM

Hola a todos:

Tengo un lío monumental con Struct, Union y su manipulación con la EEPROM. El asunto es que tengo varios bloques de datos de tipos variables, boolean, byte, float, etc., que quiero manejar de forma agrupada para escribirlos y leerlos de la EEPROM.

Mis dudas son tales que necesitaría una secuencia ejemplo de:

  • Declaración de las variables dentro de la Struct y si es o no necesario utilizar Union
  • Cómo declarar punteros para cada grupo.
  • Cómo escribir y como leer la Struct

Por favor, no me derivéis a enlaces que no sean para completos novatos. Os aseguro que me los he leído y releído todos, en Español y en Inglés y no me he enterado.

Disculpad mi tremenda ignorancia pero cuando pido ayuda aquí es que el problema me supera. Gracias por vuestro tiempo y atención.

Poque te complicas si ahora es muy fácil con EEPROM.get() y EEPROM.put()

Mira los ejemplos y verás lo simple que es pasar de una structura a la EEPROM ida y vuelta.

Gracias, surbyte, gracias ArduMyth. Lo único que tengo claro es el uso de .put() y .get(). Voy a tratar de ser más explícito.

El "grupo" de variables es una simple agrupación práctica sin otro objeto que facilitar su manipulación conjunta:

boolean aFTR_PUMP;
boolean aFTR_FLOW_Ctrl;
boolean aFTR_PRESS_Ctrl;
float aFTR_PRESS_Ctrl_MAX;
float aFTR_PRESS_Ctrl_MIN;
boolean aASV;
boolean aASV_Ready_LED;
byte aASV_SCRTY_Time;

En el caso del grupo anterior, (de los cuáles tengo media docena), he visto que si no tengo un "indicador" que me diga, primero, en qué dirección de EEPROM empieza cada grupo y, segundo, el tamaño de cada grupo, el tema de actualizar la EEPROM se me complica hasta el punto de tener que ir "apuntando", una por una, la posición en la EEPROM de cada una de las variables.

No he conseguido encontrar nada que me ayude pero estoy seguro que debe haber una solución.

Gracias por vuestra paciencia,

Gracias, ArduMyth. Ciertamente la librería EEPROM.h es muy simple de aplicar. Mis dudas son en cómo facilitar dónde están las variables en la EEPROM y, en mi ignorancia, sospecho que el problema se resolvería mediante punteros.

Concretamente en tu ejemplo .put está claro el cómo obtener la ubicación para cada elemento de la estructura, sin embargo, en la operación .get ¿para cada estructura tendría que memorizar todas y cada una de las posiciones de dirección de las variables?, en resumen, ¿cómo y dónde podría almacenar la dirección individual de cada variable (que yo llamo "punteros", puede que indebidamente)?, si es que ello es posible.

Seguramente pensarás que estoy muy verde en esto de programación, pues es cierto, muy muy verde y muy muy mayor.

Otra vez gracias por vuestra paciencia.

Gracias a todos. Esto es lo que andaba buscando:

#include <EEPROM.h>
int eeAddress = 0;

// GRABACION
#include <EEPROM.h>
// Paso 1: Creación Estructura
struct MiStruct{
  float field1;
  byte field2;
  char name[10];
};

// Paso 2: Asignación de valores "por defecto"
  MiStruct MiStructVal = {
    3.14f,
    65,
    "FUNCIONA!"
  };
  
void setup() {
  Serial.begin(9600);
  // GRABACION EEPROM Valores "por defecto"
  EEPROM.put(eeAddress, MiStructVal);  
}
void loop() {  
    Serial.print("Pra.DIRECCION: ");Serial.println(eeAddress);
    // LECTURA EEPROM Valores "por defecto"
    EEPROM.get(eeAddress, MiStructVal);
    Serial.println(MiStructVal.field1);
    Serial.println(MiStructVal.field2);
    Serial.println(MiStructVal.name);
    eeAddress += sizeof(MiStructVal);
    Serial.print("Ste.DIRECCION: ");Serial.println(eeAddress);
    //eeAddress = 0;
}

Me permite grabar los valores "por defecto", separarlos por materias mediante estructuras "ad hoc", leer y separar individualmente los valores (sin punteros) y (debo probarlo), grabar los cambios mediante EEPROM.update.
Aunque he encontrado muchísima información, ninguna tan simple y eficaz como la encontrada en:

Nuevamente gracias a todos por vuestra paciencia.

Hola, ArduMyth:

Francamente, hay ejemplos de arduino (y el caso de struct, union e instances) que no logro comprender muy bien, como una buena parte del C, de ahí que incluso "bautice" cosas inapropiadamente, como es el caso de los "punteros". Para entender muchas cosas de Arduino, suelo buscar ejemplos durante horas y, probablemente porque no sé explicar muy bien la ingente cantidad de dudas que tengo, el foro de Arduino no me está sirviendo de mucha ayuda.

El ejemplo que puse me funciona perfectamente, tengo como media docena de otras estructuras tan abigarradas como la del ejemplo y pretendo utilizar sizeof para obtener la siguiente dirección. Pese a que las funciones de la librería EEPROM son claras, no conseguía adaptarlas a mis propósitos.

Concretamente, dices que puedo asignar los valores en la declaración de la estructura:

struct MiStruct{
  float field1 = 3.14;
  byte field2 = 65;
  char name[10] = "FUNCIONA!!";
};

Para escribir en la EEPROM tengo la función:

void saveAssembledEEPROM() {
  EEPROM.put(eeAdress,MiStructVal);
}

y para leer de la EEPROM:

void loadAssembledEEPROM() {
  // Lee la EEPROM
  EEPROM.get(eeAdress,MiStructVal);
}

y para individualizar cada campo:

x = MiStructVal.field1;
y = MiStructVal.field2;
z = MiStructVal.name;

lo único que se me ocurre es, de acuerdo con tu sugerencia, es sustituir MiStructVal por MiStruct pero me da un montón de errores, no sé si he metido la pata o esa no es la forma.

Te agradeceré tus comentarios,

P.S. Tengo claros los límites de escritura de la EEPROM. Para hacer pruebas (y las hago a miles) utilizo la simulación de Proteus, todavía no he grabado nada en mis variadas tarjetas de Arduino, salvo el típico ejemplo de "blink" para saber que funcionan, sea, tan solo el LED.
Te adjunto una copia muy parcial del "tinglado" en que me he metido. Observa que tengo herramientas y conocimientos sobre ellas de sobra, me faltan conocimientos del lenguaje de Arduino y me sobran una pila de años.

APC.pdf (664 KB)

Bueno, ArduMyth, parece que se me ha olvidado escribir en Español o mi Español es de la época del Quijote. Estando de acuerdo con buena parte de lo que dices, no puedo estar de acuerdo en tu deducción de que pretendo utilizar el foro para aprender, lo único que pretendo es solventar dudas y, si bien es posible que no sepa expresarme convenientemente en una materia que no domino, creo que el último ejemplo que he puesto merecería, en mi humilde opinión, contestar a si se puede o no se puede utilizar tu sugerencia en el modo y manera que yo lo he interpretado y que, simplemente no me ha funcionado.

Resulta evidente que siguiendo tu sugerencia suprimo el según tú, superfluo Paso2, en cuyo caso, necesariamente cambian las funciones de gestión de la EEPROM que me funcionaban y que se citan en el mensaje anterior y que, en mi corto entender, he modificado y no funcionan. No veo otra forma de plantearlo para que se me entienda.
La estructura sí es idéntica:
INICIAL

[b]// Paso 1: Creación Estructura
struct MiStruct{
  float field1;
  byte field2;
  char name[10];
};
// Paso 2: Asignación de valores "por defecto"
  MiStruct MiStructVal = {
    3.14f,
    65,
    "FUNCIONA!"
  };[/b]

INTERPRETACIÓN DE TU SUGERENCIA

[b]// Paso 1 &2: Creación Estructura y asig. de valores
struct MiStruct{
  float field1 = 3.14;
  byte field2 = 65;
  char name[10] = "FUNCIONA!!";
};[/b]

// Paso 2: Asignación de valores "por defecto"
//  MiStruct MiStructVal = {
//    3.14f,
//    65,
//    "FUNCIONA!"
//  };

En cualquier caso, si sigues sin entender mi pregunta, prefiero que, simplemente no me contestes, en lugar de darme toda una suerte de lecciones que, en mi humilde opinión, no entiendo el porqué de las mismas ya que no responden a mis dudas, ni tampoco entiendo el porqué de tanto reproche y es que, si siguiendo tu sugerencia y modificando (con mis escasos conocimiento) las funciones de escritura, lectura e individualización de campos me dan errores de compilación ¿qué estoy haciendo mal?.
Aunque no consigo resolver ni una sola de mis dudas, sigo apreciando vuestra paciencia y atención pero, por favor, no necesito "palizas" que tan solo me provocan confusión.
Saludos y, repito, si mis preguntas no se entienden, la ausencia de respuesta será suficientemente significativa.

Tienes que concebir la estructura o struct como una plantilla vacia que contiene los tipos de datos que necesitas .Si voy a guardar datos ,creo una nueva variable a partir de la plantilla ,le asigno los valores que quiera y la guardo.Si voy a recuperar un dato guardado en la eeprom ,creo una variable vacia a partir de la plantilla y guardo en ella lo que recojo de la eeprom y trabajo con los datos recogidos.