Go Down

Topic: SD/MMC From the ground up (Read 59290 times) previous topic - next topic


Here's some code that will print a directory listing of files on the card.

Note: it relies on the PROGMEM print routine available in the device print demo sketch

Add this first clip to the code at some point after the mmc and uFat initialisation:

Code: [Select]
 int count = 0;
 print_P(PSTR("Directory of files on card:\n\n"));

 microfat2::walkDirectory(showDirectory_walkerfn, &count);

 Serial.print(count, DEC);
 print_P(PSTR(" files found.\n\n"));

Then add this subroutine to the sketch somewhere above the setup() function:

Code: [Select]
bool showDirectory_walkerfn(directory_entry_t* directory_entry_data, unsigned index, void* user_data)
 int* count = (int*)user_data;

 Serial.print(index, DEC);
 Serial.print(' ');

 // Terminate the filename string.  
 // This is deliberately corrupting the buffer data, but that's ok.
 directory_entry_data->filespec[11] = 0;


 // Increase 'seen file' count
 *count = (*count)+1;

 // don't stop
 return false;

Your reward will be a list of the files which uFat is able to see. This should help in the cases where mmc & uFat initialisation succeeds, but nothing is found on the card. Note: the directory walker loop excludes deleted files, directories and files with long names.



May 11, 2009, 06:11 pm Last Edit: May 11, 2009, 06:14 pm by CWAL Reason: 1
I have the demo up and running fine, thanks so much for your code, it does exactly what I need!

(Although it did take me forever to find a working demo, I copied it from this thread.  The current zip file only have the libraries, no examples)

I do have one question, however.  What are the advantages/disadvantages of using PROGMEM?  From what I can tell, it's writing to the flash memory.  Won't that reduce the lifetime of the flash in my arduino?

I was under the impression that PROGMEM was generally used to write a constant string that never changes while a program runs, and thus it only writes to flash once.  In your code it looks like it's being used as a buffer, being written/read from pretty frequently..



We only read from PROGMEM, your impressions are correct. The data is written to an intermediate buffer in SRAM and then to the card.

The advantages of storing your constant data in PROGMEM is that it leaves the RAM free for things that RAM does best.



Okay, thanks.  I still haven't managed to find the example sketches, I've been over every thread I can find on the forums and google related to uFat.  Could someone please link to them?


Here you go:


It's not a great demo, but it shows everything you need.

I really should update it  :D


May 13, 2009, 03:40 am Last Edit: May 13, 2009, 03:40 am by rhb123 Reason: 1
How does this solution compare to the FileLogger library?


One difference is that with FileLogger you have to create the file, but you don't have to pre-allocate the size.  

I'm curious as to the difference in data bandwidth and code space.

NOTE: They both use 'mmc' sub-files which are not the same, so if you want to try both be aware of this.


I haven't used filelogger, I suspect it utilises FAT 'properly'. The trade-off is speed and sketch size. It requires far more grunt to navigate the file allocation tables and ensure a consistent file system.

Perhaps people could post of their experiences?



Since I have used both DevicePrint and FileLogger and you ask for experiences, I will share mine. While both libraries represent a lot of creative work, and both are a real asset to the community, there is still some value in comparing the two.

Functionally, they both do a great job in appending to what becomes a "proper" FAT file on the SD card. Resource wise, I think the FileLogger is somewhat smaller at the stated 3601 bytes. I found the 'self adjusting' file size in FileLogger to be more convenient over the fixed file size as I did not need to anticipate the maximum file size, and can therefore switch to a bigger card when I need to.

For my application, I was not comfortable with having to use PROGMEM. This might be a personal issue, but I find PROGMEM to be somewhat arcane, and since I store my strings in EEPROM, redundant. It was indicated that I was "allowed" to bypass it in DevicePrint, but the comments in the source said otherwise.

Both libs use the mmc  lib to do the grunt work, however there are differences. RD123's warning is correct about trying to have both DevicePrint and FileLogger coexist in the same build environment. Part of this is due to the directory structure. DevicePrint sees mmc as a separate lib in the libraries folder while FileLogger finds it in it's own folder.

A more important difference, however, is that FileLogger now uses a modified version of the mmc lib. I understand that this modification is optional, but basically it uses the SPI lib to handle the I/O rather than the direct port addressing that the mmc lib was using. This is an advantage for me in that it gives me the option of more easily changing the pins for the SPI that the SD write uses. (via #defines SPI.h)

The reason I cared about reallocating the pins is that with both DevicePrint and FileLogger I initially had a problem accessing a second SPI device after writing to the card. My second device (LedControl.lib) allows me to change the SPI pins and that is how I solved the problem. This may have worked for either lib. but now I have the option of changing the pins for both SPI devices, and thus the possibility of regaining some of the pins I had to give up. (I have not tried this yet.)

My, I must have too much time on my hands, but perhaps this may prove useful. I hope this is taken in the sprit in which it's written and I again thank both authors for their contributions and commitment.  :)

"Data is not information, information is not knowledge, knowledge is not understanding, understanding is not wisdom."
~ Clifford Stoll


I tried the filelogger library before.  While it is nice to append data to the file and grow it, the library always failed to initialize the card on the first write attempt, and inserting an SD card would do weird things with the serial port...


Jun 28, 2009, 10:15 pm Last Edit: Jun 28, 2009, 10:22 pm by jackie Reason: 1
Ok I finally made it to the end of this thread trying every possible solution posted of my problem but I am still getting the following error when running serial monitor on DevicePrintDemo.pde  =

Code: [Select]

uFat / DevicePrint Demo
2009 arduinonut.blogspot.com

Error  Couldn't initialise card

Even though I don't think the program went as far as searching for data.txt I put it in there in FAT16, FAT32, different file sizes, reformats, etc. I tried using a 2GB and a 8GB microSD card with the Libelium adapter (http://www.libelium.com/tienda/catalog/product_info.php?cPath=21&products_id=66). When I take out the SD and run serial monitor it shows the same error but it takes about 15 seconds to show "Couldn't initialise card" instead of about 2 seconds with the card in.

I am able to write to the card using the SDuFat library but I am trying this one since I can't seem to figure out how to print variables, can only print txt with the SDuFAT for some reason as explained in my help post here = (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1246090486

Could it be that the Libelium adapter doesn't work with this library? I hope someone can help, I have been reading and working on this for hours now :(


I've been using the SD/MMC Mini Board from FUTURLEC
And, mainly, the code from sirmorris' devicePrintdemo.

The problem with FUTURLEC, is that it takes almost a month, after you have placed the order, to receive the parts.  But thje price of the SD/MMC Mini Board is only $6.90.  (I live in the USA).  It is preassembled and easy to use.

I use a Kingston 1GB SD card to store data, which can be bought at any computer store. probably even at Wal-Mart.

I use an arduino compatable RBBB (really bare bones board), with an arduinoized atmega168, and a USB conversion board. (for programming via USB)

I'm sorry, I can't help more with your problem;  I don't know what board or microcontroller you are using.  (Under TOOLS > BOARD, have you checked the proper board?)  Proper serial port? (getting on the proper port can be a little confusing)

After the SD card is formatted, you need to load the card up with a bunch of 'stuff', data of any kind, for instance just a bunch of (cccccccccc)'s,  then put that 'stuff' in a file, on the card, and name the file, BUT when you name the file, just name it 'data', leave off the '.txt', as that will be put on automatically.  Otherwise, if you add the'.txt', you will end up with a file named 'data.txt.txt', which won't work.

You're probably aware of all this stuff.


I am using the atmega 168 on windows xp. I know it is connected fine, did the standard tests. I did the txt file. I don't think the program even got far enough to checking the txt file since the error I got is checked for before checking for any txt file errors. Maybe I will try another board, has anyone got this working with the libelium board?


These are at SPARKFUN

They are a bit more costly than FUTURLEC, though, but will be received in much less time.

As far as the operation of the code, you will probably need to contact sirmorris, or wait for him to reply.  Or one of the other more knowledgeable members. ::)

We don't know which board you are using, there are several choices under:  ARDUINO-0014 > TOOLS > BOARD > Diecimila/Duemilanove w/atmega168,  Arduino NG  or older w/atmega168, etc, etc.



Jun 29, 2009, 10:49 pm Last Edit: Jun 29, 2009, 10:50 pm by garinus Reason: 1
does anyone know how can i connect an sd with an arduino mega?
with the 2009 i can but with the mega dont compile

thanks to all

and excuse my english


I saw the sparkfun ones, they are just breakout boards, is that all I need? No resisters, capacitors, etc between the SD and the pins on my Arduino? If so can't I just solder some wires directly to the correct SD pins and wire to the correct Arduino pins or do I need some components in between?

I am using the Duemilanove w/atmega328

Go Up