cancel
Showing results for 
Search instead for 
Did you mean: 

stm32duino STM32SD library append

Driadix
Associate

Im using STM32SD library on my stm32f407vet6 board.  I want to make a logging system for my application. My initial logic is: on setup we count number of files in our root directory and create a new file named dataLog{fileNumber}. Then we write data into that file and check if its not empty. In given code example im always getting only last write into file (fouth write). As ive got this library only works in FILE_WRITE or FILE_READ modes. I trtied to use FA_OPEN_APPEND modifier but when im using this im getting errors while file creating.
And another thing is that im always getting a lot of initialization errors and file open errors overall while using this library, maybe it depends on me using stm32f407vet6, any advices would be great. Now i will try to use an advice from github issue of "unstable work with sdcard on stm32f4" - i'll try to redefine the value of the SD_CLK_DIV to bigger value.

 

 

 

 

 

#include <STM32SD.h>

int fileNumber = 0;
const int maxRetries = 5;

void initializeSDCard() {
  Serial.print("Initializing SD card...");
  int retryCount = 0;

  while (!SD.begin() && retryCount < maxRetries) {
    Serial.println("Initialization failed! Retrying...");
    delay(1000);
    retryCount++;
  }

  if (retryCount >= maxRetries) {
    Serial.println("Initialization failed after maximum retries. Halting.");
    while (true) {
      delay(1000);
    }
  } else {
    Serial.println("Initialization done.");
  }
}

void getNewFileName(char *fileName) {
  File root = SD.open("/");
  while (true) {
    File entry = root.openNextFile();
    if (!entry) {
      break;
    }
    fileNumber++;
    entry.close();
  }
  root.close();

  sprintf(fileName, "dataLog%d.txt", fileNumber + 1);
}

bool writeToFile(const char *fileName) {
  File dataFile = SD.open(fileName, FILE_WRITE);
  Serial.println(String(dataFile.getErrorstate()));
  if (dataFile) {
    Serial.printf("Writing to %s...\n", fileName);

    for (int i = 0; i < 3000; i++) {
      dataFile.println("This is line " + String(i + 1));
    }

    dataFile.flush();
    dataFile.close();
    delay(10);
    dataFile = SD.open(fileName);
    if (dataFile) {
      size_t fileSize = dataFile.size();
      dataFile.close();
      if (fileSize > 0) {
        Serial.printf("Data successfully written to %s (size: %d bytes)\n", fileName, fileSize);
        return true;
      } else {
        Serial.printf("File %s is empty after writing. Retrying...\n", fileName);
      }
    } else {
      Serial.printf("Error reopening %s to verify write\n", fileName);
    }
  } else {
    Serial.printf("Error opening %s for writing\n", fileName);
  }

  int retryCount = 0;
  while (!SD.begin() && retryCount < maxRetries) {
    Serial.println("Reinitializing SD card... Retrying...");
    delay(1000);
    retryCount++;
  }

  if (retryCount >= maxRetries) {
    Serial.println("Reinitialization failed after maximum retries.");
    return false;
  } else {
    Serial.println("Reinitialization successful.");
    return writeToFile(fileName);
  }
}

bool writeToFile1(const char *fileName)
{
  File dataFile = SD.open(fileName, FILE_WRITE);
   if (dataFile) {
    Serial.printf("Writing to %s...\n", fileName);
    dataFile.println("First write");
    for (int i = 0; i < 200; i++) {
      dataFile.println("This is line " + String(i + 1));
    }
    dataFile.println("----------------");
   }
   dataFile.flush();
   dataFile.close();
   delay(1);

   dataFile = SD.open(fileName, FILE_WRITE);
   if (dataFile) {
    Serial.printf("Writing to %s...\n", fileName);
    dataFile.println("Second write");
    for (int i = 0; i < 200; i++) {
      dataFile.println("This is line " + String(i + 1));
    }
    dataFile.println("----------------");
   }
   dataFile.flush();
   dataFile.close();
   delay(1);

   dataFile = SD.open(fileName, FILE_WRITE);
   if (dataFile) {
    Serial.printf("Writing to %s...\n", fileName);
    dataFile.println("Third write");
    for (int i = 0; i < 200; i++) {
      dataFile.println("This is line " + String(i + 1));
    }
    dataFile.println("----------------");
   }
   dataFile.flush();
   dataFile.close();
   delay(1);

   dataFile = SD.open(fileName, FILE_WRITE);
   if (dataFile) {
    Serial.printf("Writing to %s...\n", fileName);
    dataFile.println("Fourth write");
    for (int i = 0; i < 200; i++) {
      dataFile.println("This is line " + String(i + 1));
    }
    dataFile.println("----------------");
   }
   dataFile.flush();
   dataFile.close();
   delay(1);

}

void readFromFile(const char *fileName) {
  File dataFile = SD.open(fileName);

  if (dataFile) {
    Serial.printf("Reading %s...\n", fileName);

    while (dataFile.available()) {
      Serial.write(dataFile.read());
    }

    dataFile.close();
    Serial.printf("Data successfully read from %s\n", fileName);
  } else {
    Serial.printf("Error opening %s for reading\n", fileName);
  }
}

void setup() {
  Serial.begin(115200);
  while (!Serial) {
    ;
  }

  initializeSDCard();

  char fileName[20];
  getNewFileName(fileName);
  
  while (!writeToFile1(fileName)) {
    delay(500);
  }

  readFromFile(fileName);
}

void loop() {
}

 

 

 

 

 

 

5 REPLIES 5
SHs
ST Employee

Hello @Driadix ,

I suspect that the file system may not be mounted correctly, as I did not see the f_mount() function in the provided code. It sounds like there are potential problems with file system mounting and SD card initialization.

Could you please ensure file system is mounted using f_mount() function? This function is crucial for initializing the file system, so kindly include it in your setup code.

 

BRs,

 

Please close this topic by clicking on “Accept as solution" button if it fully answered your question.
UnderGnd
ST Employee

Hi @Driadix 

You should file an issue on the library:

https://github.com/stm32duino/STM32SD/issues

 

BR

https://github.com/stm32duino
lockie555
Associate

I am having the same issue using the STM32SD library with the SDIO interface for SD cards on a Sparkfun ThingPlus STM32F405 board. I am finding that FILE_WRITE is not appending the data, but overwriting it instead. If I use the File.seek( myFile.size()) construct to get to the end of the file, then data is appended correctly.

However after approx 10,000,000 lines of data I find my logging speed has reduced significantly.

I am running another Sparkfun Micromod STM32F405 logger using SD.h library with the SPI interface in parallel, and it has no issues with FILE_WRITE, and consequently is not losing speed as it does not use the File.seek( myFile.size()) construct to get to the end of the file. Is there a solution for this problem. AI seems to think FILE_WRITE will append data when using STM32SD library.

I don't know the STM32SD library, but as with many Arduino libraries, there might be a quality issue.
Usual file systems have a sync mechanism to force read/write buffer synchronisation with the medium. This would be fsync() in the POSIX standard C library, or f_sync() in FatFS.
At first glance, nothing like that seems to be implemented in this library, at least not on user/API level.

Andrew Neil
Super User

The best place to ask stm32duino questions is in the dedicated forum: https://www.stm32duino.com/

You could also try the general Arduino forums: https://forum.arduino.cc/

See also: https://docs.arduino.cc/libraries/stm32duino-examples/

 

This forum is focussed on "traditional" workflow - like STM32CubeIDE.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.