Lectura datos SD

Buenas a todos,

Escribo por aquí, ya que estoy teniendo un problema con la lectura de datos SD en un proyecto a ver si alguien me puede arrojar algo de ayuda...

En primer lugar, el proyecto consiste en recibir datos de un sensor, guardarlos en una SD y enviarlos por modbus.

El problema que tengo, es que si el arduino se desconectase, necesito que el ultimo valor del sensor no se pierda, por esto lo de usar la SD. He conseguido grabar el valor, pero no leerlo.
Me es indiferente ir guardando valores uno detrás de otro o un único valor y sobrescribir (de la segunda opción, no he conseguido ningún avance...). El caso es poder leer el valor de la SD y continuar en caso de desconexion.

Os pongo el código con el que consigo escribir, pero no leer el último valor desde la SD.

Muchas gracias de antemano.

#include <SPI.h>
#include <Ethernet.h>
#include "MgsModbus.h"
#include <SD.h>

int caudalMax = 15000; // Caudal masico en ml (0-15.000) L/h
int Valor;
int Valor1;
int incremento;
int acumulado=0;
int acumuladoL=0;

MgsModbus Mb;

File myFile;

String cadena = " ";

// Configuración ethernet
byte mac[] = {0x90, 0xA2, 0xDA, 0x0E, 0x94, 0xB5 };
IPAddress ip(192, 168, 1, 151);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

void setup()
{
Serial.begin(9600);

Serial.println("Iniciando SD ...");
  if (!SD.begin(4)) {
    Serial.println("No se pudo inicializar");
    return;
  }
Serial.println("inicializacion exitosa");

Ethernet.begin(mac, ip, gateway, subnet); // Inicialización ethernet

Mb.MbData[0] = 0; // holding Registrer 40001
Mb.MbData[1] = 0; // holding Registrer 40002
Mb.MbData[2] = 0; // holding Registrer 40003
}

void loop()
{
Mb.MbsRun();

leerSD();

analogReadResolution(12); //Damos resolucion de 12 bits al Due
Valor = analogRead(0); //Leemos la entrada analógica
Valor1 = map(Valor , 0, 4096, 0, caudalMax); //Escalamos el valor
Serial.println("Valor leido y escalado:");
Serial.println(Valor1);
incremento = Valor1/360; //ml a incrementar en cada vuelta de 10 segundos
Serial.println("Valor de incremento:");
Serial.println(incremento);
acumulado+=incremento; //Añadimos al acumulado el incremento (ml)
Serial.println("Acumulado:");
Serial.println(acumulado);
acumuladoL=acumulado/1000; //Acumulado en L
Serial.println("Acumulado en litros:");
Serial.println(acumuladoL);

escribirSD();

Mb.MbData[0] = Valor1;
Mb.MbData[1] = acumulado;
Mb.MbData[2] = acumuladoL;

//Serial.println(Mb.MbData[0]);

delay (10000);
}





void escribirSD()
{
  myFile = SD.open("datos.txt", FILE_WRITE);//abrimos  el archivo
  if (myFile) { 
        Serial.println("Escribiendo SD");
        myFile.println(Valor1);
        myFile.close(); //cerramos el archivo        
  }
  else {
    Serial.println("Error al abrir el archivo");
  }
}


void leerSD()
{
  myFile = SD.open("datos.txt",FILE_READ);//abrimos  el archivo 

  if (myFile) 
  {
    bool line=false;
    myFile.seek(myFile.size()-1); //Ubicacion en posicion anterior a ultimo caracter
   
    while (myFile.available()) 
    {
      if(line==false) //Primero leer en reversa para buscar salto de linea
      {
        char caracter=myFile.read();
        Serial.println(caracter);
        myFile.seek(myFile.position()-2);   
        
          if(caracter=='\n') //Cuando encuentra salto de linea cambia estado
          {
            line=true;
          }   
      }

      if(line==true) //Empieza a leer normalmente de izquierda a derecha
      {
          char caracter=myFile.read();
         //Serial.println(caracter);
          cadena=cadena+caracter;
        
          if(caracter=='\n') //La cadena termina en este caracter
          {
            break;
          }      
      }
    }
    
    myFile.close(); //cerramos el archivo
  } 
  else 
  {
    Serial.println("Error al abrir el archivo");
  }

  cadena="";
}

He conseguido grabar el valor, pero no leerlo.

Esto es lo que no entiendo de tu explicación.
Cuando es que lo lees, porque dices

El problema que tengo, es que si el arduino se desconectase,

O sea que el Arduino se desconecta o pierde energía. Okay, entonces ubica en el tiempo cuando ocurren las cosas o cuando pretendes que ocurran.

Hola surbyte,

El único problema que tengo es que no consigo leer los valores (int) que guardo en la SD... El resto de la explicación es parte del proyecto.

O sea que básicamente lo que andaría mal es

void leerSD()

Hola, este código escribe de a 2 números por linea (pero si lo entiendes es facil de modificar) y luego lee el ultimo numero, a ver si te sirve.

Saludos.

#include <SD.h>
File archivo;

int a,b, n,nn, maxi, valor, nnn, a1,a2,a3,a4, num ;
int cs = 4;
char fila[12]; 


void setup() {
  Serial.begin(9600);
  pinMode(cs, OUTPUT);
    
      //***********************************************************
      if (!SD.begin(cs)) {
        Serial.println("no hay SD");
        while (1) ;
      }
      //***********************************************************
      
     a=10;
     b=72;
     n=0;
}

void loop() {
    a=a+1;
    b=b+1;
    n=n+1; 

     archivo = SD.open("automat.txt", FILE_WRITE); //abrimos para escribir
     sprintf(fila, "%-5d%-5d", a, b);  //conviene que los valores no superen los 4 digitos, si son valores de 7 
     archivo.println(fila);            //digitos, por ej, ponemos "8d", etc. Luego modificamos los valores de fila[12]
     archivo.close();
     delay(500);
     Serial.println(n);  
     
     
  if (n > 7 ) {
  Serial.println(" ya se escribieron 8 lineas mas, ahora esperamos 5 segundos, abrimos el archivo y leemos el ultimo valor");
  delay(5000);
  archivo = SD.open("automat.txt"); //abrimos para leer
  maxi = archivo.size();            
  Serial.print(" archivi.size() = "); //maxi tiene que ser multiplo de 12 por la dimension que le dimos a fila[12]
  Serial.println(maxi);
  
  for (nn=(maxi-7); nn<(maxi); nn=nn+1) {
  archivo.seek(nn);
  valor = archivo.read();    //valor viene en codigo ASCII
  if (valor > 47 and valor < 58) {
    nnn=nnn+1;
    if (nnn == 1) { a1= valor-48;  num = a1 }
    if (nnn == 2) { a2 = valor-48; num = a1*10 + a2; }
    if (nnn == 3) { a3 = valor-48; num = a1*100 + a2*10 + a3; }
    if (nnn == 4) { a4 = valor-48; num = a1*1000 + a2*100 + a3*10 + a4; }
  }
  
  }
  Serial.println();
  Serial.print(" el ultimo valor del archivo multiplicado por 10 es ");
  Serial.println(num*10); // ya se puede operar con la variable "num"
  delay(50);
  archivo.close();  //cierra el archivo abierto en modo lectura
  while (1);
  }
 
 }

Muchas gracias por el ejemplo hypernovat, pero lo que me fastidia es no ver el fallo en mi código...

La cosa es que consigo leer, pero no lo hace bien.. Pongo ejemplo:

Los datos recogidos, los separo por comas y cuando leo, lo hago con la función leerSD(), pero si imprimo lo que recojo con esta función, solamente veo el ultimo dígito, y la coma siguiente... :sob:

Ej:

Valor anterior guardado: 8181

Lectura del ultimo valor: 1,

Valor anterior guardado: 4097

Lectura del ultimo valor: 7,

Valor anterior guardado: 4123

Lectura del ultimo valor: 3,

void escribirSD()
{
  myFile = SD.open("datos.txt", FILE_WRITE); //abrimos  el archivo
  if (myFile) { 
        Serial.println("Escribiendo SD");
        myFile.print(",");
        myFile.print(Valor1);
        myFile.print(",");
        myFile.close(); //cerramos el archivo        
  }
  else {
    Serial.println("Error al abrir el archivo");
  }
}


void leerSD()
{
  myFile = SD.open("datos.txt",FILE_READ);//abrimos  el archivo 

  if (myFile) 
  {
    bool line=false;
    myFile.seek(myFile.size()-1); //Ubicacion en posicion anterior a ultimo caracter
   
    while (myFile.available()) 
    {
      if(line==false) //Primero leer en reversa para buscar salto de linea
      {
        char caracter=myFile.read();
        Serial.println(caracter);
        myFile.seek(myFile.position()-2);   
        
          if(caracter==',') //Cuando encuentra un espacio cambia estado
          {
            line=true;
          }   
      }

      if(line==true) //Empieza a leer normalmente de izquierda a derecha
      {
          char caracter=myFile.read();
         Serial.println(caracter);
          cadena=cadena+caracter;
        
          if(caracter==',') //La cadena termina en este caracter
          {
            break;
          }      
      }
    }
    
    myFile.close(); //cerramos el archivo
  } 
  else 
  {
    Serial.println("Error al abrir el archivo");
  }

Serial.println(cadena);

  cadena="";
}

Y has verificado que esta bien guardado? Miras la rutina de lectura, pero verificaste la de escritura?

No entiendo con que programa visualizas esto

Valor anterior guardado: 8181

Lectura del ultimo valor: 1,

Valor anterior guardado: 4097

Lectura del ultimo valor: 7,

Valor anterior guardado: 4123

Hola, y no, parece que no los guarda bien, si nos fijamos en esta parte del codigo coloca una "," antes y despues del dato. Eso le produce una doble coma entre datos numericos. No creo que alli este el problema, yo creo que deberia definir cuantos digitos como maximo tiene que guardar y hacer que la separacion entre comas sea siempre la misma, creo que eso ayuda un poco, suerte!
Saludos.

void escribirSD()
{
  myFile = SD.open("datos.txt", FILE_WRITE); //abrimos  el archivo
  if (myFile) {
        Serial.println("Escribiendo SD");
        myFile.print(",");                        //esta linea creo que esta de mas (salvo que asi lo quieras)
        myFile.print(Valor1);
        myFile.print(",");
        myFile.close(); //cerramos el archivo       
  }