Tarjeta SD - Falla aleatoria al escribir [SOLUCIONADO]

Estimados, no he encontrado algo relacionado con este tipo de falla aleatoria que estoy teniendo al querer escribir/guardar sobre un TXT en una MicroSD.

El Sketch que estoy utilizando es el siguiente:

#include <SD.h>
File myFile;
int contador=0;

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

  Serial.print("Initializing SD card...");

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

  // 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("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
  
}

void loop(){
  // 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("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    delay(5);
    myFile.print("contador");
    delay(5);
    myFile.print(":");
    delay(5);
    myFile.println(contador);
    myFile.close();
    Serial.println("pasada");
    } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
contador=contador+1;
   delay(10000);
}

y la falla es que de manera aleatoria, y por algún motivo el cual no entiendo, NO escribe la palabra contador, pero si por ejemplo los dos puntos ( : ) y el valor de la variable. Ver adjunto, esta resaltado en amarillo donde se produce la falla.

En este ejemplo, de los 5297 registros, solo 46 hubo con falla (un 0.8%), no es muy elevado, pero me genera incertidumbre el motivo.

Adjunto también el diagrama de conexión de la SD contra el Arduino:

Hola diegotala1985, por favor edita tu post anterior y usa los enlaces adjuntados (botón derecho del mouse) para insertarlo como imagen usando el tag (pantalla junto al eslabón). Asi se puede ver directamente cada imagen.

No estarás usando un LCD shield conjuntamente con tu SD no?
En el código no veo que uses LCD pero el backlight del LCD usa el pin 10 y es el mismo en algunas placas que controlan la SD.

Buenas tardes. Use o no el LCD, la falla se produce igual. En el ejemplo que adjunto, no lo uso, y falla igual. El LCD que tengo no tiene BackLight igualmente. Ahora hago la prueba de cambiar el PIN 10 por el PIN 4 y vuelvo a probar.

Probé con una versión algo modificada de tu código:

#include <SD.h>
File myFile;
unsigned long contador = 0;

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

  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
}

void loop() {
  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    myFile.print("Contador: ");
    myFile.println(contador++);
    myFile.close();
    //Serial.println("pasada");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

Llegué hasta 1999 (pura coincidencia); y sinceramente no encontré falla alguna.

Parece ser problema de hardware, conexiones flojas o quizá alimentación inadecuada de la tarjeta.
Los 3.3v de dónde provienen? De un regulador o fuente de poder externa? O de la salida 3V3 de la placa Arduino?

Con el pin 4, exactamente mismo problema. Probé de que imprima unos ( : ) antes de la palabra contador y en algunas ocasiones no imprime los : y a veces tampoco la palabra.

Los 3.3 los tengo directamente del arduino.

El modulo de la SD no lo compre, lo hice yo.

Problema de alguna conexión floja, lo descarto porque los pines no tienen ningún tipo de oxido y la falla es muy al azar. En pleno proceso de escritura, si lo muevo tampoco pasa nada.

PD: con tu mismo Sketch, me pasa lo mismo.

diegotala1985:
Los 3.3 los tengo directamente del arduino.

diegotala1985:
PD: con tu mismo Sketch, me pasa lo mismo.

Empiezo a sospechar que el problema esté en la alimentación de la tarjeta.

En especial porque (si no me equivoco), la salida 3V3 de una placa Arduino que normalmente trabaja con 5V, está diseñada para dar ese nivel de voltaje a AREF (voltaje de referencia externo para las entradas analógicas o ADC); y no precisamente para alimentar dispositivos de tal voltaje.

Otra teoría puede ser la inductancia parásita de las resistencias, que en ocasiones puede desatiempar los pulsos de SCK con los de MOSI.
Lo digo porque siempre he tenido la duda de que si hay efectos secundarios al pasar una señal de muy alta frecuencia sobre un resistencia.

Luego de leer varias tarjetas SD y sus consumos, muchas podrían facilmente ser alimentadas con los 3.3V del Arduino pero otras no. Por lo tanto, la sugerencia de Lucario es la mas apropiada para resolver o intentar resolver tu problema.
Busca un regulador 3.3V, lo alimentas conlos 5V del arduino si quieres y posiblemente resuelvas tu problema.

He probado con una fuente externa regulable, a 3.3 v y pasa exactamente lo mismo. Mañana compro un modulo SD y pruebo.

Muchachos, hoy compre el modulo MicroSD y parece estar resuelto este problema de escritura que tenia. Ahora bien....tengo un problema mucho mas extraño. Usando este modulo SD, por algún motivo desestabiliza la lectura analógica del LM35.

Modulo SD CATALEX. http://www.monocilindro.com/tag/catalex-microsd-adapter/

Del segundo 0 al 12 esta con la alimentación de la MicroSD, del segundo 12 al final, sin la alimentación de la SD y se ve como le lectura de la temperatura es mucho mas estable. Si bien puedo modificar el Sketch para obtener un promedio, me gustaría saber porque pasa esto. Es muy extraño y no me puedo quedar con la duda.

Y como presentas la lectura del LM35, la promedias o vas tal como la lees?

En el video que subí, la promedio solo 2 veces (#define MAX_AV_READ 1). Paso el Sketch.
Puede ser largo, pero es muy sencillo en realidad.

#include <LCD.h>
#include <LiquidCrystal_SR.h>
LiquidCrystal_SR lcd(2, 3, 4);
// constructor prototype parameter:
// LiquidCrystal_SR lcd(DataPin, ClockPin, Enable);

#include <SD.h>
File myFile;

#define MAX_AV_READ  1        //n. read for average
const float SUPPLY_VOLTAGE = 500; // 5V * 100 (LM35 costant)
#define tA0  0      //Arduino analog input 0 connect to +out pin
#define tA1  1      //Arduino analog input 1 connect to -out pin
float tC0;          //A0 read temp var
float tC1;          //A1 read temp var
float tCalc;        //var need for calc celsius degrees
#define FCORR 0.9   // only for test if we don't have precision read
                    //because supply voltage is not exactly +5v
int contador;

void setup() {
 analogReference(DEFAULT);  // set voltage reference at default 5.0 V for Arduino 1 
 Serial.begin(9600);        //open serial port at 9600 bps
  lcd.begin(16, 2);
  lcd.print("hello, world!");
  delay(1000);

  Serial.print("Initializing SD card...");
  lcd.clear();
  if (!SD.begin(10)) {
   lcd.print("SDInit.FAILED!");
    return;
  }
  Serial.println("initialization done.");
   lcd.print("SDInit.OK!");

  myFile = SD.open("temp.txt", FILE_WRITE);
  if (myFile) {
    myFile.print("START");
    myFile.close();
    }
 
  }

void loop() {
   lcd.setCursor(0, 1);
int i;
 for(i=0;i<MAX_AV_READ;i++){
    tC0 += analogRead(tA0) ;    //read +out sensor pin
    delay(5);                   //atmega need 10uS delay but we preferr 5mS 
    tC1 += analogRead(tA1) ;    //for full range scale -55 to + 155 C
    }                           //must read -out pin (virtual Vss)
    
  tC0 /=(MAX_AV_READ+1);   //average
  tC1 /=(MAX_AV_READ+1);   //average
  
   tCalc = tC0 - tC1 ;  //subtract virtual ground value
    // now we can calc celsius degrees 
   tCalc = ( tCalc * SUPPLY_VOLTAGE /1024) - FCORR; 
    //only for debug next three line show millVolt out from LM35
//Serial.print(tC0);           //show mV reads at A0 input
//Serial.print(" ");           //print space
//Serial.print(tC1);           //show mV reads at A1 input
//Serial.print(" ");           //print space
//Serial.print("Celsius: ");
Serial.println(tCalc);

    lcd.setCursor(0, 1);
    lcd.print("Celsius: ");
    lcd.print(tCalc);
    //lcd.print("                    ");

  myFile = SD.open("temp.txt", FILE_WRITE);
  if (myFile) {
    myFile.print("Celsius: ");
    myFile.println(tCalc);
    myFile.close();
    //Serial.println("done.");
    }
  else {
    //Serial.println("error opening temp.txt");
    }
    lcd.setCursor(10, 0);
    contador=contador + 1;
    lcd.print(contador);
    delay(200);
}

Estimados, los comparto para tener en cuenta. Con un simple capacitor en el rail de alimentación de 5v, suaviza muchísimo la oscilación. Evidentemente, este modulo mete mucho ruido.

diegotala1985:
Evidentemente, este modulo mete mucho ruido.

Eso, o en realidad son los pulsos de SCK.

Cuando uso mi Arduino como reproductor de archivos WAV, de fondo se escucha un ruido "pulsante" que se sincroniza con el parpadeo del LED L (pin 13); por esta razón es que digo que lo provoca SCK.
Debido a que todo debe compartir una misma línea de tierra, lo único que podría eliminar por completo ese ruido, es aislar las conexiones de señal con optoacopladores.

Lucario, estoy leyendo valores analógicos. La idea de poner optcopladores, seria en la lectura analógica?

Habla de que pongas optos para el módulo SD lo que conlleva a usar otra fuente.