(Solucionado)Ayuda! Guardar variables en SD y luego obtenerlas.

Buenas a todos mi nombre es Andrés y acabo de entrar en este foro esperando que vuestra sabiduría me sirviera de inspiración jaja.
Bueno aquí va la duda, resulta que estoy trabajando en un programador de riego para mi invernadero con hidropónico porque me salia realmente caro comprarlo, y lo que quiero es que me guarde todos los programas que le meto osea hora, minuto de riego, etc en una SD para cuando haya un corte de luz me los recupere y no se borren. Pero ahí el dilema he intentado de todas las maneras que he podido hacerlo y nada no consigo sacar la cadena de datos correcta... lo que me gustaría hacer seria una cosa mas o menos así:

DatosRiego.txt

id hora minuto duración
1 , 10 , 12 , 05
2 , 11 , 15 , 02

..y así hasta el infinito xD.

Si alguien fuera tan amable de echarme un cable se lo agradecería mucho porque en esta semana tengo que poner la planta y todo tiene que estar listo y funcionando. Saludos a todos!!

Bienvenido
Cambia el título del post por algo mas claro
Copia tu código actual para ver donde esta el problema
Si pones esquema de conexión mejor

Pues mira lo del código he estado probando con un ejemplo que viene y lo he modificado para ver si podía guardar cada riego en un archivo de texto para así tenerlos separados en vez de con las lineas que he puesto antes. el código seria este:

int hora;
int minuto;
int duracion;
int id;
int pos;
int todo;
int ide;
#include <SD.h>
//#include <stdlib.h>

File myFile;

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


 // Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
   pinMode(4, OUTPUT);
   
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
}

void loop(){
  id=45;
  ide=id;
  Serial.print(ide);
  const char*(ide);
  hora=12;
  minuto=13;
  duracion=14;
  myFile = SD.open(ide, FILE_WRITE);
  myFile.println(hora);
  myFile.println(minuto);
  myFile.println(duracion);

  delay(1000);
  myFile = SD.open(ide);
  if (myFile) {
    while (myFile.available()) {
        Serial.print(myFile.read());
    }
    // close the file:
    myFile.close();
  }
}

Esto aparte de que no funciona porque no pasa el numero entero a const char estaría en el mismo problema porque no puedo obtener el dato de cada cosa para su posterior asignación a variable. Espero que me podáis ayudar por que llevo 4 días con esto del c++ y tengo la cabeza hecha un bombo jeje. Saludos !

Hola,
¿has probado en guardar y recuperar como cadena, y convertir a int después?

myFile.println("12");
myFile.println("13");
myFile.println("14");

No puedo guardar como cadena por que esas variables son las que uso en el código original para guardar datos del programa de riego, eso que mostré era solo un ejemplo para hacer las pruebas y luego se lo implementaría al programa original. Lo que tengo en mente es lo que he dicho anteriormente guardar los datos en una sola linea en el fichero de texto cosa así:

id hora minuto duración
1 , 12 , 13 , 14

... pero hay esta el asunto que todavía no se trabajar con cadenas, he estado viendo la librería para cadenas que tiene arduino pero me da fallos al compilar con lo cual no he podido ver lo que hace cada cosa xd. La cosa iría así, me explico, el programa me guardaría las variables en la línea que he puesto arriba, y con algún separador por ejemplo una coma ir diferenciando cada cosa para volver a meterlas en un array de variables que así es como lo tengo en el código del programador ahora mismo y para localizar la línea utilizaríamos el identificador. en definitiva todo se trata de saber jugar con las cadenas así que si alguien por este foro sabe algo de eso le ruego me ayude porque tengo que sembrar este martes y estoy ya desquiciado jaja. Un saludo y muy buen día para todos!

Hola,

Puedes enfocar de dos modos:

    1. fichero de datos en txt con separador (los datos los verás en texto con un editor): escribes y lees una cadena con separador. Después de leer, troceas la cadena y conviertes los trozos a integer.
    1. fichero de datos binario (los datos los verás como basura si los miras con un editor): puedes usar una estructura con todos los datos, y leer y escribir la estructura entera en la SD:

struct datos
{
int id;
int hora;
int minuto;
int duracion;
} datos;

Para escribir usas myFile.write(buf, len), y para leer myFile.read(buf, len)
donde buf es un puntero a la estructura y len el tamaño de la misma (len = sizeof(struct datos))

Buenas curro92, mira he probado lo que tu me has dicho pero se queda atascado al compilar. Te pego el trozo de código y pongo el sitio y el error que me tira. Seguro que es una tontería pero no estoy muy entendido todavía en C++ xD.

Saludos!!

int buf;
struct datos
{
   int id;
   int hora;
   int minuto;
   int duracion;
};
#include <SD.h>
//#include <stdlib.h>

File myFile;

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

   pinMode(4, OUTPUT);
   
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
}

void loop(){
  myFile = SD.open("1", FILE_WRITE);
  struct datos a1;
  buf=a1.id;
  ////////// Invalid conversion from 'int' to  'const uint8_t*'///////
  
  myFile.write(buf , sizeof(a1));
  
  ///////////
  delay(1000);
  myFile = SD.open("1");
  if (myFile) {
    while (myFile.available()) {
        Serial.print(myFile.read());
    }
    // close the file:
    myFile.close();
  }
}

está mal declarado el buffer

struct tdatos
{
int id;
int hora;
int minuto;
int duracion;
};

tdatos buf;

ahi ya tienes definido una variable del tipo tdatos.
y ya no la vuelves a definir luego, es global al fichero. si la quieres local al metodo la declaras justo antes de usarla.

Hola,
en este caso el buffer sería a1
la función write tiene que recibir un buffer (una variable o posición de memoria) de bytes sin signo. Tendrías que hacer una conversión explícita o cast (const uint8_t*) señalando la dirección del buffer (&a1)

// abrir, escribir y cerrar
 myFile = SD.open("1", FILE_WRITE);
 myFile.write((const uint8_t*)(&a1) , sizeof(a1));
 myFile.close();

// y abrir para leer
  myFile = SD.open("1");
  myFile.read(&a1, sizeof(a1));

Cada vez que hagas algo (por ejemplo, abrir fichero) haz las comprobaciones de errores.

Voy a abrir un nuevo post como INFO para este terma

Muy buenos días, lo primero gracias a todos los que me vais contestando y soportando porque no se mucho de esto todavía y me cuesta arrancarme xD. Lo segundo es que ya he puesto todo como me dice ha dicho curro92 y si ya me escribe y me lee pero no los valores correctamente (pone números a su antojo jaja) os pego el código y los números que me da:

struct datos
{
   int id;
   int hora;
   int minuto;
   int duracion;
}; 
datos a1;

#include <SD.h>

File myFile;

void setup()
{
  a1.id=1;
  a1.hora=12;
  a1.minuto=13;
  a1.duracion=14;
  Serial.begin(9600);
   while (!Serial) {
     ;
  }
  pinMode(4, OUTPUT);
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  myFile = SD.open("1", FILE_WRITE);
  myFile.write((const uint8_t*)(&a1) , sizeof(a1));
  myFile.close();
}

void loop(){
  a1.id=2;
  a1.hora=121;
  a1.minuto=132;
  a1.duracion=143;
  myFile = SD.open("1");
  myFile.read(&a1, sizeof(a1));
  myFile.close();
  Serial.println(a1.id);
  Serial.println(a1.hora);
  Serial.println(a1.minuto);
  Serial.println(a1.duracion);
  delay(1000);
}

y los valores que me da son:

initialization done.
512
1536
680
125

...esto se puede deber a que se han escrito en el fichero convertidos a otro formato??

Un saludo a todos!! y gracias de nuevo jeje

si quieres guardar el estado o variables en previsión de un corte de tensión te recomiendo usar la EEPROM interna.
Te dejo el pde que uso yo para el riego. Este skech contempla el uso de una pantalla LCD y un reloj por I2C. No hagas caso al código que no necesites.
En mi ejemplo, guardo en la eeprom el tiempo que quiero que riegue caza zona y la hora y minuto que quiero que empiece.
el menú es útil si tienes pantalla LCD y uno bootones (resistencias) para moverse.

Buenas, yo como primera opción también opte por la eeprom pero no había manera de que me guardara las variables xD, cuando me pases el código intentare implementarse lo al mio también pero con todo eso me gustaría la verdad tenerlo también en la sd ya que se la tengo en la caja atornillada y demás jeje. Estoy a la espera del código, un saludo compañero y gracias!!

Muy buenas compañeros, ya he solucionado el temita de la dichosa SD y se la he implementado a mi código satisfactoriamente XD. Os lo dejo por si a alguien le sirve de algo, utiliza un teclado matricial, una caja de reles de 4, pantalla lcd, reloj a tiempo real y tarjetas SD:

Un saludo a todos y muchísimas gracias por vuestra ayuda y el que viva por la costa de granada que me avise y le invito a una cervecica! jeje

Nuebo_proyecto.ino (8.32 KB)

donde estaba el problema? como lo has solucionado?
Esto es lo que hace el foro rico de sabiduria.

Pues mira en vez de hacer la estructura he cogido y lo he puesto variable a variable porque poniendolo como estructura me daba numeros equivocados, y para la obtencion del dato en concreto he utilizado el identificador que uso en el codigo de mi maquina de riego. Hay una pega que para borrar cualquier dato hay que usar el mismo identificador con un bucle no he conseguido borrarlo entero pero vamos que me sirve igualmente jeje, he dejado el codigo en mi comentario anterior por si le quiere echar un vistazo y si le sirve pues mucho mejor . Saludos!!

paco garcia me podria ayudar mandando el archivo yo necesito guardar datos en la eeprom seria de mucha ayuda para mi proyecto