A Micro-SD card for the Arduino

A Micro-SD card for the Arduino

The SD card is the de facto standard storage device for the Arduino, due to its relative ease of use. We will connect one to the Arduino Uno and do a few simple tests to see what we can do with an SD card. In this example, we are using the microSD card (or TransFlash, or µSD).

The Arduino Uno hooks to the SD card using the SPI interface on the SD card module. It is a 4-wire interface, meaning it has the three SPI signals (SCK, MISO, MOSI) plus a chip select line to tell the SD card to listen and talk. Make sure the module is a 5 volt module! SD cards are 3V devices, and 5V will damage them. This SD card module has a 3.3V regulator, and a level shifter to keep the SD card from getting 5V on any pin.

For this tutorial we hooked the SD card to the Arduino Uno using jumper wires about 4 inches long. We are first going to read the SD card to see what is on it. The card must have previously been formatted on a Linux, Mac or Windows computer using the FAT-16 or FAT-32 format. There is no other option for Windows but it is selectable at format time for Linux and Mac.

The example program, "CardInfo", reads the SD card and prints out the files found. A freshly formatted 1GB µSD card looks like this (formatted using Windows):

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

Card type: SD2

Volume type is FAT32

Volume size (bytes): 984084480
Volume size (Kbytes): 961020
Volume size (Mbytes): 938

Files found on the card (name, date and size in bytes): 
SYSTEM~1/     2016-02-19 18:22:40
  INDEXE~1      2016-02-19 18:22:40 76
	

A 32GB card looks like this:

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

Card type: SDHC

Volume type is FAT32

Volume size (bytes): 3468689408
Volume size (Kbytes): 3387392
Volume size (Mbytes): 3308

Files found on the card (name, date and size in bytes): 
SYSTEM~1/     2016-02-19 18:20:14
  INDEXE~1      2016-02-19 18:20:14 76
	

Oops! Where did the other 29GB go?

There are limitations to the size of the SD card. 3.2GB appears to be the maximum. It will still read and write the card, but it will treat it as a 3.2GB card.

/*
  SD card test

 This example shows how use the utility libraries on which the
 SD library is based in order to get info about your SD card.
 Very useful for testing a card when you're not sure whether
 it's working or not.

 The circuit:
  * SD card attached to SPI bus as follows:
 ** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
 ** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
 ** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
 ** CS - depends on your SD card shield or module.
 		Pin 4 used here for consistency with other Arduino examples

 created  28 Mar 2011
 by Limor Fried
 modified 9 Apr 2012
 by Tom Igoe
 */
// include the SD library:
#include <SPI.h>
#include <SD.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
const int chipSelect = 4;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("\nInitializing SD card...");

  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin?");
    return;
  } else {
    Serial.println("Wiring is correct and a card is present.");
  }

  // print the type of card
  Serial.print("\nCard type: ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' -
  // it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\n");
    return;
  }

  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();

  volumesize = volume.blocksPerCluster();
  volumesize *= volume.clusterCount();   
  volumesize *= 512;                     
  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);


  Serial.println("\nFiles found on the card: ");
  root.openRoot(volume);

  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
}


void loop(void) {

}
	

Listing the Files on the SD Card

You can list the files in the directory of the SD card by opening the directory using a directory object, and then reading the list of files from it.

#include <SPI.h>
#include <SD.h>

File root;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

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

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  root = SD.open("/");

  printDirectory(root, 0);

  Serial.println("done!");
}

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

void printDirectory(File dir, int numTabs) {
   while(true) {
     
     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');
     }
     Serial.print(entry.name());
     if (entry.isDirectory()) {
       Serial.println("/");
       printDirectory(entry, numTabs+1);
     } else {
       // files have sizes, directories do not
       Serial.print("\t\t");
       Serial.println(entry.size(), DEC);
     }
     entry.close();
   }
}

	

The directory on an "empty" card formatted on OS X looks like this:

Initializing SD card...initialization done.
SYSTEM~1/
	INDEXE~1		76
~1.TRA		4096
TRASHE~1/
SPOTLI~1/
	STORE-V2/
		117591~1/
			PSID.DB		8192
			TM~1.SNO		0
			TM~1.LIO		0
			LIO~1.CRE		0
			TMP.CAB		0
			CA~1.CRE		0
			INDEXS~1		28
			~1.IND		4096
			~~2.IND		32768
			~~~3.IND		3277
			~~~~4.IND		4096
			~~~~~5.IND		8192
			~~~~~~34.IND		4096
			~~~~~~37.IND		8192
			~~~~~~40.IND		8224
			~~~~~~43.IND		1024
			~~~~~~46.IND		65536
			~~~~~~48.IND		1037
			~1.DIR		65536
			LIVE~1.IND		4096
			LIVE~~2.IND		32768
			LIVE~~~3.IND		3277
			LIVE~~~4.IND		4096
			LIVE~~~5.IND		8192
			LIVE~~69.IND		4096
			LIVE~~72.IND		8192
			LIVE~~75.IND		8224
			LIVE~~78.IND		1024
			LIVE~~82.IND		65536
			LIVE~~85.IND		1462
			LIVE~1.DIR		65536
			STORE.DB		118784
			STOR~1.DB		118784
			REVERS~1		65536
			TMPSPO~1.STA		4096
			JOURNA~1.1		0
			STORE_~1		4
			JOURNA~1.COR/
			JOURNA~1.LIV/
			JOURNA~2.LIV/
			JOURNA~3.LIV/
				JOURNAL.1		38
			JOURNA~4.LIV/
			JOURNA~1.ASS/
			JOURNA~2.ASS/
			JOURNA~1.HEA/
			JOURNA~1.MIG/
			JOURNA~2.MIG/
			JOURNA~1		0
			JOURNA~1.SCA/
				JOURNAL.1		71
				RETIRE.1		0
			SHUTDO~1		4
			REVERS~1.SHA		3136
			~1.SHA		4096
			~~2.SHA		376
			~~~3.SHA		0
			~~~~4.SHA		65536
			~~~~~5.SHA		8
			~~~~~164.SHA		2056
			0DIREC~1.SHA		1088
			~~~~~171.SHA		2
			LIVE~1.SHA		4096
			LIVE~~2.SHA		0
			LIVE~~~3.SHA		0
			LIVE~~~4.SHA		65536
			LIVE~~~5.SHA		8
			LIVE~191.SHA		2056
			LIVE0D~1.SHA		1088
			LIVE~199.SHA		1
			STOR~1.UPD		12
			REVERS~1.UPD		2
			PERMST~1		553
			TMPSPO~1.LOC		10065
			JOURNA~1.REP/
			CA~1.MOD		0
			JOURNA~1.2		264
	STORE-V1/
		VOLUME~1.PLI		348
	VOLUME~1.PLI		4000
done!
	

You can also read and write files on the SD card. This is done by first opening the file for read or write, then actually reading or writing data. In this case, we will write and then read "test.txt".

/*
  SD card read/write

 This example shows how to read and write data to and from an SD card file
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4

 created   Nov 2010
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe

 This example code is in the public domain.

 */

#include <SPI.h>
#include <SD.h>

File myFile;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

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

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.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) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

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

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

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

The following should print when the program runs:

Initializing SD card...initialization done.
Writing to test.txt...done.
test.txt:
testing 1, 2, 3.
testing 1, 2, 3.
	
Arduino Board Logo

 

Arduino-Board is the go-to source for information on many available Arduino and Arduino-like boards, tutorials and projects.

Help and Support

Arduino-Board

Stay updated

Sign up if you would like to receive our once monthly newsletter.