Go Down

Topic: Having some error with saving a new file into SD card (Read 173 times) previous topic - next topic

weifengtoh

Hello everyone,

I am having some problem saving a new file everytime my arduino reboot. I tried using the exact same code below and I manage to save a new file everytime i reboot. For instance, DATA01 ... to DATA18 is save into my SD card. However, when i reach DATA19, the file is not save inside my SD card. The file below is my code. please help! thanks in advance

Code: [Select]


#include "Wire.h" // This library allows you to communicate with I2C devices.
#include <SD.h>
#include <SPI.h>
#include <Time.h>
#define FILE_BASE_NAME "DATA"

File file;
const uint8_t pinCS = 10;
const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
char fileName[] = FILE_BASE_NAME "00.csv";

const int MPU_ADDR = 0x68; // I2C address of the MPU-6050. If AD0 pin is set to HIGH, the I2C address will be 0x69.
int16_t accelerometer_x, accelerometer_y, accelerometer_z; // variables for accelerometer raw data
int16_t gyro_x, gyro_y, gyro_z; // variables for gyro raw data
int16_t temperature; // variables for temperature data
char tmp_str[7]; // temporary variable used in convert function
char* convert_int16_to_str(int16_t i) { // converts int16 to string. Moreover, resulting strings will have the same length in the debug monitor.
  sprintf(tmp_str, "%6d", i);
  return tmp_str;
}

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
  Wire.write(0x6B); // PWR_MGMT_1 register
  Wire.write(0); // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println(" ");
  Serial.println("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(pinCS)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");

  while (SD.exists(fileName)) {
    if (fileName[BASE_NAME_SIZE + 1] != '9') {
      fileName[BASE_NAME_SIZE + 1]++;
    } else if (fileName[BASE_NAME_SIZE] != '9') {
      fileName[BASE_NAME_SIZE + 1] = '0';
      fileName[BASE_NAME_SIZE]++;
    } else {
      Serial.println(F("Can't create file name"));
      return;
    }
  }

  file = SD.open(fileName, FILE_WRITE);
  if (!file) {
    Serial.println(F("open failed"));
    return;
  }
  Serial.print(F("opened: "));
  Serial.println(fileName);
  file.close();

  pinMode(pinCS, OUTPUT);
}

void loop() {
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) [MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2, p.40]
  Wire.endTransmission(false); // the parameter indicates that the Arduino will send a restart. As a result, the connection is kept active.
  Wire.requestFrom(MPU_ADDR, 7 * 2, true); // request a total of 7*2=14 registers

  // "Wire.read()<<8 | Wire.read();" means two registers are read and stored in the same variable
  accelerometer_x = Wire.read() << 8 | Wire.read(); // reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
  accelerometer_y = Wire.read() << 8 | Wire.read(); // reading registers: 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
  accelerometer_z = Wire.read() << 8 | Wire.read(); // reading registers: 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
  temperature = Wire.read() << 8 | Wire.read(); // reading registers: 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)

  // print out data
  Serial.print("aX = "); Serial.print(convert_int16_to_str(accelerometer_x));
  Serial.print(" | aY = "); Serial.print(convert_int16_to_str(accelerometer_y));
  Serial.print(" | aZ = "); Serial.print(convert_int16_to_str(accelerometer_z));
  // the following equation was taken from the documentation [MPU-6000/MPU-6050 Register Map and Description, p.30]
  Serial.print(" | temp = "); Serial.print(temperature / 340.00 + 36.53);
  Serial.println();

  file = SD.open(fileName, FILE_WRITE);

  if (file) {

    file.print (temperature / 340.00 + 36.53);
    file.print (",");
    file.print(convert_int16_to_str(accelerometer_x));
    file.print (",");
    file.print(convert_int16_to_str(accelerometer_y));
    file.print (",");
    file.println (convert_int16_to_str(accelerometer_z));
    file.close();
  }
  else {
    Serial.println ("Error opening test.");
  }
  {
    // delay
    delay(500);
  }
}

Klaus_K

I tested your code and can confirm, it can create files beyond DATA19. Just format your card and place some DATA files on your card and try. If that failes maybe your SD card is broken.

However I noticed some things that might help.

I added a LED ON/OFF around the SD card access and the LED is blinking constantly. It feels like 10% ON 90% OFF. This could mean when you reset your MCU you have a chance of corrupting the SD card.

Your code only works till DATA99.

Every time you reboot the process of creating a file gets slower, because it runs trough all possible filenames.

You included the time library, if you have date and time you could just create a new filename based on that. Then you only need to do one test, before creating a new file.

I think SD card do not like constant writing of small amounts fo data. They where created for larger blocks (photos, music files, ...). Maybe it worthwhile to collect the data and only write every minute. This would also reduce the risk of damaging the card when you reset your system.

Hope this helps.

Go Up