Skip to content

SD_MMC problem #1169

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
magnuskarlsson opened this issue Mar 4, 2018 · 11 comments
Closed

SD_MMC problem #1169

magnuskarlsson opened this issue Mar 4, 2018 · 11 comments

Comments

@magnuskarlsson
Copy link

Hardware:

Board: ESP Wroom-32

Description:

I want to setup the sd-card and open a file for writing in setup(), then write to the file in loop() using a global file handle, but this does not work.
In the sketch below, if I declare file as a global variable then nothing gets written to the sd-card in setup(), while if I declare file locally in setup() then the data is written as expected. In other words, the code below will result in an empty file hello.txt since file is declared as a global, but if I comment out the global file declaration and instead use the local file declaration in setup() then the file hello.txt has 10 lines of data as expected.

BTW, the sketch SD_MMC works fine so it's not a hardware problem.

Sketch:

#include "FS.h"
#include "SD_MMC.h"

File file;

void setup(){
    int i;
//    File file;
    Serial.begin(115200);
    if(!SD_MMC.begin()){
        Serial.println("Card Mount Failed");
        return;
    }
    uint8_t cardType = SD_MMC.cardType();

    if(cardType == CARD_NONE){
        Serial.println("No SD_MMC card attached");
        return;
    }

    Serial.print("SD_MMC Card Type: ");
    if(cardType == CARD_MMC){
        Serial.println("MMC");
    } else if(cardType == CARD_SD){
        Serial.println("SDSC");
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
    } else {
        Serial.println("UNKNOWN");
    }

    uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024);
    Serial.printf("SD_MMC Card Size: %lluMB\r\n", cardSize);

    file = SD_MMC.open("/hello.txt", FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }
    for (i=0; i<10; i++) {
      if(file.print("Hello ***\r\n")){
          Serial.println("File written");
      } else {
          Serial.println("Write failed");
      }
      file.flush();
      delay(1000);
    }

}

void loop(){

}
@ghost
Copy link

ghost commented Mar 4, 2018

If "File file" is a C++ class, it will be deconstructed at the end of the function when it goes out of scope when it's a local variable, that will close the file and ensure all data is written. When it's a global variable, that doesn't appear to be done here anywhere, and would be required if you want it to work. flush() probably doesn't do anything (but I didn't look).

@magnuskarlsson
Copy link
Author

That makes sense. The system is logging data @10 Hz and once the file is opened it will keep on writing data and flush it for every chunk of data being logged, but it will never close the file. The code has been ported from Teensy where SD.flush() works but I guess SD_MMC.flush() as you say don't do anything, which is the real problem. I hate to keep on closing and opening the file every time I need to add data.

@ghost
Copy link

ghost commented Mar 4, 2018

That's a tough situation, eventually you will want to read the SD card and it would be best if it had all the data written at the time you power down the MCU to remove the SD card. The only thing I can think of is, check the current millis() time in loop() and close/re-open the file every 2~5 seconds instead of 10 times a second.

The trouble with flush() is, you will wear out the SD card much more quickly with their limited writes before failure (even with write levelling).

@magnuskarlsson
Copy link
Author

I'm not really concerned about wear, the logging happens infrequent (at the most several times a day) and will last for less than 10 min and the code works great on Teensy3.6. esp32 would be a great way to save money ($29 vs. $6) but the lack of SD_MMC.flush() working would be a problem. I think the solution of closing the file now and then might work (I have to test it) but in my opinion it's a pretty bad hack.

@magnuskarlsson
Copy link
Author

Also, someone reported a memory leak every time a file is closed and opened....

@ghost
Copy link

ghost commented Mar 4, 2018

I thought that issue was with the SD subsystem being started and ended.

Anyway, in terms of SD card accesses, I doubt there's much difference between flush() and close()+open(). I wouldn't worry about it, if wear isn't a concern.

Anyway, I have other issues with my ESP32, which is why I'm visiting here..

@magnuskarlsson
Copy link
Author

I understand and appreciate you helping out. I will try your solution of close() + open() instead of flush().

@ghost
Copy link

ghost commented Mar 4, 2018

No problem, and good luck with it.

@ghost
Copy link

ghost commented Mar 4, 2018

Actually, one last thought, with that use-case I would change the algorithm slightly... Open the file when needed for any log output, but close it after ~10-30 seconds of inactivity by testing in loop().

@magnuskarlsson
Copy link
Author

Sure, but there is no inactivity, part of the data is GPS data stream @ 10Hz.

@magnuskarlsson
Copy link
Author

I will close this issue and open a new issue with the real problem (SD_MMC.flush() wont sync the file).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant