SD_Test problems

thanks @Baozhu, the SD was of the compatible type but you were right, changing SD was all right :smile:

Hi @hasen, forgive my little experience but I’m going crazy trying to read a json configuration file from SD and store it in the flash to use it on boot. I started from your TestSD example but I can’t manage reading from SD and writing to Flash at the same time. I regularly perform the operations one at a time but only by changing the #define USESPIFLASH header macros. Do you happen to have an example that can solve my problem?
I would be very grateful to you.
Thank you

@ Hansen
hello,
I used exactly your code example from post at 27 May.
And this is the only code working. None of the others (including the codes you mentioned from Github) works with mount fail message.
Card formatted as fat32
But your code works only partially. Below is the program output:

Card Size: 3819MB
Listing directory: /
Not a directory
Creating Dir: /mydir
mkdir failed
Listing directory: /
Not a directory
Removing Dir: /mydir
Dir removed
Listing directory: /
Not a directory
Writing file: /hello.txt
File written
0
Appending to file: /hello.txt
Message appended
0
Reading Dir: /hello.txt
Read from file: Hello World!
0
Deleting file: /foo.txt
File deleted
Renaming file /hello.txt to /foo.txt
File renamed
Reading Dir: /foo.txt
Read from file: Hello World!
0
13 bytes read for 1606 ns
0
Total space:3807MB
Used space: 0MB

What could be done?

I rewrite the example for more compact output and made it run in cycle.
It works with the following issues:

  1. listDir never works

  2. After approximately 30 cycles, the output stops for about a minute, then cycles
    continue but none of operation completed successfully. To restore normal operation power off/on needed.

     #include <Seeed_FS.h>
     #include "SD/Seeed_SD.h"
    

    int cycles;

     void listDir(fs::FS &fs, const char *dirname, uint8_t levels) {
         Serial.printf("Listing directory: %s\n\r", dirname);
    
         File root = fs.open(dirname);
         if (!root) {
             Serial.println(" Failed to open directory");
             return;
         }
         if (!root.isDirectory()) {
             Serial.println(" Not a directory");
             return;
         }
    
         File file = root.openNextFile();
         while (file) {
             if (file.isDirectory()) {
                 Serial.printf("  DIR : %s\n\r",file.name());
                 if (levels) {
                     listDir(fs, file.name(), levels - 1);
                 }
             } else {
                 Serial.printf("  FILE: %s  SIZE: %s\n\r",file.name(), file.size());
             }
             file = root.openNextFile();
         }
     }
    
     void createDir(fs::FS& fs, const char* path) {
         Serial.printf("Creating Dir: %s", path);
         if (fs.mkdir(path)) {
             Serial.println(" Dir created");
         } else {
             Serial.println(" mkdir failed");
         }
     }
    
     void removeDir(fs::FS& fs, const char* path) {
         Serial.printf("Removing Dir: %s", path);
         if (fs.rmdir(path)) {
             Serial.println(" Dir removed");
         } else {
             Serial.println(" rmdir failed");
         }
     }
    
     void readFile(fs::FS& fs, const char* path) {
         Serial.printf("Reading File: %s ", path);
         File file = fs.open(path);
         if (!file) {
             Serial.println("Failed to open file for reading");
             return;
         }
    
         Serial.print("Read from file: ");
         while (file.available()) {
             Serial.write(file.read());
         }
         file.close();
     }
    
     void writeFile(fs::FS& fs, const char* path, const char* message) {
         Serial.printf("Writing file: %s", path);
         File file = fs.open(path, FILE_WRITE);
         if (!file) {
             Serial.println(" Failed to open file for writing");
             return;
         }
         
         if (file.print(message)) {
             Serial.println(" File written");
         } else {
             Serial.println(" Write failed");
         }
         file.close();
     }
    
     void appendFile(fs::FS& fs, const char* path, const char* message) {
         Serial.printf("Appending to file: %s", path);
    
         File file = fs.open(path, FILE_APPEND);
         if (!file) {
             Serial.println(" Failed to open file for appending");
             return;
         }
         if (file.print(message)) {
             Serial.println(" Message appended");
         } else {
             Serial.println(" Append failed");
         }
         file.close();
     }
    
     void renameFile(fs::FS& fs, const char* path1, const char* path2) {
         Serial.printf("Renaming file: %s to %s ", path1, path2);
         if (fs.rename(path1, path2)) {
             Serial.println(" File renamed");
         } else {
             Serial.println(" Rename failed");
         }
     }
    
     void deleteFile(fs::FS& fs, const char* path) {
         Serial.printf("Deleting file: %s ", path);
         if (fs.remove(path)) {
             Serial.println(" File deleted");
         } else {
             Serial.println(" Delete failed");
         }
     }
    
     void testFileIO(fs::FS& fs, const char* path) {
         File file = fs.open(path);
         static uint8_t buf[512];
         size_t len = 0;
         uint32_t start = micros();
         uint32_t end = start;
         if (file) {
             len = file.size();
             size_t flen = len;
             start = micros();
             while (len) {
                 size_t toRead = len;
                 if (toRead > 512) {
                     toRead = 512;
                 }
                 file.read(buf, toRead);
                 len -= toRead;
             }
             end = micros() - start;
             Serial.printf("%d bytes read for %d us\n\r", flen, end);
             file.close();
         } else {
             Serial.println("Failed to open file for reading");
         }
     }
    
     void setup() {
         Serial.begin(115200);
    

// pinMode(5, OUTPUT); // Do not know what for
// digitalWrite(5, HIGH);
while (!Serial) {};

        while (!SD.begin(SDCARD_SS_PIN, SDCARD_SPI, 4000000UL)) {
            Serial.println("Card Mount Failed");
			delay(1000);
        }
    }

    void loop() {
		test();
		cycles++;
		Serial.printf("Cycles %d\n\r", cycles);
		delay(1000);
    }
	
	void test() {

		uint8_t cardType = SD.cardType();
		Serial.printf("Card type: %d\n\r", cardType);
		if (cardType == CARD_NONE) {
			Serial.println("No SD card attached");
			return;
		}

		uint64_t cardSize = SD.cardSize() / (1024 * 1024);
		Serial.print("SD Card Size: ");
		Serial.print((uint32_t)cardSize);
		Serial.println("MB");

		listDir(SD, "/", 0);
		createDir(SD, "/mydir");	// Dir created		OK
		//listDir(SD, "/", 0);		// Not a directory
		removeDir(SD, "/mydir");
		//listDir(SD, "/", 2);
		writeFile(SD, "/hello.txt", "Hello ");
		appendFile(SD, "/hello.txt", "World!\n");
		readFile(SD, "/hello.txt");
		deleteFile(SD, "/foo.txt");
		renameFile(SD, "/hello.txt", "/foo.txt");
		readFile(SD, "/foo.txt");
		testFileIO(SD, "/foo.txt");
		uint32_t totalBytes = SD.totalBytes();
		Serial.printf("Total space: %d MB ", totalBytes / (1024 * 1024));
		uint32_t usedBytes = SD.usedBytes();
		Serial.printf("Used space: %d MB\n\r", usedBytes / (1024 * 1024));

}

Output:

Card type: 3
SD Card Size: 15200MB
Listing directory: /
Not a directory
Creating Dir: /mydir Dir created
Removing Dir: /mydir Dir removed
Writing file: /hello.txt File written
0
Appending to file: /hello.txt Message appended
0
Reading File: /hello.txt Read from file: Hello World!
0
Deleting file: /foo.txt File deleted
Renaming file: /hello.txt to /foo.txt File renamed
Reading File: /foo.txt Read from file: Hello World!
0
13 bytes read for 1383 us
0
Total space: 2898 MB Used space: 2 MB

Hi @Gianfry60:
there exist a demo that creates multi-partition by using flash and sd card in our github.

OK. It works with master release and I used 1.1.0

What does Pin 5 used for?

Hi @Hansen, I’m having problems writing two files consecutively on the Flash, If I run the sequences one at a time everything goes well, if I execute them consecutively the second writing corrupts the first file. The sequence consists of deleting the file and writing the new file. Do you have any idea where the problem might be? I’ll post the code part.
I will be grateful if you can help me

void deleteFile(fs::FS &fs, const char *pathD)
{
DPRINT("Deleting file: ");
DPRINTLN(pathD);
if (fs.remove(pathD))
{
DPRINTLN(“File deleted”);
}
else
{
DPRINTLN(“Delete failed”);
}
delay(500);
}

void writeFile(fs::FS &fs, const char *pathF, const char *message)
{
DPRINT("Writing file: ");
DPRINTLN(pathF);
File fileF = fs.open(pathF, FILE_WRITE);
if (!fileF)
{
DPRINTLN(“Failed to open file for writing”);
return;
}
const int capacity = 1024;
StaticJsonDocument docW;
// Set the values in the document
docW[“IdDevice”] = config.IdDevice;
docW[“DeviceName”] = config.DeviceName;
docW[“tftTimeout”] = config.tftTimeout;
docW[“ssidSD”] = config.ssidSD;
docW[“passSD”] = config.passSD;
docW[“local_IP”] = config.local_IP;
docW[“gateway”] = config.gateway;
docW[“subnet”] = config.subnet;
docW[“primaryDNS”] = config.primaryDNS;
docW[“secondaryDNS”] = config.secondaryDNS;
docW[“LowWiFiTreshold”] = config.LowWiFiTreshold;
docW[“SensorCalibrationTime”] = config.SensorCalibrationTime;
docW[“DBAddressParam”] = config.DBAddressParam;
docW[“DBPortParam”] = config.DBPortParam;
docW[“DBUpTimeParam”] = config.DBUpTimeParam;
docW[“DBUserParam”] = config.DBUserParam;
docW[“DBPswParam”] = config.DBPswParam;
docW[“HumAlaParam”] = config.HumAlaParam;
docW[“TempAlaParam”] = config.TempAlaParam;
docW[“DewAlaParam”] = config.DewAlaParam;
docW[“HumCalParam”] = config.HumCalParam;
docW[“TempCalParam”] = config.TempCalParam;
docW[“SyncDB”] = config.SyncDB;
// Serialize JSON to file
if (serializeJson(docW, fileF) == 0)
{
DPRINTLN(F(“Failed to write to file”));
}
fileF.close();
}

void WriteCfgNew()
{
DPRINTLN(“Delete file”);
deleteFile(SPIFLASH, FileCfgtest);
char bufcfgTime[30];
const char *fineriga = “\n”;
writeFilecfg(SPIFLASH, FileCfgtest, strcat(itoa(cfgTime, bufcfgTime, 10), fineriga));
readFile(SPIFLASH,FileCfgtest);
delay(500);
}

void writeFilecfg(fs::FS &fs, const char *pathcfg, const char *message)
{
DPRINT("Writing file cfg: ");
DPRINTLN(pathcfg);
File filecfg = fs.open(pathcfg, FILE_WRITE);
if (!filecfg)
{
DPRINTLN(“Failed to open file for writing”);
return;
}
if (filecfg.print(message))
{
DPRINTLN(“File written”);
}
else
{
DPRINTLN(“Write failed”);
}
filecfg.close();
}

Hi @Hansen, I tried to do a test based on the example file you indicated and I found the same problem sometimes the writing fails and one of the files gets corrupted. this is my code that i used:

/*
Connect the SD card to the following pins:
SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
*/

#include <Seeed_FS.h>
//#undef USESPIFLASH
#define USESPIFLASH
#ifdef USESPIFLASH
#define DEV SPIFLASH
#include “SFUD/Seeed_SFUD.h”
#else
#define DEV SD
#include “SD/Seeed_SD.h”
#endif

#define SERIAL Serial

#ifdef SAMD21
#define SDCARD_SS_PIN 1
#define SDCARD_SPI SPI
#endif
int c = 0;

void listDir(fs::FS &fs, const char *dirname, uint8_t levels)
{
SERIAL.print("Listing directory: ");
SERIAL.println(dirname);

File root = fs.open(dirname);
if (!root)
{
    SERIAL.println("Failed to open directory");
    return;
}
if (!root.isDirectory())
{
    SERIAL.println("Not a directory");
    return;
}

File file = root.openNextFile();
while (file)
{
    if (file.isDirectory())
    {
        SERIAL.print("  DIR : ");
        SERIAL.println(file.name());
        if (levels)
        {
            listDir(fs, file.name(), levels - 1);
        }
    }
    else
    {
        SERIAL.print("  FILE: ");
        SERIAL.print(file.name());
        SERIAL.print("  SIZE: ");
        SERIAL.println(file.size());
    }
    file = root.openNextFile();
}

}

void createDir(fs::FS &fs, const char *path)
{
SERIAL.print("Creating Dir: ");
SERIAL.println(path);
if (fs.mkdir(path))
{
SERIAL.println(“Dir created”);
}
else
{
SERIAL.println(“mkdir failed”);
}
}

void removeDir(fs::FS &fs, const char *path)
{
SERIAL.print("Removing Dir: ");
SERIAL.println(path);
if (fs.rmdir(path))
{
SERIAL.println(“Dir removed”);
}
else
{
SERIAL.println(“rmdir failed”);
}
}

void readFile(fs::FS &fs, const char *path)
{
SERIAL.print("Reading Dir: ");
SERIAL.println(path);
File file = fs.open(path);
if (!file)
{
SERIAL.println(“Failed to open file for reading”);
return;
}

SERIAL.println("Read from file: ");
while (file.available())
{
    SERIAL.write(file.read());
}
file.close();

}

void writeFile(fs::FS &fs, const char *path, const char *message)
{
SERIAL.print("Writing file: ");
SERIAL.println(path);
File file = fs.open(path, FILE_WRITE);
if (!file)
{
SERIAL.println(“Failed to open file for writing”);
return;
}

if (file.print(message))
{
    SERIAL.println("File written");
}
else
{
    SERIAL.println("Write failed");
}

file.close();

}

void appendFile(fs::FS &fs, const char *path, const char *message)
{
SERIAL.print("Appending to file: ");
SERIAL.println(path);

File file = fs.open(path, FILE_APPEND);
if (!file)
{
    SERIAL.println("Failed to open file for appending");
    return;
}
if (file.print(message))
{
    SERIAL.println("Message appended");
}
else
{
    SERIAL.println("Append failed");
}
file.close();

}

void renameFile(fs::FS &fs, const char *path1, const char *path2)
{
SERIAL.print("Renaming file “);
SERIAL.print(path1);
SERIAL.print(” to ");
SERIAL.println(path2);
if (fs.rename(path1, path2))
{
SERIAL.println(“File renamed”);
}
else
{
SERIAL.println(“Rename failed”);
}
}

void deleteFile(fs::FS &fs, const char *path)
{
SERIAL.print("Deleting file: ");
SERIAL.println(path);
if (fs.remove(path))
{
SERIAL.println(“File deleted”);
}
else
{
SERIAL.println(“Delete failed”);
}
}

void testFileIO(fs::FS &fs, const char *path)
{
File file = fs.open(path);
static uint8_t buf[512];
size_t len = 0;
uint32_t start = micros();
uint32_t end = start;
if (file)
{
len = file.size();
size_t flen = len;
start = micros();
while (len)
{
size_t toRead = len;
if (toRead > 512)
{
toRead = 512;
}
file.read(buf, toRead);
len -= toRead;
}
end = micros() - start;
SERIAL.print(flen);
SERIAL.print(" bytes read for “);
SERIAL.print(end);
SERIAL.println(” ns");
file.close();
}
else
{
SERIAL.println(“Failed to open file for reading”);
}
}

void setup()
{
SERIAL.begin(115200);
pinMode(5, OUTPUT);
digitalWrite(5, HIGH);
while (!SERIAL)
{
};
#ifdef SFUD_USING_QSPI
while (!DEV.begin(104000000UL))
{
SERIAL.println(“Card Mount Failed”);
return;
}
#else
while (!DEV.begin(SDCARD_SS_PIN, SDCARD_SPI, 4000000UL))
{
SERIAL.println(“Card Mount Failed”);
return;
}
#endif

#ifdef USESPIFLASH
uint8_t flashType = DEV.flashType();
if (flashType == FLASH_NONE)
{
SERIAL.println(“No SD card attached”);
return;
}
#else
uint8_t cardType = DEV.cardType();
if (cardType == CARD_NONE)
{
SERIAL.println(“No SD card attached”);
return;
}
#endif

#ifdef USESPIFLASH
uint8_t flashSize = DEV.flashSize() / (1024 * 1024);
SERIAL.print("SD Card Size: ");
SERIAL.print((uint32_t)flashSize);
SERIAL.println(“MB”);
#else
uint64_t cardSize = DEV.cardSize() / (1024 * 1024);
SERIAL.print("SD Card Size: ");
SERIAL.print((uint32_t)cardSize);
SERIAL.println(“MB”);
#endif
}

void loop()
{
c++;
delay(3000);
SERIAL.println©;
readFile(DEV, “/cfg2.json”);
readFile(DEV, “/cfg3.json”);
deleteFile(DEV, “/cfg2.json”);
writeFile(DEV, “/cfg2.json”, “file2!!!\n”);
readFile(DEV, “/cfg2.json”);
delay(1000);
deleteFile(DEV, “/cfg3.json”);
writeFile(DEV, “/cfg3.json”, “file3!!!\n”);
readFile(DEV, “/cfg3.json”);
}

Hi @Hansen, I placed the code again because I realized that the editor had changed it

#include <Seeed_FS.h>
//#undef USESPIFLASH
#define USESPIFLASH
#ifdef USESPIFLASH
#define DEV SPIFLASH
#include “SFUD/Seeed_SFUD.h”
#else
#define DEV SD
#include “SD/Seeed_SD.h”
#endif

#define SERIAL Serial

#ifdef SAMD21
#define SDCARD_SS_PIN 1
#define SDCARD_SPI SPI
#endif
int count = 0;

void listDir(fs::FS &fs, const char *dirname, uint8_t levels)
{
SERIAL.print("Listing directory: ");
SERIAL.println(dirname);

File root = fs.open(dirname);
if (!root)
{
    SERIAL.println("Failed to open directory");
    return;
}
if (!root.isDirectory())
{
    SERIAL.println("Not a directory");
    return;
}

File file = root.openNextFile();
while (file)
{
    if (file.isDirectory())
    {
        SERIAL.print("  DIR : ");
        SERIAL.println(file.name());
        if (levels)
        {
            listDir(fs, file.name(), levels - 1);
        }
    }
    else
    {
        SERIAL.print("  FILE: ");
        SERIAL.print(file.name());
        SERIAL.print("  SIZE: ");
        SERIAL.println(file.size());
    }
    file = root.openNextFile();
}

}

void createDir(fs::FS &fs, const char *path)
{
SERIAL.print("Creating Dir: ");
SERIAL.println(path);
if (fs.mkdir(path))
{
SERIAL.println(“Dir created”);
}
else
{
SERIAL.println(“mkdir failed”);
}
}

void removeDir(fs::FS &fs, const char *path)
{
SERIAL.print("Removing Dir: ");
SERIAL.println(path);
if (fs.rmdir(path))
{
SERIAL.println(“Dir removed”);
}
else
{
SERIAL.println(“rmdir failed”);
}
}

void readFile(fs::FS &fs, const char *path)
{
SERIAL.print("Reading Dir: ");
SERIAL.println(path);
File file = fs.open(path);
if (!file)
{
SERIAL.println(“Failed to open file for reading”);
return;
}

SERIAL.println("Read from file: ");
while (file.available())
{
    SERIAL.write(file.read());
}
file.close();

}

void writeFile(fs::FS &fs, const char *path, const char *message)
{
SERIAL.print("Writing file: ");
SERIAL.println(path);
File file = fs.open(path, FILE_WRITE);
if (!file)
{
SERIAL.println(“Failed to open file for writing”);
return;
}

if (file.print(message))
{
    SERIAL.println("File written");
}
else
{
    SERIAL.println("Write failed");
}

file.close();

}

void appendFile(fs::FS &fs, const char *path, const char *message)
{
SERIAL.print("Appending to file: ");
SERIAL.println(path);

File file = fs.open(path, FILE_APPEND);
if (!file)
{
    SERIAL.println("Failed to open file for appending");
    return;
}
if (file.print(message))
{
    SERIAL.println("Message appended");
}
else
{
    SERIAL.println("Append failed");
}
file.close();

}

void renameFile(fs::FS &fs, const char *path1, const char *path2)
{
SERIAL.print("Renaming file “);
SERIAL.print(path1);
SERIAL.print(” to ");
SERIAL.println(path2);
if (fs.rename(path1, path2))
{
SERIAL.println(“File renamed”);
}
else
{
SERIAL.println(“Rename failed”);
}
}
void deleteFile(fs::FS &fs, const char *path)
{
SERIAL.print("Deleting file: ");
SERIAL.println(path);
if (fs.remove(path))
{
SERIAL.println(“File deleted”);
}
else
{
SERIAL.println(“Delete failed”);
}
}

void testFileIO(fs::FS &fs, const char *path)
{
File file = fs.open(path);
static uint8_t buf[512];
size_t len = 0;
uint32_t start = micros();
uint32_t end = start;
if (file)
{
len = file.size();
size_t flen = len;
start = micros();
while (len)
{
size_t toRead = len;
if (toRead > 512)
{
toRead = 512;
}
file.read(buf, toRead);
len -= toRead;
}
end = micros() - start;
SERIAL.print(flen);
SERIAL.print(" bytes read for “);
SERIAL.print(end);
SERIAL.println(” ns");
file.close();
}
else
{
SERIAL.println(“Failed to open file for reading”);
}
}

void setup()
{
SERIAL.begin(115200);
pinMode(5, OUTPUT);
digitalWrite(5, HIGH);
while (!SERIAL)
{
};
#ifdef SFUD_USING_QSPI
while (!DEV.begin(104000000UL))
{
SERIAL.println(“Card Mount Failed”);
return;
}
#else
while (!DEV.begin(SDCARD_SS_PIN, SDCARD_SPI, 4000000UL))
{
SERIAL.println(“Card Mount Failed”);
return;
}
#endif

#ifdef USESPIFLASH
uint8_t flashType = DEV.flashType();
if (flashType == FLASH_NONE)
{
SERIAL.println(“No SD card attached”);
return;
}
#else
uint8_t cardType = DEV.cardType();
if (cardType == CARD_NONE)
{
SERIAL.println(“No SD card attached”);
return;
}
#endif

#ifdef USESPIFLASH
uint8_t flashSize = DEV.flashSize() / (1024 * 1024);
SERIAL.print("SD Card Size: ");
SERIAL.print((uint32_t)flashSize);
SERIAL.println(“MB”);
#else
uint64_t cardSize = DEV.cardSize() / (1024 * 1024);
SERIAL.print("SD Card Size: ");
SERIAL.print((uint32_t)cardSize);
SERIAL.println(“MB”);
#endif
}
void loop()
{
count++;
delay(3000);
SERIAL.println(count);
readFile(DEV, “/cfg2.json”);
readFile(DEV, “/cfg3.json”);
deleteFile(DEV, “/cfg2.json”);
writeFile(DEV, “/cfg2.json”, “file2!!!\n”);
readFile(DEV, “/cfg2.json”);
delay(1000);
deleteFile(DEV, “/cfg3.json”);
writeFile(DEV, “/cfg3.json”, “file3!!!\n”);
readFile(DEV, “/cfg3.json”);
}

Click to see the code
/*
Connect the SD card to the following pins:
SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
*/

#include <Seeed_FS.h>
//#undef USESPIFLASH
#define USESPIFLASH
#ifdef USESPIFLASH
#define DEV SPIFLASH
#include “SFUD/Seeed_SFUD.h”
#else
#define DEV SD
#include “SD/Seeed_SD.h”
#endif

#define SERIAL Serial

#ifdef SAMD21
#define SDCARD_SS_PIN 1
#define SDCARD_SPI SPI
#endif
int c = 0;

void listDir(fs::FS &fs, const char *dirname, uint8_t levels)
{
SERIAL.print("Listing directory: ");
SERIAL.println(dirname);

File root = fs.open(dirname);
if (!root)
{
    SERIAL.println("Failed to open directory");
    return;
}
if (!root.isDirectory())
{
    SERIAL.println("Not a directory");
    return;
}

File file = root.openNextFile();
while (file)
{
    if (file.isDirectory())
    {
        SERIAL.print("  DIR : ");
        SERIAL.println(file.name());
        if (levels)
        {
            listDir(fs, file.name(), levels - 1);
        }
    }
    else
    {
        SERIAL.print("  FILE: ");
        SERIAL.print(file.name());
        SERIAL.print("  SIZE: ");
        SERIAL.println(file.size());
    }
    file = root.openNextFile();
}

}

void createDir(fs::FS &fs, const char *path)
{
SERIAL.print("Creating Dir: ");
SERIAL.println(path);
if (fs.mkdir(path))
{
SERIAL.println(“Dir created”);
}
else
{
SERIAL.println(“mkdir failed”);
}
}

void removeDir(fs::FS &fs, const char *path)
{
SERIAL.print("Removing Dir: ");
SERIAL.println(path);
if (fs.rmdir(path))
{
SERIAL.println(“Dir removed”);
}
else
{
SERIAL.println(“rmdir failed”);
}
}

void readFile(fs::FS &fs, const char *path)
{
SERIAL.print("Reading Dir: ");
SERIAL.println(path);
File file = fs.open(path);
if (!file)
{
SERIAL.println(“Failed to open file for reading”);
return;
}

SERIAL.println("Read from file: ");
while (file.available())
{
    SERIAL.write(file.read());
}
file.close();

}

void writeFile(fs::FS &fs, const char *path, const char *message)
{
SERIAL.print("Writing file: ");
SERIAL.println(path);
File file = fs.open(path, FILE_WRITE);
if (!file)
{
SERIAL.println(“Failed to open file for writing”);
return;
}

if (file.print(message))
{
    SERIAL.println("File written");
}
else
{
    SERIAL.println("Write failed");
}

file.close();

}

void appendFile(fs::FS &fs, const char *path, const char *message)
{
SERIAL.print("Appending to file: ");
SERIAL.println(path);

File file = fs.open(path, FILE_APPEND);
if (!file)
{
    SERIAL.println("Failed to open file for appending");
    return;
}
if (file.print(message))
{
    SERIAL.println("Message appended");
}
else
{
    SERIAL.println("Append failed");
}
file.close();

}

void renameFile(fs::FS &fs, const char *path1, const char *path2)
{
SERIAL.print("Renaming file “);
SERIAL.print(path1);
SERIAL.print(” to ");
SERIAL.println(path2);
if (fs.rename(path1, path2))
{
SERIAL.println(“File renamed”);
}
else
{
SERIAL.println(“Rename failed”);
}
}

void deleteFile(fs::FS &fs, const char *path)
{
SERIAL.print("Deleting file: ");
SERIAL.println(path);
if (fs.remove(path))
{
SERIAL.println(“File deleted”);
}
else
{
SERIAL.println(“Delete failed”);
}
}

void testFileIO(fs::FS &fs, const char *path)
{
File file = fs.open(path);
static uint8_t buf[512];
size_t len = 0;
uint32_t start = micros();
uint32_t end = start;
if (file)
{
len = file.size();
size_t flen = len;
start = micros();
while (len)
{
size_t toRead = len;
if (toRead > 512)
{
toRead = 512;
}
file.read(buf, toRead);
len -= toRead;
}
end = micros() - start;
SERIAL.print(flen);
SERIAL.print(" bytes read for “);
SERIAL.print(end);
SERIAL.println(” ns");
file.close();
}
else
{
SERIAL.println(“Failed to open file for reading”);
}
}

void setup()
{
SERIAL.begin(115200);
pinMode(5, OUTPUT);
digitalWrite(5, HIGH);
while (!SERIAL)
{
};
#ifdef SFUD_USING_QSPI
while (!DEV.begin(104000000UL))
{
SERIAL.println(“Card Mount Failed”);
return;
}
#else
while (!DEV.begin(SDCARD_SS_PIN, SDCARD_SPI, 4000000UL))
{
SERIAL.println(“Card Mount Failed”);
return;
}
#endif

#ifdef USESPIFLASH
uint8_t flashType = DEV.flashType();
if (flashType == FLASH_NONE)
{
SERIAL.println(“No SD card attached”);
return;
}
#else
uint8_t cardType = DEV.cardType();
if (cardType == CARD_NONE)
{
SERIAL.println(“No SD card attached”);
return;
}
#endif

#ifdef USESPIFLASH
uint8_t flashSize = DEV.flashSize() / (1024 * 1024);
SERIAL.print("SD Card Size: ");
SERIAL.print((uint32_t)flashSize);
SERIAL.println(“MB”);
#else
uint64_t cardSize = DEV.cardSize() / (1024 * 1024);
SERIAL.print("SD Card Size: ");
SERIAL.print((uint32_t)cardSize);
SERIAL.println(“MB”);
#endif
}

void loop()
{
c++;
delay(3000);
SERIAL.println©;
readFile(DEV, “/cfg2.json”);
readFile(DEV, “/cfg3.json”);
deleteFile(DEV, “/cfg2.json”);
writeFile(DEV, “/cfg2.json”, “file2!!!\n”);
readFile(DEV, “/cfg2.json”);
delay(1000);
deleteFile(DEV, “/cfg3.json”);
writeFile(DEV, “/cfg3.json”, “file3!!!\n”);
readFile(DEV, “/cfg3.json”);
}

tip : If you have large code chunks (or logs) , you can collapse (and format) them to avoid a very long post like this :

[details=Click to see the code]
```cpp

code here

[/details]

thank you @BoRRoZ @Hansen,
I enter the code as you indicated below

Click to see the code

#include <Seeed_FS.h>
//#undef USESPIFLASH
#define USESPIFLASH
#ifdef USESPIFLASH
#define DEV SPIFLASH
#include "SFUD/Seeed_SFUD.h"
#else
#define DEV SD
#include "SD/Seeed_SD.h"
#endif

#define SERIAL Serial

#ifdef _SAMD21_
#define SDCARD_SS_PIN 1
#define SDCARD_SPI SPI
#endif
int count = 0;

void listDir(fs::FS &fs, const char *dirname, uint8_t levels)
{
    SERIAL.print("Listing directory: ");
    SERIAL.println(dirname);

    File root = fs.open(dirname);
    if (!root)
    {
        SERIAL.println("Failed to open directory");
        return;
    }
    if (!root.isDirectory())
    {
        SERIAL.println("Not a directory");
        return;
    }

    File file = root.openNextFile();
    while (file)
    {
        if (file.isDirectory())
        {
            SERIAL.print("  DIR : ");
            SERIAL.println(file.name());
            if (levels)
            {
                listDir(fs, file.name(), levels - 1);
            }
        }
        else
        {
            SERIAL.print("  FILE: ");
            SERIAL.print(file.name());
            SERIAL.print("  SIZE: ");
            SERIAL.println(file.size());
        }
        file = root.openNextFile();
    }
}

void createDir(fs::FS &fs, const char *path)
{
    SERIAL.print("Creating Dir: ");
    SERIAL.println(path);
    if (fs.mkdir(path))
    {
        SERIAL.println("Dir created");
    }
    else
    {
        SERIAL.println("mkdir failed");
    }
}

void removeDir(fs::FS &fs, const char *path)
{
    SERIAL.print("Removing Dir: ");
    SERIAL.println(path);
    if (fs.rmdir(path))
    {
        SERIAL.println("Dir removed");
    }
    else
    {
        SERIAL.println("rmdir failed");
    }
}

void readFile(fs::FS &fs, const char *path)
{
    SERIAL.print("Reading Dir: ");
    SERIAL.println(path);
    File file = fs.open(path);
    if (!file)
    {
        SERIAL.println("Failed to open file for reading");
        return;
    }

    SERIAL.println("Read from file: ");
    while (file.available())
    {
        SERIAL.write(file.read());
    }
    file.close();
}

void writeFile(fs::FS &fs, const char *path, const char *message)
{
    SERIAL.print("Writing file: ");
    SERIAL.println(path);
    File file = fs.open(path, FILE_WRITE);
    if (!file)
    {
        SERIAL.println("Failed to open file for writing");
        return;
    }

    if (file.print(message))
    {
        SERIAL.println("File written");
    }
    else
    {
        SERIAL.println("Write failed");
    }

    file.close();
}

void appendFile(fs::FS &fs, const char *path, const char *message)
{
    SERIAL.print("Appending to file: ");
    SERIAL.println(path);

    File file = fs.open(path, FILE_APPEND);
    if (!file)
    {
        SERIAL.println("Failed to open file for appending");
        return;
    }
    if (file.print(message))
    {
        SERIAL.println("Message appended");
    }
    else
    {
        SERIAL.println("Append failed");
    }
    file.close();
}

void renameFile(fs::FS &fs, const char *path1, const char *path2)
{
    SERIAL.print("Renaming file ");
    SERIAL.print(path1);
    SERIAL.print(" to ");
    SERIAL.println(path2);
    if (fs.rename(path1, path2))
    {
        SERIAL.println("File renamed");
    }
    else
    {
        SERIAL.println("Rename failed");
    }
}
void deleteFile(fs::FS &fs, const char *path)
{
    SERIAL.print("Deleting file: ");
    SERIAL.println(path);
    if (fs.remove(path))
    {
        SERIAL.println("File deleted");
    }
    else
    {
        SERIAL.println("Delete failed");
    }
}

void testFileIO(fs::FS &fs, const char *path)
{
    File file = fs.open(path);
    static uint8_t buf[512];
    size_t len = 0;
    uint32_t start = micros();
    uint32_t end = start;
    if (file)
    {
        len = file.size();
        size_t flen = len;
        start = micros();
        while (len)
        {
            size_t toRead = len;
            if (toRead > 512)
            {
                toRead = 512;
            }
            file.read(buf, toRead);
            len -= toRead;
        }
        end = micros() - start;
        SERIAL.print(flen);
        SERIAL.print(" bytes read for ");
        SERIAL.print(end);
        SERIAL.println(" ns");
        file.close();
    }
    else
    {
        SERIAL.println("Failed to open file for reading");
    }
}

void setup()
{
    SERIAL.begin(115200);
    pinMode(5, OUTPUT);
    digitalWrite(5, HIGH);
    while (!SERIAL)
    {
    };
#ifdef SFUD_USING_QSPI
    while (!DEV.begin(104000000UL))
    {
        SERIAL.println("Card Mount Failed");
        return;
    }
#else
    while (!DEV.begin(SDCARD_SS_PIN, SDCARD_SPI, 4000000UL))
    {
        SERIAL.println("Card Mount Failed");
        return;
    }
#endif

#ifdef USESPIFLASH
    uint8_t flashType = DEV.flashType();
    if (flashType == FLASH_NONE)
    {
        SERIAL.println("No SD card attached");
        return;
    }
#else
    uint8_t cardType = DEV.cardType();
    if (cardType == CARD_NONE)
    {
        SERIAL.println("No SD card attached");
        return;
    }
#endif

#ifdef USESPIFLASH
    uint8_t flashSize = DEV.flashSize() / (1024 * 1024);
    SERIAL.print("SD Card Size: ");
    SERIAL.print((uint32_t)flashSize);
    SERIAL.println("MB");
#else
    uint64_t cardSize = DEV.cardSize() / (1024 * 1024);
    SERIAL.print("SD Card Size: ");
    SERIAL.print((uint32_t)cardSize);
    SERIAL.println("MB");
#endif
}
void loop()
{
  count++;
  delay(3000);
  SERIAL.println(count);
  readFile(DEV, "/cfg2.json");
  readFile(DEV, "/cfg3.json");
  deleteFile(DEV, "/cfg2.json");
  writeFile(DEV, "/cfg2.json", "file2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  readFile(DEV, "/cfg2.json");
  delay(1000);
  deleteFile(DEV, "/cfg3.json");
  writeFile(DEV, "/cfg3.json", "file3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  readFile(DEV, "/cfg3.json");
}

1 Like

Hi @Gianfry60
we have been updated the lib to solve this problem. we can get the newest lib by accessing https://github.com/Seeed-Studio/Seeed_Arduino_FS.git.

2 Likes

Hi @Hansen, I did some tests with the Multi_partition example file by inserting as a test the reading of the files. The files I layered with the SD_Test code on the SD and I checked both by reading them with the code and on the PC and they read perfectly. In the Multi_partition code, however, the reading of the files fails. is it a library error or am I doing something wrong?
I am attaching below the code I used for testing both the one to write “SD_TEST” and the one to read “Multi_partition”
If you can help me I will be grateful.
Thank you

CODE USED TO WRITE

Click to see the code
/* SD_Test code */

/*

    Connect the SD card to the following pins:

    SD card attached to SPI bus as follows:

 ** MOSI - pin 11

 ** MISO - pin 12

 ** CLK - pin 13

 ** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)

*/

#include <Seeed_FS.h>

//#define USESPIFLASH

#undef USESPIFLASH

#ifdef USESPIFLASH

#define DEV SPIFLASH

#include "SFUD/Seeed_SFUD.h"

#else

#define DEV SD

#include "SD/Seeed_SD.h"

#endif

#define SERIAL Serial

#ifdef _SAMD21_

#define SDCARD_SS_PIN 1

#define SDCARD_SPI SPI

#endif

void listDir(fs::FS &fs, const char *dirname, uint8_t levels)

{

    SERIAL.print("Listing directory: ");

    SERIAL.println(dirname);

    File root = fs.open(dirname);

    if (!root)

    {

        SERIAL.println("Failed to open directory");

        return;

    }

    if (!root.isDirectory())

    {

        SERIAL.println("Not a directory");

        return;

    }

    File file = root.openNextFile();

    while (file)

    {

        if (file.isDirectory())

        {

            SERIAL.print("  DIR : ");

            SERIAL.println(file.name());

            if (levels)

            {

                listDir(fs, file.name(), levels - 1);

            }

        }

        else

        {

            SERIAL.print("  FILE: ");

            SERIAL.print(file.name());

            SERIAL.print("  SIZE: ");

            SERIAL.println(file.size());

        }

        file = root.openNextFile();

    }

}

void createDir(fs::FS &fs, const char *path)

{

    SERIAL.print("Creating Dir: ");

    SERIAL.println(path);

    if (fs.mkdir(path))

    {

        SERIAL.println("Dir created");

    }

    else

    {

        SERIAL.println("mkdir failed");

    }

}

void removeDir(fs::FS &fs, const char *path)

{

    SERIAL.print("Removing Dir: ");

    SERIAL.println(path);

    if (fs.rmdir(path))

    {

        SERIAL.println("Dir removed");

    }

    else

    {

        SERIAL.println("rmdir failed");

    }

}

void readFile(fs::FS &fs, const char *path)

{

    SERIAL.print("Reading Dir: ");

    SERIAL.println(path);

    File file = fs.open(path);

    if (!file)

    {

        SERIAL.println("Failed to open file for reading");

        return;

    }

    SERIAL.print("Read from file: ");

    while (file.available())

    {

        SERIAL.write(file.read());

    }

    file.close();

}

void writeFile(fs::FS &fs, const char *path, const char *message)

{

    SERIAL.print("Writing file: ");

    SERIAL.println(path);

    File file = fs.open(path, FILE_WRITE);

    if (!file)

    {

        SERIAL.println("Failed to open file for writing");

        return;

    }

    if (file.print(message))

    {

        SERIAL.println("File written");

    }

    else

    {

        SERIAL.println("Write failed");

    }

    file.close();

}

void appendFile(fs::FS &fs, const char *path, const char *message)

{

    SERIAL.print("Appending to file: ");

    SERIAL.println(path);

    File file = fs.open(path, FILE_APPEND);

    if (!file)

    {

        SERIAL.println("Failed to open file for appending");

        return;

    }

    if (file.print(message))

    {

        SERIAL.println("Message appended");

    }

    else

    {

        SERIAL.println("Append failed");

    }

    file.close();

}

void renameFile(fs::FS &fs, const char *path1, const char *path2)

{

    SERIAL.print("Renaming file ");

    SERIAL.print(path1);

    SERIAL.print(" to ");

    SERIAL.println(path2);

    if (fs.rename(path1, path2))

    {

        SERIAL.println("File renamed");

    }

    else

    {

        SERIAL.println("Rename failed");

    }

}

void deleteFile(fs::FS &fs, const char *path)

{

    SERIAL.print("Deleting file: ");

    SERIAL.println(path);

    if (fs.remove(path))

    {

        SERIAL.println("File deleted");

    }

    else

    {

        SERIAL.println("Delete failed");

    }

}

void testFileIO(fs::FS &fs, const char *path)

{

    File file = fs.open(path);

    static uint8_t buf[512];

    size_t len = 0;

    uint32_t start = micros();

    uint32_t end = start;

    if (file)

    {

        len = file.size();

        size_t flen = len;

        start = micros();

        while (len)

        {

            size_t toRead = len;

            if (toRead > 512)

            {

                toRead = 512;

            }

            file.read(buf, toRead);

            len -= toRead;

        }

        end = micros() - start;

        SERIAL.print(flen);

        SERIAL.print(" bytes read for ");

        SERIAL.print(end);

        SERIAL.println(" ns");

        file.close();

    }

    else

    {

        SERIAL.println("Failed to open file for reading");

    }

}

void setup()

{

    SERIAL.begin(115200);

    pinMode(5, OUTPUT);

    digitalWrite(5, HIGH);

    while (!SERIAL)

    {

    };

#ifdef SFUD_USING_QSPI

    while (!DEV.begin(104000000UL))

    {

        SERIAL.println("Card Mount Failed");

        return;

    }

#else

    while (!DEV.begin(SDCARD_SS_PIN, SDCARD_SPI, 4000000UL))

    {

        SERIAL.println("Card Mount Failed");

        return;

    }

#endif

#ifdef USESPIFLASH

    uint8_t flashType = DEV.flashType();

    if (flashType == FLASH_NONE)

    {

        SERIAL.println("No flash attached");

        return;

    }

#else

    uint8_t cardType = DEV.cardType();

    if (cardType == CARD_NONE)

    {

        SERIAL.println("No SD card attached");

        return;

    }

#endif

#ifdef USESPIFLASH

    uint32_t flashSize = DEV.flashSize() / (1024 * 1024);

    SERIAL.print("flash Size: ");

    SERIAL.print((uint32_t)flashSize);

    SERIAL.println("MB");

#else

    uint64_t cardSize = DEV.cardSize() / (1024 * 1024);

    SERIAL.print("SD Card Size: ");

    SERIAL.print((uint32_t)cardSize);

    SERIAL.println("MB");

#endif

    listDir(DEV, "/", 0);

    // createDir(DEV, "/mydir");

    // listDir(DEV, "/", 0);

    // removeDir(DEV, "/mydir");

    // listDir(DEV, "/", 2);

    deleteFile(DEV, "/foo.txt");

    writeFile(DEV, "/foo.txt", "Hello ");

    appendFile(DEV, "/foo.txt", "World!\n");

    readFile(DEV, "/foo.txt");

    // renameFile(DEV, "/hello.txt", "/foo.txt");

    deleteFile(DEV, "/foo2.txt");

    writeFile(DEV, "/foo2.txt", "Hello2 ");

    appendFile(DEV, "/foo2.txt", "World!2\n");

    readFile(DEV, "/foo2.txt");

    // testFileIO(DEV, "/foo.txt");

    listDir(DEV, "/", 0);

    uint32_t totalBytes = DEV.totalBytes();

    SERIAL.print("Total space: ");

    SERIAL.print(totalBytes / (1024 * 1024));

    SERIAL.println("MB");

    uint32_t usedBytes = DEV.usedBytes();

    SERIAL.print("Used space: ");

    SERIAL.print(usedBytes / (1024 * 1024));

    SERIAL.println("MB");

}

void loop()

{

}


CODE USED TO READ

Click to see the code
#include <Seeed_FS.h>
#include "SFUD/Seeed_SFUD.h"
#include "SD/Seeed_SD.h"
#define SERIAL Serial

#ifdef _SAMD21_
#define SDCARD_SS_PIN 2
#define SDCARD_SPI SPI
#endif

void readFile(fs::FS &fs, const char *path)
{
    SERIAL.print("Reading Dir: ");
    SERIAL.println(path);
    File file = fs.open(path);
    if (!file)
    {
        SERIAL.println("Failed to open file for reading");
        return;
    }

    SERIAL.print("Read from file: ");
    while (file.available())
    {
        SERIAL.write(file.read());
    }
    file.close();
}

void listDir(fs::FS &fs, const char *dirname, uint8_t levels)
{
    SERIAL.print("Listing directory: ");
    SERIAL.println(dirname);

    File root = fs.open(dirname);
    if (!root)
    {
        SERIAL.println("Failed to open directory");
        return;
    }
    if (!root.isDirectory())
    {
        SERIAL.println("Not a directory");
        return;
    }

    File file = root.openNextFile();
    while (file)
    {
        if (file.isDirectory())
        {
            SERIAL.print("  DIR : ");
            SERIAL.println(file.name());
            if (levels)
            {
                listDir(fs, file.name(), levels - 1);
            }
        }
        else
        {
            SERIAL.print("  FILE: ");
            SERIAL.print(file.name());
            SERIAL.print("  SIZE: ");
            SERIAL.println(file.size());
        }
        file = root.openNextFile();
    }
}
void setup()
{
    SERIAL.begin(115200);
    while (!SERIAL)
    {
    };
#ifdef SFUD_USING_QSPI
    while (!SPIFLASH.begin(104000000UL))
    {
        SERIAL.println("Flash Mount Failed");
        return;
    }
    while (!SD.begin(SDCARD_SS_PIN, SDCARD_SPI, 4000000UL))
    {
        SERIAL.println("SD Card Mount Failed");
        return;
    }
#else
    while (!SD.begin(SDCARD_SS_PIN, SDCARD_SPI, 4000000UL))
    {
        SERIAL.println("SD Card Mount Failed");
        return;
    }
    while (!SPIFLASH.begin(1, SPI, 4000000UL))
    {
        SERIAL.println(" Flash Mount Failed");
        return;
    }
#endif
    uint8_t flashType = SPIFLASH.flashType();
    if (flashType == FLASH_NONE)
    {
        SERIAL.println("No Flash attached");
        return;
    }
    uint8_t cardType = SD.cardType();
    if (cardType == CARD_NONE)
    {
        SERIAL.println("No SD card attached");
        return;
    }
    uint8_t flashSize = SPIFLASH.flashSize() / (1024 * 1024);
    SERIAL.print("Flash Size: ");
    SERIAL.print((uint32_t)flashSize);
    SERIAL.println("MB");
    uint64_t cardSize = SD.cardSize() / (1024 * 1024);
    SERIAL.print("SD Card Size: ");
    SERIAL.print((uint32_t)cardSize);
    SERIAL.println("MB");

    uint32_t FlashtotalBytes = SPIFLASH.totalBytes();
    SERIAL.print("Total space: ");
    SERIAL.print(FlashtotalBytes / (1024 * 1024));
    SERIAL.println("MB");
    uint32_t FlasusedBytes = SPIFLASH.usedBytes();
    SERIAL.print("Used space: ");
    SERIAL.print(FlasusedBytes / (1024 * 1024));
    SERIAL.println("MB");

    uint32_t SDtotalBytes = SD.totalBytes();
    SERIAL.print("Total space: ");
    SERIAL.print(SDtotalBytes / (1024 * 1024));
    SERIAL.println("MB");
    uint32_t SDusedBytes = SD.usedBytes();
    SERIAL.print("Used space: ");
    SERIAL.print(SDusedBytes / (1024 * 1024));
    SERIAL.println("MB");

    listDir(SD, "SD:/", 0);

    readFile(SD, "/foo2.txt");
    readFile(SD, "/foo.txt");
    //listDir(SPIFLASH, "Flash:/", 0);
    //readFile(SPIFLASH, "/foo.txt");
}

void loop()
{
}

1 Like

Hi @Hansen, I noticed that the problem arises when both #include “SD / Seeed_SD.h” and #include “SFUD / Seeed_SFUD.h” files are included. If I include both of them only FLASH reading works if I include only #include “SD / Seeed_SD.h” then SD works. How can you solve this problem to use both SD and FLASH at the same time?
I await your considerations.
Thank you

The updated library doesn’t appear on the Arduino Library Manager.

Do you plan to make an official release? Thank you!

Of course, we’re going to do that in Q4. @reivilo

Hi @Gianfry60:
there exist an example for doing this thing in our Github.

Hi @Hansen, the code you indicate is the same one I used if you see in the code I sent. It is the same code but if you try to insert a routine for reading the files you will see that it crashes unless you comment out all the Flash related code by removing the inclusion of “SFUD / Seeed_SFUD.h”. if you don’t do this the reading fails.

Hi @Gianfry60:
I would say, you must use a different filesystem’s variety if you want to use control two partitions at the same time.

    writeFile(SD, "/foo2.txt", "Hello2 ");
    writeFile(SPIFLASH, "/foo2.txt", "Hello2 ");