SOLUCIONADO - Tarjeta SD deja de grabar datos al irse y volver la luz

Buenas arduineros,

Tengo un arduino Leonardo con un módulo micro SD adapter para guardar datos leidos de un sensor LM35 (quiero hacer una toma de datos de temperaturas de una caldera pero he simplificado el código para que sea mas sencillo entender el problema)

He conseguido guardar el dato del sensor de temperatura en la tarjeta SD pero el problema es cuando hay un corte de luz.

Tengo entendido que, ante un corte de alimentación, arduino tiene el código guardado internamente y reinicia el programa que tiene guardado al regresar la misma.

Pero con el módulo de tarjeta Micro SD esto no ocurre. Cuando se le quita alimentación al arduino y se vuelve a conectar, en la tarjeta micro SD ya no se guardan más valores.

Es posible hacer que al irse y volver la luz, se sigan guardando datos en la tarjeta MicroSD??

He conectado el módulo micro SD asi:

MicroSD Card<------>Arduino Leonardo

Cs-------------------Pin digital 4
SCK-----------------Pin 3 del ICSP
MOSI----------------Pin 4 del ICSP
MISO----------------Pin 1 del ICSP
Vcc-----------------Pin 3.3v (power)
Gnd-----------------Pin Gnd (power)

Y el código que estoy usando es el siguiente:

#include <SPI.h>
#include <SD.h>

const int chipSelect=4;                             // Declaramos el pin CS en el pin 4
const int sensor0=0;                                // Declaramos el pin analógico 0 como constante "int"
float bytes0;                                       // Declaramos "bytes0" como constante "float"
float temperatura0;                                 // Declaramos "temperatura0" como constante "float"

void setup() {
  Serial.begin(9600);                               // Iniciamos la comunicación serial
  while (!Serial);                                  // Esperamos a que conecte el serial port, solo para Arduino Leonardo
  pinMode(chipSelect, OUTPUT);                      // Declaramos el pin donde está chipSelect como salida

  Serial.print("Inicializando SD...");              // Mensaje inicialización SD card adapter
  if (!SD.begin(chipSelect))    {                   // Comprobamos si tarjeta SD funciona ok
    Serial.println("Fallo o tarjeta no presente");
    return;
  }
  Serial.println("Tarjeta SD OK");
  }
void loop() {
  String datos_publicar = "";                       // Vacia el string de la variable "datos_publicar" para evitar problemas
  bytes0=analogRead(sensor0);                       // Calculamos los bytes del sensor analogico 0 (LM35) en la entrada
  temperatura0=(5.0*bytes0*100.0)/1024.0;           // Pasamos los bytes del sensor 0 a grados centígrados
  Serial.print(temperatura0);                       // Publicamos en el monitor serie
  Serial.println("=TA0; ");
  datos_publicar += String(temperatura0)+String("=TA0; ");  // Guardamos en la variable la lectura del sensor LM35

  File datos_temp = SD.open("logTemp.txt", FILE_WRITE);     // Se genera el archivo o variable temporal "datos_temp" para generar en la SD el archivo "logTemp.txt"
  if (datos_temp) {                                         // Si el archivo existe ¿¿logTemp.txt??, hacemos la siguiente línea
    datos_temp.println(datos_publicar);                     // Escribe el contenido de la variable "datos_publicar" en el archivo logTemp.txt y cambia de línea
    datos_temp.close();                                     // Cierra el archivo "logTemp.txt" para poder volver a escribir en él después
    }
  else {                                                    // Si el archivo no existe ¿¿logTemp.txt??, hacemos la siguiente línea
    Serial.println("error abriendo logTemp.txt");           // Imprime por el monitor serie un error para avisar.
    }
  delay(5000);
  }

Muchas gracias

Saludo

Creo que era un cable roto que hacía mal contacto. Ahora funciona bien.

Gracias

Buenas arduineros,

Después de muchas pruebas he confirmado que no es un problema de mala conexión o cableado suelto, he creado un código que incluye la hora tomada de un RTC para explicaros un poco mejor el problema (el código nuevo lo dejo más abajo).

La prueba que hago consiste en:

1º Arrancar arduino con alimentación externa y el cable usb conectado. → La SD empieza a guardar valores.
2º Desconectar el cable usb. → La SD sigue guardando valores solo alimentado con la alimentación externa.
3º Desconectar la alimentación externa (el arduino se queda sin alimentación de ningún tipo). → La tarjeta SD deja de registrar valores porque no hay alimentación.
4º Conectar la alimentación externa. → La tarjeta SD debería empezar a registrar valores pero no lo hace.
5º Conectar el cable usb (solo conectar el cable, no cargo el programa de nuevo ni toco nada del programa). → La tarjeta SD empieza a registrar valores otra vez (solo por el hecho de recibir alimentación a través del cable USB).

Estos son los resultados obtenidos en la tarjeta SD he indico los momentos en los que hago cada paso:

15.14=TA0; 18:42:54; → Arranco con alimentación externa y cable USB.
15.14=TA0; 18:42:56;
15.14=TA0; 18:42:58;
14.65=TA0; 18:43:0; → Desconecto el cable USB.
14.65=TA0; 18:43:2;
15.14=TA0; 18:43:4;
15.14=TA0; 18:43:6;
14.65=TA0; 18:43:8;
16.11=TA0; 18:43:10; → Desconecto la alimentación externa y 15 segundos más tarde conecto la alimentación externa.
15.14=TA0; 18:44:44; → Conecto el cable usb.
15.14=TA0; 18:44:46;
15.14=TA0; 18:44:48;
15.14=TA0; 18:44:50;
15.14=TA0; 18:44:52;

No debería empezar a funcionar la SD en cuanto recibe alimentación externa? Porque empieza a funcionar cuando se conecta la alimentación a través del cable usb?

Aqui os dejo el código:

#include <Time.h>               // RTC DS1307
#include <Wire.h>               // RTC DS1307
#include <RTClib.h>             // RTC DS1307
#include <SPI.h>                // SD Card
#include <SD.h>                 // SD Card

const int chipSelect=4;         // Pin de la constante chipSelect para el "SD Card adapter"
const int sensor0=0;            // "sensor0" en el pin analógico 0
float bytes0;                   // "bytes0" como constante "float"
float temperatura0;             // "temperatura0" como constante "float"
RTC_DS1307 RTC;                 // RTC DS1307

void setup() {
  Serial.begin(9600);           // Iniciamos la comunicación serial
  while (!Serial);              // Esperamos a que conecte el serial port, solo para Arduino Leonardo
  pinMode(chipSelect, OUTPUT);  // Pin chipSelect como salida
  Wire.begin();                 // RTC
  RTC.begin();                  // RTC  
  Serial.print("Inicializando SD...");              // Mensaje inicialización SD card adapter
  if (!SD.begin(chipSelect))    {                   // Comprobamos si tarjeta SD funciona ok
    Serial.println("Fallo o tarjeta no presente");  // Si cumple la condición imprimimos esto
    return;                                         // Se para el programa aqui si la condición anterior es ok
  }
  Serial.println("Tarjeta SD OK");                  // Si no se cumple la condición imprimimos esto
}
void loop() {
  String datos_publicar = "";                       // Vacia el string de la variable "datos_publicar" para evitar problemas
  bytes0=analogRead(sensor0);                       // Calculamos los bytes del sensor 0 en la entrada
  temperatura0=(5.0*bytes0*100.0)/1024.0;           // Pasamos los bytes del sensor 0 a grados centígrados
  DateTime now = RTC.now();                         // Programa funcion del RTC que devuelve el tiempo
// Publicamos en el monitor serie:
  Serial.print(temperatura0);
  Serial.print("=TA0; ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
  Serial.println(";");
// Guardamos en la tarjeta SD:
  datos_publicar += String(temperatura0)+String("=TA0; ")+String(now.hour(), DEC)+String(":");
  datos_publicar += String(now.minute(), DEC)+String(":")+String(now.second(), DEC)+String(";");

  File datos_temp = SD.open("logTemp.txt", FILE_WRITE);  // Se genera el archivo o variable temporal "datos_temp" para generar en la SD el archivo "logTemp.txt"
  if (datos_temp) {                                      // Si el archivo existe ¿¿logTemp.txt??, hacemos la siguiente línea
    datos_temp.println(datos_publicar);                  // Escribe el contenido de la variable "datos_publicar" en el archivo logTemp.txt y cambia de línea
    datos_temp.close();                                  // Cierra el archivo "logTemp.txt" para poder volver a escribir en él después
    }
  else {                                                 // Si el archivo no existe ¿¿logTemp.txt??, hacemos la siguiente línea
    Serial.println("error abriendo logTemp.txt");        // Imprime por el monitor serie un error para avisar.
    }
  delay(2000);
  }

Muchas gracias por todo

Saludos

Esta respuesta se basa en algo que respondí hace tiempo pero debo revisar si aún es asi.

Alimentas la SD con los 3.3V provenientes del ARduino pero adivina quien provee esos 3.3V?
En muchos casos salen del USB, sea el FTDI por eso es de baja capacidad, 60 mA.
Recomendación. Compra un regulador 5 a 3.3V y alimenta el SD con ese regulador. O un LM317 con las resistencias adecuadas. Luego te digo.
Por ahi esta el problema.

EDITO: este esquema sugiere que no es asi, pero he visto otros arduinos donde esta diferente. En este hay regulador de 3.3V asi que habrái que ver tu caso.

Porque no mides la tensión 3.3V de tu arduino cuando le quitas el USB seguro cae a 0V

Sólo por asegurar, no vaya a ser esta tontería, prueba a comentar la línea
//while (!Serial);

Buenas arduineros,

Noter - He comentado la línea "//while (!Serial);" y parece que funciona, voy a seguir haciendo pruebas pero tiene muy buena pinta, había incluido esa línea de "while" porque leí en algún sitio que era necesaria para los arduino leonardo.

Surbyte - He medido el voltaje en la salida de 3.3 voltios y se mantiene aunque no esté conectado el usb, con lo cual, en este caso no es ese el motivo.

Muchas gracias a ambos

Un saludo