How To Use SD Card with Arduino

by Oscar

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.

Some of the links on this page are affiliate links. I receive a commission (at no extra cost to you) if you make a purchase after clicking on one of these affiliate links. This helps support the free content for the community on this website. Please read our Affiliate Link Policy for more information.

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);

Leave a Comment

By using this form, you agree with the storage and handling of your data by this website. Note that all comments are held for moderation before appearing.

18 comments

sravya 22nd October 2019 - 10:20 am

hi i connected sd card interfacing with Arduino uno and i given pin description MOSI 11, MISO 12, SCK 13, CS 10, iam try to save the ultrasonic sensor values in sd card excel format if any body can know this please reply me thank you

Reply
Necip ŞAHİN 5th May 2019 - 1:56 pm

hi all. I have an issue. I can’t dir in my sd card with this procedure, void printDirectory(File dir, int numTabs) , just it is listing lost.dir but if I use “root.ls(LS_R | LS_DATE | LS_SIZE);” prosedure, it can list a lot of files. Do you have an idea about this issue?

Reply
nizar anambas 2nd February 2018 - 12:45 pm

hi, help me please, i want to make time bell using sd card with comment on notepad text.
for example if time chose is correct the mp3 can be play follow song file name.
thank you

Reply
rehna 21st January 2018 - 1:24 pm

Can we use to locate our saved locations on gps through arduino with the sd card

Reply
andre de bruijn 9th April 2017 - 8:07 am

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
Arjun 4th December 2016 - 7:55 pm

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
Alf 4th December 2016 - 4:07 pm

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
Elia Herrzberg 30th November 2016 - 8:20 am

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
GURLEEN KAUR 7th November 2016 - 11:46 am

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
matthias macherey 28th November 2016 - 5:37 pm

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
Jim Summersides 18th March 2016 - 10:53 am

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
Eric 4th December 2015 - 3:52 pm

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
Christian Duke 27th February 2015 - 11:55 pm

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
Michael 3rd February 2015 - 12:24 am

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
Bob 2nd November 2014 - 3:12 pm

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
Buddhika Mawella 29th October 2014 - 6:57 am

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
Oscar 29th October 2014 - 9:59 am

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
Michael 3rd February 2015 - 12:18 am

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