How To Use SD Card with Arduino

Just a quick walk through how to use the SD card module with Arduino. It is the same for Micro SD card modules. The Arduino official site provide a library for this purpose, and I will describe how I used this library and explain what each function does.

The Type of SD Card Module

I have not tested this library with all the SD card modules, but I think it should work for majority of them, unless you are told by the seller that you should use a different library.

The Library uses standard SPI interface for communication, which hasSPI buses, MISO, MOSI, SCK (CLK) and a chip select signal pin, CS.

Connection With Arduino

[pic]

** MOSI – pin 11
** MISO – pin 12
** SCK (CLK) – pin 13
** CS – pin 4

Libraries

The default Arduino library for SD card is huge! With the example read/write sketch, when compiled it’s 13690 Bytes which is half of the available flash space on an Arduino pro mini!

So if you are tight in sketch space, it’s a good idea to find a smaller library. Depends on the SD cards you have and the format you want to use, you have these options.

FAT32 Format (larger than 2GB)

FAT16 Format (smaller than 2GB)

I haven’t tested all of these libraries, so do your research and test them before using it. Here I will show you how to use the Arduino SD library.

How To Use the Arduino SD Library

The SD library comes with the Arduino IDE, so you don’t need to download it. It needs to be include at the beginning of the sketch.

#include <SD.h>

Including `SD.h` automatically creates a global “SD” object which can be interacted within a similar
manner to other standard global objects like “Serial”.

The Available SD Card Module Functions

Read from SD card

First you need top open the file first.

File dataFile = SD.open("datalog.txt");

It will return false if it fails to open the file, so check dataFile before using it. The “read” function reads the file line by line, so you will have to use a while loop, until it fail to reach the end of the file. Now you can write to the file using this.

if (dataFile) {
  while (dataFile.available()) {
    Serial.write(dataFile.read());
  }
  dataFile.close();
} 

else {
  // if the file isn't open, pop up an error:
}

Note that you need to close the file after finished reading it. Also, you can only open one file at a time, if you want to read the next file, you need to close the current file first.

Write to SD card

First you need to open the file  you want to write to with “FILE_WRITE” parameter.

File dataFile  = SD.open("test.txt", FILE_WRITE);

The “open” function takes two parameters, file location and  mode (only required for “Write”, if missing by default it opens the file in Read-Only mode). It will return false if it fails to open the file, so check dataFile before using it. Now you can write to the file using this.

if (dataFile) {
  dataFile.println("writing data to test file");
  dataFile.close();
} 
else {
  // if the file didn't open, do something here
}

Note that you need to close the file after writing to it. Also, you can only open one file at a time, if you want to open the next file, you need to close the current file first.

Check if a File Exists

// Check to see if the file exists: 
 if (SD.exists("example.txt")) {
    // example.txt exists
 }
 else {
    // example.txt doesn't exist
 }

Create a Text File on SD Card

There isn’t a function for this purposes, but you can open a file with “FILE_WRITE” mode to create a file, if this file doesn’t exist.

// To create a text file, we can open a new file and immediately close it:
 dataFile = SD.open("example.txt", FILE_WRITE);
 dataFile.close();

Delete a File on SD card

SD.remove("example.txt");

List All the files on SD card

There isn’t a function for this in the library, but we can create a custom function to achieve this purpose. This function is from the example sketch in the Library. It prints the file directory to serial monitor.

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("tt");
       Serial.println(entry.size(), DEC);
     }
     entry.close();
   }
}

Testing SD card or Get SD Card Information

Sd2Card card;
SdVolume volume;
SdFile root;

const int chipSelect = 4;   // 4 for Arduino boards, might be different in other non-Arduino boards.

// 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 is inserted?");
	Serial.println("* Is your wiring correct?");
	Serial.println("* did you change the chipSelect pin to match your shield or module?");
	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.nMake sure you've formatted the card");
	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();    // clusters are collections of blocks
volumesize *= volume.clusterCount();       // we'll have a lot of clusters
volumesize *= 512;                            // SD card blocks are always 512 bytes
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 (name, date and size in bytes): ");
root.openRoot(volume);

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

14 thoughts on “How To Use SD Card with Arduino

  1. andre de bruijn

    hello everybody,

    I cannot figure out whi my SD.remove line ins’t working:

    assuming the file exists….

    works:
    SD.remove(“1244.log”);

    does not work:
    String filename=”1244.log”;
    SD.remove(filename);
    error: no matching function for call to ‘SDClass::remove(String&)’

    or

    does also not work:
    String filename=”1244.log”;
    SD.remove(filename.c_str()”);
    error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]

    but !!

    when using for example SD.open….

    myFile = SD.open(filename.c_str(), FILE WRITE);
    or
    myFile = SD.open(filename.c_str());

    this works !!!!

    any ideas ????

    Reply
  2. Arjun

    Thanks Oscar. This was swell.. I’ve connected my arduino to a basic digital to analog converter (DAC) with an audio output. I want my arduino to play the song stored in my sd card. So do I Read from sd card or what else do i do? By the way, I’m new to using Arduino.

    Reply
  3. Alf

    Why are some words at the end of lines hyphen-
    ated like this? Is it my browser, or is it the server soft-
    ware doing this?

    Reply
  4. Elia Herrzberg

    Hi Oscar,

    I am trying to connect Arduino micro SD card reader to Arduino Nano.
    I will appreciate your response on the following:
    a. Pinout interfacing (to which pins on the Arduino nano should the MOSI,MISO, SCL and CS be connected)?
    b. Does the software routines and library elements such as TMRpcm work the same on Arduino nano?
    Thanks,

    Elia

    Reply
  5. GURLEEN KAUR

    Hii Oscar
    I have written one code to record tempsensor data on SD card getting error of file not opening can u pls help me out with write code . for your reference code has been enclosed below :-

    #include
    #include

    File myFile ;

    const int tempsensor=A0; // Assigning analog pin A0 to variable ‘sensor’
    float tempc; //variable to store temperature in degree Celsius
    float tempf; //variable to store temperature in Fahreinheit
    float vout; //temporary variable to hold sensor reading

    void setup()
    {
    pinMode(tempsensor,INPUT); // Configuring pin A1 as input
    Serial.begin(9600);

    while(!Serial)
    {
    ; //wait for serial communication and port to open
    }

    Serial.print(“Initializing SD Card…..”);

    pinMode(10,OUTPUT);

    if(!SD.begin(4))
    {
    Serial.println(“Initialisation Failed…..”);
    return;
    }

    Serial.println(“Initialization done….”);

    }

    void loop(){
    // read the value on AnalogIn pin 0
    // and store it in a variable
    int sensorVal = analogRead(tempsensor);

    // send the 10-bit sensor value out the serial port
    Serial.print(“sensor Value: “);
    Serial.print(sensorVal);

    // convert the ADC reading to voltage
    float voltage = (sensorVal/1024.0) * 5.0;

    // Send the voltage level out the Serial port

    myFile = SD.open(“data.csv” , FILE_WRITE);

    if(myFile) //Chk if its open ,print to file ,choose file
    {
    Serial.print(“, Volts: “);
    Serial.print(voltage);

    // convert the voltage to temperature in degrees C
    // the sensor changes 10 mV per degree
    // the datasheet says there’s a 500 mV offset
    // ((volatge – 500mV) times 100)
    Serial.print(“, degrees C: “);
    float temperatureC = (voltage – .5) * 100;

    Serial.print(temperatureC);
    myFile.print(temperatureC);

    myFile.print(“,”);
    Serial.print(“,”);

    // convert the celcius value to fahrenheit to display for Americans
    Serial.print(“, degrees F: “);
    float temperatureF = (temperatureC * 9 / 5 + 32);

    Serial.println(temperatureF);
    myFile.print(temperatureF);

    myFile.close();
    }
    else //if dont write to file , give an eerror

    {
    Serial.println(“Error in opening File”);
    }
    // if the current temperature is lower than the baseline
    // turn off all LEDs

    delay(5000);

    // delay of 5000 millisec for the next data to be recorded
    }

    Reply
    1. matthias macherey

      Hi, I’m not a professional, but right now i’m also starting with programming arduino with read an write to SD cards.

      – First of all: Since you have no compiling error, i assume that the “#include” statements are different in your original file?! better looks like #include , #include or something like that ;-)
      – The program itself doesn’t look so much different from mine, so maybe your hardware connection isn’t right (Uno: SCK=13, MISO=12, MOSI=11, CS = Pin 4 as in SD.begin(4); but depends on board), your SD card is not proper formated or faulty.
      – As far as i know, the port address is of type “uint8_t” so that you could write “static const uint8_t tempsensor=A0;” But that should not produce an collision with card and sensor?!
      – I start the file name with “/” for the root directory, like myFile = SD.open(“/data.csv” , FILE_WRITE);
      – Maybe you should do all the calculation stuff, before opening the file and writing.
      – if your programm is running, and you use your board for a temperature logger, wich runs on battery, you should consider a interrupt and power functions to save energy

      and now to my problem:
      – how do i erase bytes/characters from my file?
      i tried to open a second file, then to copy all the stuff besides the deleted ones in that file and…
      … failed to rename that file, to the name of the original one (that was deleted before)
      – when i copy all the bytes from the original file to the “temporarely” one, the file is shorter. Which byte signals the end of the file? file.write(EOF); file.flush(); did compile, but after printing the file shows a strange ‘y’-character with two dots over it ;-)

      Maybe i should use a different library. Thanks a lot
      matthias

      Reply
  6. Jim Summersides

    hi Oscar I am having ploblems compling any of the sd card examples a second time keeps coming up with errors.
    if I exit out of the ide and start again it will compile but not if I change something or recomple it with no chsnges.

    Reply
  7. Eric

    Hi Oscar,
    I try to remove several files from SD CARD in one shot. For some reason the program get stucks.
    If I do the same sequence line after line, it will work even if the file has been removed and there is no such file anymore.
    Of course, it’s better to do it in a loop rather then putting 4 or 5 times 100 lines…
    Any idea ? Your help will be appreciated.

    String fileExt = “_LIN.DAT”;
    for( int j = 1; j < 100; j++) {
    String fileName = j + fileExt;
    Serial.println(fileName);
    if (SD.exists(fileName)) {
    SD.remove(fileName);
    delay(500);
    }
    }
    Thanks in advance and regards.
    ericyonter AT hotmail.fr

    Reply
  8. Christian Duke

    Sir. Is it possible to get the latest file based on the date on SD Card Module and send it to a number using GSM Module. If yes, can you make a tutorial with it? Thank Sir. More power!

    Reply
  9. Michael

    Nice tut! I had to add the following lines to any examples i tried because im using the ethernet shield v2.2 on MEGA2560ADK.
    const int8_t DISABLE_CHIP_SELECT = 10
    pinMode(DISABLE_CHIP_SELECT, OUTPUT);
    digitalWrite(DISABLE_CHIP_SELECT, HIGH);
    This code disables the selection of the ethernet chip that shares the SPI bus.
    Works fine under Linux mint 17.1 with Arduino IDE 1:1.0.5+DFSG2-2.

    Reply
  10. Bob

    Oscar
    I want to use the data collected on the SD to compare sensor readings being gathered on arduino realtime. So here is my need…If I collect an unnamed amount of rfid numbers say 1000 and want to compare my database on the SD and return an accept or reject to a output on the arduino. how is this compare possible or is it.

    Bob

    Reply
  11. Buddhika Mawella

    Hello,
    Thanks for your nice article. I am going to write some simple texts data into SD card.
    But in my arduino project I have already used pin 11, pin 12 and pin 4 already. So can I use another digital pins instead of pins mentioned in above tutorial? Is it mandatory to use SPI pins for this?

    Thanks,

    Reply
    1. Oscar Post author

      Hi, not really. The pins 4, 11, 12, 13 are SPI pins, you will have to free these pins up somehow if you want to use SD card module.
      Regards
      Oscar

      Reply
    2. Michael

      YES, you can. ” A feature to use software SPI is available. Software SPI is slower
      than hardware SPI but allows any digital pins to be used. See
      SdFatConfig.h for software SPI definitions.” -from readme.txt

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Are you Robot? *

I only check blog comments once or twice a week, if you want a quick reply you can post your question on this forum IntoFPV.com... You might get a faster response from me there (multirotor related only).