Go Down

Topic: SD Card not opening after a few file writes (Read 365 times) previous topic - next topic

stueck9356

Jul 21, 2019, 11:22 pm Last Edit: Jul 21, 2019, 11:23 pm by stueck9356
I have a school project and I'm having trouble writing data to an SD card. I am using a blue robotics bar30 pressure/temperature sensor and writing its data to an SD card. I have the arduino capturing sensor data at 100ms intervals, and writing the data to the SD card every 10 seconds. Then, at 5 minute intervals the arduino creates a new file and begins the process over. The new file procedure is so that when we turn the device off (literally disconnecting the battery) the risk of corrupting a file is lowered (we will only lose data of the last 5 mins of the test at worst).

The issue is we can get about 4-5 files written before the arduino fails to 'sd.open' the file. I don't know what the issue is, maybe the arduino is not flushing old data from its internal memory and its filling up? I am a beginner at the arduino and code so any help is appreciated!

BTW, the SD card is a 64 GB microSD, I've formatted it to a single 1 GB partition as FAT and left the rest of it unpartitioned.

Code: [Select]

// Include necessary libraries for SD and BAR30 sensor
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "MS5837.h"

MS5837 sensor; // initialize sensor

//Timers for recording data
unsigned long currentMillis = 0;    // current time
unsigned long fileMillis = 0;       // timer for file saving
unsigned long SDMillis = 0;         // timer for writing to SD
unsigned long sensorMillis = 0;     // timer for polling sensor

char fileName[] = "DATA_01.CSV";  // filename format used for logging
byte fileNameidx = 1;             // filename index
int SDpwr = 9;                    // 5v pin for SD card
const int buzzer = 6;             // buzzer
int buzzerGND = 7;                // ground pin for buzzer
File Testing;                     // referenced file

void setup() {
  // apply 5v power to SD card
  pinMode(SDpwr,OUTPUT);
  digitalWrite(SDpwr,HIGH);
  pinMode(buzzerGND,OUTPUT);
  digitalWrite(buzzerGND,LOW);

  delay(500);         // wait 500 ms for everything to boot up
 
  Serial.begin(9600); // initialize serial monitor
 
  SD.begin(10);               // initialize SD card
  while (!SD.begin(10)) {     // Failure warnings for SD
    Serial.println("SD Card initilization failed");
    for (int b=1; b<=2; b++){
      tone(buzzer,5000);
      delay(300);
      noTone(buzzer);
      delay(300);
    }
  }

  Wire.begin();             // initialize i2c board
  sensor.init();            // initialize sensor
  while (!sensor.init()) {  // failure warnings for sensor
    Serial.println("Sensor initilization failed");
    for (int b=1; b<=3; b++){
      tone(buzzer,5000);
      delay(300);
      noTone(buzzer);
      delay(300);
    }
    delay(1000);
  }
 
  sensor.setModel(MS5837::MS5837_30BA);   // define sensor type
  sensor.setFluidDensity(997);            // define density of fluid

  // Check for files stored on SD card. iterates file number until a new file is created.
  // saves us from overwriting older files even after a full power-down of the uno.
  while (SD.exists(fileName)) {
    // the filename exists so increment the 2 digit filename index.
    Serial.println("file name exists, updating.");
    fileNameidx++;
    fileName[5] = fileNameidx/10 + '0';
    fileName[6] = fileNameidx%10 + '0';
  }

  // Successful initialization of all hardware, ready to record
  Serial.println("Initialization Success");
  for (int b=1; b<=3; b++){
    tone(buzzer,3000+b*1500);
    delay(200);
  }
  noTone(buzzer);
  delay(250);
}

void loop() {
  // serial print current filename
  Serial.print("File name updated to ");
  Serial.println(fileName);
 
  // buzzer sound for new file starting
  tone(buzzer,5000);
  delay(300);
  noTone(buzzer);

  // open file on SD card
  Testing = SD.open(fileName, FILE_WRITE);

  // if opening SD card fails, sound buzzer and try to open SD card again
  while (!Testing) {
    tone(buzzer,5000);
    delay(150);
    noTone(buzzer);
    delay(150);
    Testing = SD.open(fileName, FILE_WRITE);
  }

  // write header to file, reset all timers to zero
  if (Testing) {
    Testing.println("Time [ms],Pressure [mbar],Temperature [C],Depth [m],Altitude [m ASL]");
    currentMillis = millis();
    fileMillis = currentMillis;
    SDMillis = currentMillis;
    sensorMillis = currentMillis;
    Serial.println("File Opened Successfully");
  }

  // The uno will collect sensor data at given intervals, collect the data to onboard RAM
  // then save it to the SD card at regular intervals. It will do this for a set length
  // then close the file completely, and start a new file. This reduces file corruption
  // risk when the uno is suddenly shut down.
 
  Serial.println("Recording Data...");
  while (currentMillis-fileMillis <= 300000) { // individual files will record for this length
    currentMillis = millis();
   
    if (currentMillis-SDMillis >= 10000) {     // save collected data to SD card at this interval
     Testing.close();
     Testing = SD.open(fileName, FILE_WRITE);
     SDMillis = currentMillis;
    }
   
    if (currentMillis-sensorMillis >=100) {     // poll sensor data at this interval
      // Update pressure and temperature readings
      sensor.read();
      Testing.print(currentMillis);
      Testing.print(',');
      Testing.print(sensor.pressure());
      Testing.print(',');
      Testing.print(sensor.temperature());
      Testing.print(',');
      Testing.print(sensor.depth());
      Testing.print(',');
      Testing.println(sensor.altitude());
      sensorMillis = currentMillis;
    }
  }
  Testing.close();  // close file
  Serial.println("File closed Successfully");
  Serial.println();

  //iterate file name index for next loop.
  fileNameidx++;
  fileName[5] = fileNameidx/10 + '0';
  fileName[6] = fileNameidx%10 + '0';
}

wildbill

When you open a file, there is a memory allocation of a 500 (or is it 512?)  byte buffer that occurs behind the scenes. It should be released when you close the file. Four successful opens suggests that you may be running out of memory. Grab the freemem function and use it to see if that is so.

The only place I can see a possibility of that happening is if the initial open fails and you try to open it again - do you see an open failure when it runs?

Go Up