Scrittura su SD card... "corrotta"

Buongiorno a tutti,
scrivo per chiedere aiuto nei confronti della scrittura su SD card.
Utilizzo un sketch che salva su SD dati di temperatura ed arduino è alimentato da una batteria 9V.
Tutto funziona regolarmente, ma talvolta la carta SD, inserita nel computer, non viene letta ma mi viene "detto" che il dispositivo è da formattare (e quindi perdo i dati).

Dato che la registrazione va avanti fino a quanto la batteria è carica, arduino si spegne "da solo". Ora la domanda è: "non sarà mica che la registrazione su SD, in condizioni di batteria al limite (scarica), mi corrompe la scheda?"

Dando per scontto che la SD non ha problemi, occorre che faccia un controllo sulla tensione della batteria ed interrompere il processo di scrittura (ogni 8 secondi, mediante Sleep e Watchdog) quando la tensione arriva in prossimità dei 7Volts?

Il tipo di scrittura che utilizzo é:
// Scrittura su file *****************************
File dataFile = SD.open(NomeFile_C, O_CREAT | O_WRITE | O_APPEND);
// dati da scrivere...
dataFile.flush();
dataFile.close();

Qualcuno di voi ha avuto la stessa esperienza?

Grazie,
Tredipunta.

Non è che spegnendo ed accendendo di continuo la sd gli dai problemi ?
Che libreria stai usando ? puoi postare l'intero codice ?

La SD ha bisogno di 3,3V. L' Arduino funziona, anche se no si dovrebbe usare con un clock di 16MHz, anche sotto i 3,3V.
Temo che i dati dulla SD siano stati corrotti durante la scrittura perché la tensione di alimentazione era troppo bassa.

Porta la tensione della atteria 9V con un partitore resistivo che la dimezza a un entrata analogica e interrompi la memorizzazione del dato quando la tensione della batteria scende sotto i 8V.

Ciao Uwe

La libreria per l'SD è SD.h (qui allegata),
mentre il codice che uso è il seguente:

Grazie a tutti,
Tredipunta.

// **** INCLUDES *****
#include <TCN75A_Reader.h> // lettura di temperatura
#include <DS1307_Reader.h> // lettura di data e ora
#include <LowPower.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <SD.h>
// --------------------

// Istanze
LiquidCrystal_I2C lcd(0x27,16,2); //set the LCD address to 0x27 for a 16 chars and 2 line display
TCN75A classe_T;
DS1307 classe_D;
// --------------------

// Variabili
float cels;
float Tensione_0;
float Tensione_1;
String giorno;
String giorno_s;
String ora;
String ora_s;

// variabili in utilizzo per la scrittura su SD
File myFile;
String NomeFile;
char NomeFile_C[12];
// ----------

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

// Classi
classe_T.TCN75A_init(72);
classe_D.DS1307_init(104);

// LCD
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Initializing...");

// SD Card ***************************************
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(10, OUTPUT);

if (!SD.begin(10)) {
Serial.println("initialization failed!");
// return;
}
else{
Serial.println("initialization done.");

}

classe_D.GetDate(&giorno, &ora, &giorno_s, &ora_s);
NomeFile =giorno + ".dat";

NomeFile.toCharArray(NomeFile_C, 12);
Serial.println("File Name:" + NomeFile);

// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open(NomeFile_C, FILE_WRITE);

// if the file opened okay, write to it:
if (myFile) {
Serial.println("Intestazione");
myFile.println("Intestazione");
// close the file:
myFile.close();
Serial.println("done.");
}
else {
// if the file didn't open, print an error:
Serial.println("error opening file");
}
// SD Card END -----------------------------------
}

void loop()
{
// Enter power down state for 8 s with ADC and BOD module disabled
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

// Get values
classe_T.GetTemperature(&cels);
classe_D.GetDate(&giorno, &ora, &giorno_s, &ora_s);

Tensione_0 = analogRead(0) * 5.0 / 1024.0 * 4.0;// da tarare in funzione del ripartitore di tensione
Tensione_1 = analogRead(1) * 5.0 / 1024.0 * 4.0;// da tarare in funzione del ripartitore di tensione
// -----------

// Invio a porta seriale *************************
Serial.print(giorno_s + " ");
Serial.print(ora_s + " ");
Serial.println(cels,4);
// -----------------------------------------------

// Invio a LCD ***********************************
lcd.clear();
lcd.setCursor(0, 0);
//lcd.print("Time ");
//lcd.print(float(millis()/1000.0), 3);
lcd.print(ora);
lcd.setCursor(0, 1);
lcd.print("T");
lcd.print(cels, 4);
lcd.print(" V0");
lcd.print(Tensione_0, 1);
lcd.print(" V1");
lcd.print(Tensione_1, 1);
// -----------------------------------------------

// Scrittura su file *****************************
File dataFile = SD.open(NomeFile_C, O_CREAT | O_WRITE | O_APPEND);

// if the file is available, write to it:
if (dataFile) {

dataFile.print(giorno + "_" + ora + "\t");
dataFile.print(float(millis()/1000.0), 3);
dataFile.print("\tTempDig\t");
dataFile.print(cels, 4);
dataFile.print("\tTensione_0\t");
dataFile.print(Tensione_0, 3);
dataFile.print("\tTensione_1\t");
dataFile.println(Tensione_1, 3);

dataFile.flush();
dataFile.close();

lcd.setCursor(7, 0);
lcd.print("-> OK");
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog");
lcd.print(" Error");
}
// -----------------------------------------------

delay(500);
}

SD.zip (54.7 KB)