greiman / SdFat

Arduino FAT16/FAT32 exFAT Library
MIT License
1.06k stars 498 forks source link

Noobs example #437

Open Ktysai opened 1 year ago

Ktysai commented 1 year ago

Hello!

It's very cool library. Finally I've been able to write on a exFAT SDCARD :)

I have a question, not an issue!

Is there an example for n00bs? I have an Arduino Zero and an 64GB exFAT. My data is less than 1KB and it's written at various intervals 4-10sec.

All the best!

IanBurwell commented 1 year ago

I agree that a barebones example was needed, and created one after reading through the other examples. It is currently waiting to be merged in, but if you are still looking for an example feel free to test it out: https://github.com/greiman/SdFat/pull/439/files

greiman commented 1 year ago

I agree that better simple examples are needed. In fact the whole set of examples needs to be improved.

SdFat has become very complex since the 2009 version used in the Arduino standard SD.h library.

I tried the simple example in the pull request with a few n00b problems and it failed in confusing ways.

Here is what happens with an Uno and a exFAT SD.

SD begin() failed (check wiring/CS pin/card seating)

The problem is that SdFat and File are typedefs and support on Uno is for FAT16/FAT32 only. So you need to either edit SdFatConfig.h or replace (SdFat, File) with (SdExFat, ExFile) or (SdFs, FsFile).

If you run your example on some SAMD21 boards from Adafruit it will fail since the AdaFruit SPI driver has a bug and must run at a slower SPI speed than SPI_FULL_SPEED.

I need to spend time redoing all the examples for SdFat.

There is a huge number of example on the web for SD.h but they are not helpful for the modern SdFat. Just try google with these word:

arduino simple sd card example

Here are the first few results:

https://randomnerdtutorials.com/guide-to-sd-card-module-with-arduino/

https://docs.arduino.cc/learn/programming/sd-guide

https://www.instructables.com/Micro-SD-Card-Tutorial/

https://lastminuteengineers.com/arduino-micro-sd-card-module-tutorial/

https://circuitdigest.com/microcontroller-projects/interfacing-micro-sd-card-module-with-arduino

https://arduinogetstarted.com/tutorials/arduino-micro-sd-card

https://how2electronics.com/using-sd-card-module-with-arduino-read-write-data-logger/

https://electropeak.com/learn/sd-card-module-read-write-arduino-tutorial/

https://www.circuitbasics.com/writing-data-to-files-on-an-sd-card-on-arduino/

IanBurwell commented 1 year ago

I thought the SdFat typedef was messed with by SDFAT_FILE_TYPE automatically. For SAMD51 it defaults to SdFs and I thought that would become SdFat32 for the Uno. I will admit, however, that I have only a surface-level understanding of SdFat and thus might not be in the best position to provide an example PR (#439). Lmk on the PR if it is useful or if I should close it. I am also willing to make it more robust if that would prove useful and test it on a uno etc.

greiman commented 1 year ago

You should close the PR. I have decided to add features to SdFat that will allow more detailed error messages for beginners.

I will then start upgrading the examples.

I need to make a list of issues and features to cover and design a set of example to cover this list.

Ktysai commented 1 year ago

Thank you, @IanBurwell & @greiman

The Ex FAT Logger example can be a good candidate to write with these conditions:

Thank you for your time!

Ktysai commented 1 year ago

A reworked example from examples/examplesV1/RawWrite I have used an Arduino zero, Serial has been renamed SerialUSB.

A 64GB card and an ExFAT was used

#include "FreeStack.h"
#include "SdFat.h"

// This example was designed for exFAT but will support FAT16/FAT32.
// Note: Uno will not support SD_FAT_TYPE = 3.
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
#define SD_FAT_TYPE 2

// SDCARD_SS_PIN is defined for the built-in SD on some boards.
const uint8_t SD_CS_PIN = 12;

// Try max SPI clock for an sd. Reduce SPI_CLOCK if errors occur.
#define SPI_CLOCK SD_SCK_MHZ(4)

#if SD_FAT_TYPE == 0
typedef SdFat sd_t;
typedef File file_t;
#elif SD_FAT_TYPE == 1
typedef SdFat32 sd_t;
typedef File32 file_t;
#elif SD_FAT_TYPE == 2
typedef SdExFat sd_t;
typedef ExFile file_t;
#elif SD_FAT_TYPE == 3
typedef SdFs sd_t;
typedef FsFile file_t;
#else  // SD_FAT_TYPE
#error Invalid SD_FAT_TYPE
#endif  // SD_FAT_TYPE

sd_t sd;

file_t binFile;
file_t csvFile;
file_t filevio;
ExFile myFile;

void setup() {
  // Open serial communications and wait for port to open:
  SerialUSB.begin(115200);
  while (!SerialUSB) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  SerialUSB.print("Initializing SD card...");

  if (!sd.begin(SD_CS_PIN)) {
    SerialUSB.println("initialization failed!");
    return;
  }
  SerialUSB.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = sd.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    SerialUSB.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    SerialUSB.println("done.");
  } else {
    // if the file didn't open, print an error:
    SerialUSB.println("error opening test.txt");
  }

  // re-open the file for reading:
  myFile = sd.open("test.txt");
  if (myFile) {
    SerialUSB.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      SerialUSB.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    SerialUSB.println("error opening test.txt");
  }
}

void loop() {
  // nothing happens after setup
}