Go Down

Topic: Don't Format SD cards with OS utilities! (Read 78317 times) previous topic - next topic



Thanks for this, and SdFat.  I'm still working on buffering (making sense of it, ME here...), but whenever I have a question about Arduino's and SDs, and ask the Google, you (in some flavor) come up and answer my question and more.

If only SDIO didn't seem so much more intimidating than SPI (which is so simple!).



Thanks for the information about using "SDFormatter V4.0" to format SD card.

Because of having no success to get my "Arduino UNO" - "SD card" running, I searched for posts which describes the same problem. But I didn't found any solution/hint which will help. In the meantime I spend many hours/days...

Therefore I also tried to use "SDFormatter V4.0" to format my SD card, but I did not solve my problem.

My "Arduino UNO" - "SD card" is still not running. That's really frustrating and makes no fun.

The best result (using "CardInfo") was:

Code: [Select]

Initializing SD card...Wiring is correct and a card is present.

Card type: SDHC
Could not find FAT16/FAT32 partition.
Make sure you've formatted the card

but it is hard to reproduce this situation.

Any hints?


Mar 12, 2017, 03:08 pm Last Edit: Mar 12, 2017, 03:17 pm by _pepe_

It could be interesting to modify the SD library in order to know the reason why the volume's initialization fails.

For instance, you could add an "error" attribute in the SdVolume class (in file SD/src/utility/SdFat.h):

class SdVolume {
  uint8_t error;

and set it to particular values depending on the exit point of the SdVolume::init() method (in file SD/src/utility/SdVolume.cpp):

uint8_t SdVolume::init(Sd2Card* dev, uint8_t part) {
  error = 0;
  uint32_t volumeStartBlock = 0;
  sdCard_ = dev;
  // if part == 0 assume super floppy with FAT boot sector in block zero
  // if part > 0 assume mbr volume with partition table
  if (part) {
    if (part > 4)return error=1,false;
    if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return error=2,false;
    part_t* p = &cacheBuffer_.mbr.part[part-1];
    if ((p->boot & 0X7F) !=0)
      // not a valid partition
      return error=3,false;
    if (p->totalSectors < 100)
      // not a valid partition
      return error=4,false;
    if (p->firstSector == 0)
      // not a valid partition
      return error=5,false;
    volumeStartBlock = p->firstSector;
  if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return error=6,false;
  bpb_t* bpb = &cacheBuffer_.fbs.bpb;
  if (bpb->bytesPerSector != 512)
       // not valid FAT volume
      return error=7,false;
  if (bpb->fatCount == 0)
       // not valid FAT volume
      return error=8,false;
  if (bpb->reservedSectorCount == 0)
       // not valid FAT volume
      return error=9,false;
  if (bpb->sectorsPerCluster == 0)
       // not valid FAT volume
      return error=10,false;
  fatCount_ = bpb->fatCount;
  blocksPerCluster_ = bpb->sectorsPerCluster;

  // determine shift that is same as multiply by blocksPerCluster_
  clusterSizeShift_ = 0;
  while (blocksPerCluster_ != (1 << clusterSizeShift_)) {
    // error if not power of 2
    if (clusterSizeShift_++ > 7) return error=11,false;
  blocksPerFat_ = bpb->sectorsPerFat16 ?
                    bpb->sectorsPerFat16 : bpb->sectorsPerFat32;

  fatStartBlock_ = volumeStartBlock + bpb->reservedSectorCount;

  // count for FAT16 zero for FAT32
  rootDirEntryCount_ = bpb->rootDirEntryCount;

  // directory start for FAT16 dataStart for FAT32
  rootDirStart_ = fatStartBlock_ + bpb->fatCount * blocksPerFat_;

  // data start for FAT16 and FAT32
  dataStartBlock_ = rootDirStart_ + ((32 * bpb->rootDirEntryCount + 511)/512);

  // total blocks for FAT16 or FAT32
  uint32_t totalBlocks = bpb->totalSectors16 ?
                           bpb->totalSectors16 : bpb->totalSectors32;
  // total data blocks
  clusterCount_ = totalBlocks - (dataStartBlock_ - volumeStartBlock);

  // divide by cluster size to get cluster count
  clusterCount_ >>= clusterSizeShift_;

  // FAT type is determined by cluster count
  if (clusterCount_ < 4085) {
    fatType_ = 12;
  } else if (clusterCount_ < 65525) {
    fatType_ = 16;
  } else {
    rootDirStart_ = bpb->fat32RootCluster;
    fatType_ = 32;
  return true;
Then, you just have to read the "error" attribute in "CardInfo" when the error occurs:

  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");


Mar 12, 2017, 05:15 pm Last Edit: Mar 12, 2017, 06:12 pm by Eimerkette Reason: (Added link to new topic.)
Hi _pepe_,

thanks for this hint.

I'll do it and report the corresponding error codes in a new topic.


Unfortunately, this utility formats the SD as FAT32, but the Arduino SD lib wants FAT16. So the tool is useless.


So the tool is useless
So are cars, if I dont know how to drive them. Or foreign languages I don't speak. They are indeed useless, but to me, not in general.
Only cause you're frustrated is no reason to be rude. People here are there to help you, not to bother you with useless crap   ;)
If google was a country, I'd move there.


Unfortunately, this utility formats the SD as FAT32, but the Arduino SD lib wants FAT16. So the tool is useless.
SD cards are designed to be formatted with a layout that matches the card's flash chips.  SDFormatter produces the optimal layout by inserting hidden sectors to adjust the layout to chip boundaries.  SDFormatter chooses an appropriate cluster size.  There are no options for the standard format.

SDFormatter uses FAT12 for very small cards.  FAT16 is used for cards <= 2GB, FAT32 for cards <= 32 GB, and exFAT for cards larger than 32GB.

The SD library supports FAT16/FAT32 and is optimized for the layout SDFormatter produces.


Feb 06, 2018, 03:44 pm Last Edit: Feb 07, 2018, 01:46 am by soundlord
I do use the OS utilities to format an SD card but I use a more flexible OS -> Linux. So your advice is correct for Windows users but Linux users should use the internal command as the SD card association doesn't provide a formatting tool for Linux.

So on Linux users may issue the command:

Code: [Select]
mkfs.vfat -F 32 -s 64 -S 512 /dev/sdb1

given that the card is available as /dev/sdb on the system.
This command does the same as the formatter from the SD card association (use 32kB clusters with a FAT32 file system).
Never worked for me... SD.begin(cable select slot) returns 0.


In fact you have to (using Linux):

1. have root rights  (su root)
2. in bash (shell) --> msdosfs -I /dev/sdd (assuming /dev/sdd is the sdcard device)
3. in arduino 1.8.5 --> verify you installed the SdFAT library
Use the example called SdFormatter
4. Change the cable select port to 4 for the arduino with LCD module with SD card reader
5. Load the program in the arduino and follow the instructions using the serial monitor


Go Up