Problems writing to SD Card



  • Has anyone else had issues writing to SD on the stack? I can place a file on an sd card and the read the directory and read the file. I can read files that were previously written to the card manually, but writing has been a challenge. I constructed this simple example to test writing and it fails every time. I'm not sure what im doing wrong? (I used to have code to initialize the card, using the proper CS pin but have seen from other examples that it wasn't necesssary on the stack. Writing didn't work for me either way)

    #include <M5Stack.h>
    
    void setup() {
    
      M5.begin();
    
      Serial.begin(9600);
    
      char filename[] = "LOGGER00.CSV";
    
      File logfile = SD.open(filename, FILE_WRITE); 
      logfile.close();
    
      if (SD.exists(filename)) {
        Serial.println("LOGGER00.CSV exists.");
      } else {
        Serial.println("LOGGER00.CSV doesn't exist.");
      }
    
    
    }
    
    
    void loop() {
     M5.update();
    }


  • @vsthose Hi Vsthose,

    The following code should work provided you use a Micro SD / TF card that only has a few files on it.... too many and the display will run off the screen and you won't see the write to card and read back.

    
    #include <M5Stack.h>
     
    //Micro SD / TF Card Test
    
    void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    
        // Print blank line on screen
        M5.Lcd.printf(" \n  ");
        M5.Lcd.printf(" \n  ");
        
        Serial.printf("Listing directory: %s\n", dirname);
        M5.Lcd.printf("Listing directory: %s\n", dirname);
    
        File root = fs.open(dirname);
        if(!root){
            Serial.println("Failed to open directory");
            M5.Lcd.println("Failed to open directory");
            return;
        }
        if(!root.isDirectory()){
            Serial.println("Not a directory");
            M5.Lcd.println("Not a directory");
            return;
        }
    
        File file = root.openNextFile();
        while(file){
            if(file.isDirectory()){
                Serial.print("  DIR : ");
                M5.Lcd.print("  DIR : ");
                Serial.println(file.name());
                M5.Lcd.println(file.name());
                if(levels){
                    listDir(fs, file.name(), levels -1);
                }
            } else {
                Serial.print("  FILE: ");
                M5.Lcd.print("  FILE: ");
                Serial.print(file.name());
                M5.Lcd.print(file.name());
                Serial.print("  SIZE: ");
                M5.Lcd.print("  SIZE: ");
                Serial.println(file.size());
                M5.Lcd.println(file.size());
            }
            file = root.openNextFile();
        }
    }
    
    void readFile(fs::FS &fs, const char * path) {
        Serial.printf("Reading file: %s\n", path);
        M5.Lcd.printf("Reading file: %s\n", path);
    
        File file = fs.open(path);
        if(!file){
            Serial.println("Failed to open file for reading");
            M5.Lcd.println("Failed to open file for reading");
            return;
        }
    
        Serial.print("Read from file: ");
        M5.Lcd.print("Read from file: ");
        while(file.available()){
            int ch = file.read();
            Serial.write(ch);
            M5.Lcd.write(ch);
        }
    }
    
    void writeFile(fs::FS &fs, const char * path, const char * message){
        Serial.printf("Writing file: %s\n", path);
        M5.Lcd.printf("Writing file: %s\n", path);
    
        File file = fs.open(path, FILE_WRITE);
        if(!file){
            Serial.println("Failed to open file for writing");
            M5.Lcd.println("Failed to open file for writing");
            return;
        }
        if(file.print(message)){
            Serial.println("File written");
            M5.Lcd.println("File written");
        } else {
            Serial.println("Write failed");
            M5.Lcd.println("Write failed");
        }
    }
    
    // the setup routine runs once when M5Stack starts up
    
    void setup() { 
     
        // initialize the M5Stack object
        M5.begin();
    
        M5.startupLogo();
        Wire.begin();
    
        // Lcd display
        M5.Lcd.setBrightness(100);
        M5.Lcd.fillScreen(BLACK);
        M5.Lcd.setCursor(0, 10);
        M5.Lcd.setTextColor(WHITE);
        M5.Lcd.setTextSize(1);
    
        // Page Header
        M5.Lcd.fillScreen(BLACK);
        M5.Lcd.setCursor(0, 05);
        M5.Lcd.printf("           Testing Micro SD Card Functions:\r\n");
        // digitalWrite(TFT_CS, 1);
     
        // Print blank line on screen
        M5.Lcd.printf(" \n    ");
        M5.Lcd.printf(" \n    ");
        
        listDir(SD, "/", 0);
        M5.Lcd.printf("");
        M5.Lcd.printf("");
    
        // Print blank line on screen
        M5.Lcd.printf(" \n  ");
        M5.Lcd.printf(" \n  ");
        
        writeFile(SD, "/hello.txt", "Hello world from M5Stack !!");
        M5.Lcd.printf("");
        M5.Lcd.printf("");
    
        // Print blank line on screen
        M5.Lcd.printf(" \n  ");
        M5.Lcd.printf(" \n  ");
    
        // Print blank line on screen
        M5.Lcd.printf(" \n  ");
        M5.Lcd.printf(" \n  ");
        
        readFile(SD, "/hello.txt");
    }
    
    void loop() {
    
      // put your main code here, to run repeatedly:
       
        M5.update();
    }


  • Thank you!

    I had started with those functions, but my function that retrieved data from the serial port was sending back a string and all these SD card functions require a Const Char * and I didn't have the skills yet to compensate.

    Ultimately, it came down to the path. I was using "\filename.ext" and the SD card functions require "/filename.ext." Instead of giving me a nice soft error message like "bad file path" or something, it just compiles and does nothing.

    I caught the difference when I was comparing your code to mine. Thanks for the assistance!



  • @vsthose No problem ! Would be great if the Arduino IDE could identify tiny errors like this.... We wait !



  • Thank you ! It helps !



  • @imro

    Hi Imro, no problem... glad it helped.

    That code is taken from the FactoryTest example that is part of the M5Stack library....

    The code in the examples is a useful source for learning how to make things happen on the M5Stack.



  • @jj said in Problems writing to SD Card:

    @vsthose Hi Vsthose,

    The following code should work provided you use a Micro SD / TF card that only has a few files on it.... too many and the display will run off the screen and you won't see the write to card and read back.

    
    #include <M5Stack.h>
     
    //Micro SD / TF Card Test
    
    void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    
        // Print blank line on screen
        M5.Lcd.printf(" \n  ");
        M5.Lcd.printf(" \n  ");
        
        Serial.printf("Listing directory: %s\n", dirname);
        M5.Lcd.printf("Listing directory: %s\n", dirname);
    
        File root = fs.open(dirname);
        if(!root){
            Serial.println("Failed to open directory");
            M5.Lcd.println("Failed to open directory");
            return;
        }
        if(!root.isDirectory()){
            Serial.println("Not a directory");
            M5.Lcd.println("Not a directory");
            return;
        }
    
        File file = root.openNextFile();
        while(file){
            if(file.isDirectory()){
                Serial.print("  DIR : ");
                M5.Lcd.print("  DIR : ");
                Serial.println(file.name());
                M5.Lcd.println(file.name());
                if(levels){
                    listDir(fs, file.name(), levels -1);
                }
            } else {
                Serial.print("  FILE: ");
                M5.Lcd.print("  FILE: ");
                Serial.print(file.name());
                M5.Lcd.print(file.name());
                Serial.print("  SIZE: ");
                M5.Lcd.print("  SIZE: ");
                Serial.println(file.size());
                M5.Lcd.println(file.size());
            }
            file = root.openNextFile();
        }
    }
    
    void readFile(fs::FS &fs, const char * path) {
        Serial.printf("Reading file: %s\n", path);
        M5.Lcd.printf("Reading file: %s\n", path);
    
        File file = fs.open(path);
        if(!file){
            Serial.println("Failed to open file for reading");
            M5.Lcd.println("Failed to open file for reading");
            return;
        }
    
        Serial.print("Read from file: ");
        M5.Lcd.print("Read from file: ");
        while(file.available()){
            int ch = file.read();
            Serial.write(ch);
            M5.Lcd.write(ch);
        }
    }
    
    void writeFile(fs::FS &fs, const char * path, const char * message){
        Serial.printf("Writing file: %s\n", path);
        M5.Lcd.printf("Writing file: %s\n", path);
    
        File file = fs.open(path, FILE_WRITE);
        if(!file){
            Serial.println("Failed to open file for writing");
            M5.Lcd.println("Failed to open file for writing");
            return;
        }
        if(file.print(message)){
            Serial.println("File written");
            M5.Lcd.println("File written");
        } else {
            Serial.println("Write failed");
            M5.Lcd.println("Write failed");
        }
    }
    
    // the setup routine runs once when M5Stack starts up
    
    void setup() { 
     
        // initialize the M5Stack object
        M5.begin();
    
        M5.startupLogo();
        Wire.begin();
    
        // Lcd display
        M5.Lcd.setBrightness(100);
        M5.Lcd.fillScreen(BLACK);
        M5.Lcd.setCursor(0, 10);
        M5.Lcd.setTextColor(WHITE);
        M5.Lcd.setTextSize(1);
    
        // Page Header
        M5.Lcd.fillScreen(BLACK);
        M5.Lcd.setCursor(0, 05);
        M5.Lcd.printf("           Testing Micro SD Card Functions:\r\n");
        // digitalWrite(TFT_CS, 1);
     
        // Print blank line on screen
        M5.Lcd.printf(" \n    ");
        M5.Lcd.printf(" \n    ");
        
        listDir(SD, "/", 0);
        M5.Lcd.printf("");
        M5.Lcd.printf("");
    
        // Print blank line on screen
        M5.Lcd.printf(" \n  ");
        M5.Lcd.printf(" \n  ");
        
        writeFile(SD, "/hello.txt", "Hello world from M5Stack !!");
        M5.Lcd.printf("");
        M5.Lcd.printf("");
    
        // Print blank line on screen
        M5.Lcd.printf(" \n  ");
        M5.Lcd.printf(" \n  ");
    
        // Print blank line on screen
        M5.Lcd.printf(" \n  ");
        M5.Lcd.printf(" \n  ");
        
        readFile(SD, "/hello.txt");
    }
    
    void loop() {
    
      // put your main code here, to run repeatedly:
       
        M5.update();
    }
    

    I tested the example. unfortunately it doesn't work for me. there are no folders or many other files on the card. what am I doing wrong?

    rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0030,len:1344
    load:0x40078000,len:13516
    load:0x40080400,len:3604
    entry 0x400805f0
    M5Stack initializing...OK
    Listing directory: /
    Failed to open directory
    Writing file: /hello.txt
    Failed to open file for writing
    Reading file: /hello.txt
    Failed to open file for reading



  • I tried it on my M5Stack Core with a SanDisk 32GB Fat32 and a Noname 4GB Fat32. Even repeated formatting did not lead to success. Do you have another tip for me?



  • A third, newly ordered sd card works now. 👍It is a Verbatin 16Gb Premium microSDHC. The m5stack seems to be pretty picky?!



  • @stoni99 , yes, I have the same issue with my "picky" M5Stack. Samsung 64GB EVO plus XC Speedclass 3 are working fine, but I can no longer find it on Amazon. Sometimes Sundisk 32GB V30 are working, but in the next insert they refuse to work. Is it really the card or the software?