Go Down

Topic: Compiling an SD/MMC and fat16 library (Read 16651 times) previous topic - next topic


Hi, I'm trying to get the software library found here http://www.roland-riegel.de/sd-reader/index.html to work with the arduino. I've successfully got it compiled to object files using the same flags in the makefile that comes with the library and avr-gcc that came with arduino0010 dev environment. I placed the obj files and headers into a directory in the libraries folder so they appear as an included library. However, if I add any of the included files to a project using #include <>, it immediately blows out over the max size of the atmega168.

The code and library I am trying to get work was developed on an atmega168 so it should work. I've checked some of the other libraries and the stepper motor library is compiled to almost the same size as the sd card raw access library. I'm wondering if I've compiled it wrong or done something incorrect. The code is standard C.

Any ideas would be appreciated.  


Here are a couple of random thoughts:

It may have been developed on a 168, but was it developed on a 168 with a 2k bootloader leaving only 14k of program space?

Are you linking against a library (libwhatever.a) or an object file (something.o)?  If you link against the object file, everything gets stuck in the executable.  If you build a library and link against it, only the functions you actually use are included in the executable.



Thanks for the ideas. Yeah I compiled object files. But the object files are quite small (some are the same size as the stepper motor object files or matrix object files) so I'm wondering if I did something wrong when I compiled the code.

If I use #include <stepper.h> (or whatever it is) it uses up only a little code space. If I use #include <my compiled stuff> it immediately blows out over the size limit even though the compiled object files are similar size.

I'm thinking that my object files are compiled somehow wrong and that is what is causing the problem.



I have been experimenting with those libraries from Roland for some time now and also managed to successfully compile them. But, unfortunately, the only way of pushing them in the mega168 is getting rid of the bootloader. The hack to be made is to clean Roland's code to be much smaller or just to work at the bytes level.

I have the thing working in an Arduino board and I can write/read files and directories. With no problem, but I had to use avrdude and avrispmkII to upload the hex file ... if you have those close to you, you can try it out just for the pleasure of seeing the thing running.



Thanks for that. Yeah I finally got it to all compile properly. I put the .c and .h files into a directory, renamed the .c to .cpp and it compiled automatically. I had to change a bit of the code as he uses the C99 standard and I don't know where to add flags when the arduino environment automatically compiles.

I probably will just use the low level read/write routines although the fat16 would be interesting. Just wanted to use robust sd/mmc access routines.


Hi all,

For the hardware part here is a good link (I've not tested it) http://uanr.com/sdfloppy/



This was a pretty ugly connection, at least with the floppy cable I tried.

Cheap SD card readers can be had for less than US$3, and every one I've looked at has a socket...



hey gang,

first i looked at arduino.cc for a mmc or sd card solution, but i didn´t found something attractive for my gps logger project.
So first i tried to get a sd card solution from Ulrich Radig http://www.ulrichradig.de/home/index.php/avr/mmc-sd to work, but that was too difficult for a greenhorn like me  to adapt to arduino.  
After i read this thread the 10th time i gave it also a try.
Why must you "talk" so crypted? ;-) Only a fog of usable information was around! *ggg* Only some needed steps were explained... the ".cpp" thing and so on... but you got that to work. Would have been very helpful with a fist full of information more, but who wants a perfect world?  8-)

Okay, what was interesting for me at R.Riegel http://www.roland-riegel.de/sd-reader/doc/index.html , that he says that you can use only the mmc part and simply leave out the fat part. http://www.roland-riegel.de/sd-reader/sd-reader_source_20071213.zip
That´s what i did, because thats enough, i only want the data stream of the gps.nmea on a BIG 1G sd card! So i can safe for sure some points of my movement profile.

For the circuit i took the simple one from Ulrich Radig, level shifting with  voltage dividers, each two resistors, works like a charme!

except for the diodes for vcc i used the 3.3V of the diecimilia. there was a reset at the first mount of the board with the sd card in the slot. so i think the FTDI chip got a reset because of a high init current >50mA? At mikrocontroller.net i read a not too small elko should help, that what i´ll add next on the hardware side. May be a 100uF? any suggestions? At the distributor reichelt.de i could read at some newer sd card, that they take a current <40mA. So this could work. Otherwise i´ll take a low drop regulator.

For the arduino i made a new folder in E:\Program Files\arduino-0010\hardware\libraries , called mmc. There i placed the following files:
sd_raw.cpp  sd_raw.h  sd_raw_config.h

They got easily compiled like extensively described above here.

For the first test i used the following code:
Code: [Select]
#include <sd_raw.h>
#include <sd_raw_config.h>

int incomingByte = 0;      // for incoming serial data

void setup() {
 Serial.begin(9600);      // opens serial port, sets data rate to 9600 bps
 //Initialisierung der MMC/SD-Karte
 Serial.print("System Ready!\r\n");      
 /* setup sd card slot */

 if( !sd_raw_init()   )
   Serial.println("** Keine MMC/SD Karte gefunden!! **");      

   Serial.println("Karte gefunden!!");
 struct sd_raw_info disk_info;

 Serial.print("manuf:  0x");
 Serial.print( disk_info.manufacturer,HEX);
 Serial.print("oem:    ");
 Serial.print( (char*)disk_info.oem);
 Serial.print("prod:   ");
 Serial.print((char*) disk_info.product);

 Serial.print("rev:    ");

 Serial.print("serial: 0x");
 Serial.print("date:   ");
 Serial.print("size:   ");
 Serial.print("copy:   ");
 Serial.print("wr.pr.: ");
 Serial.print("format: ");


void loop() {

 // not used for now:

This works (nearly), HURRAY!

Get the following output:
Binary sketch size: 4944 bytes (of a 14336 byte maximum)

System Ready!

** Keine MMC/SD Karte gefunden!! **
manuf:  0x0
serial: 0x35FF0102
size:   4027073545

some characters are not displayable here.
Where it says, no card found ("** Keine MMC/SD Karte gefunden!! **"), i think it would need only a bit more time for the init?
The later card information seems to be no problem.

Okay, enough for today, hopefully the read write test will follow tomorrow! I pasted the dirty code in here, so others can use the information now and not sometimes. I plan also to add future additions if time allows it. There will also follow experiences with my navilock gps modul (30?, RS232 - me fool did not take the ttl one   :( so i had to add a max232 .... story will continue...)


And a big THANK YOU at all the arduino gang for doing an awesome job!


I pasted the dirty code in here, so others can use the information now and not sometimes.

Yay for releasing now! :D



Feb 15, 2008, 09:59 pm Last Edit: Feb 15, 2008, 11:19 pm by agent_orange Reason: 1
Nice, its a good library and makes reading and writing to the SD card easy. There are a few parts  in the sd_raw.cpp and config files that need to be changed to get reliable operation on the arduino.  Something that isnt obvious is that in the library he specifies pins 5 and 6 of analog in(2 wire interface)  as sensor pins for card insertion and read/write tab. You can disable that in the code but the easiest way to check if your code is working is to ground pin 5 and 6 of analog in. I found this out by accident when I was holding the arduino and tilting it and trying to figure out why it wasn't working. Every now and then it would find the card, my hand must have provided a ground.  ;D

I've gone through the code and commented out various bits and changed a few things so that it works well but have to go through and make sure that all the changes work ok and document what I've changed.

Anyway yeah ground analog pin 5 and 6 and it should work.

If you want to remove the code then look in the config.h files and comment out where he defines PortC 5 and PortC 4 pins. Then remove the code that checks for memory card insertion (there's 2 functions and some code in the sd_init function) and it should work fine. If you want to leave it then you'll have to connect your memory card socket to the 2 pins for insertion and read/write checking or ground the pins.

Also if your after an SD card socket this looks nice (i found this after I'd de-soldered a memory card reader to get the SD socket lol)


Oh and just for interest,  I got the FAT library compiled and running on the arduino, however I had to do quite a few changes as he uses the C99 standard and I couldn't add that flag in arduino environment. I didn't get it working fully and kept getting a few errors. I gave up in the end because it just fits into the atmega168 memory and leaves little room for anything else. You can only run a few functions before you have no room at all left. It would be good to get it running once the larger size memory atmegas are available for the arduino environment.

Much easier to write to a text file on the memory card, pull it out and chuck it in your computer to read your values!  ;)


Some short information: At the moment i have difficulties to understand really how this functions work with the "*" thing at the variables. Have to read more about C, i think. For example: uint8_t sd_raw_write_interval(uint32_t offset, uint8_t* buffer, uint16_t length, sd_raw_write_interval_handler_t callback, void* p); The Example code is extensively about the fat part, but not so for the sd_raw part.
Any help is welcome!

Also i found a forum thread, regarding to the development of this library. It´s very interesting, but sorry folks, only in german.
One configuration hint i found:

#defines ändern:
#define configure_pin_available() DDRC &= ~(1 << DDC4)
#define configure_pin_locked() DDRC &= ~(1 << DDC5)
#define get_pin_available() ((PINC >> PC4) & 0x01)
#define get_pin_locked() ((PINC >> PC5) & 0x01)

Wenn Dein Slot keine Pins zum Detektieren einer Karte bzw. der Position des Schreibschutzschalters hat, änderst Du diese ab zu:
#define configure_pin_available()
#define configure_pin_locked()
#define get_pin_available() 0
#define get_pin_locked() 0
Im Makefile änderst Du folgende Zeilen passend ab:
MCU := atmega168 MCU_AVRDUDE := m168 MCU_FREQ := 16000000UL


it´s about the file "sd_raw_config.h":
It means if you don´t have available-pin and locked-pin connected you should change it like in the second part of the above, with the zero at the end. The defines for the atmega168 should be fine, i think. The makefile is not of interest, i believe.
I´ll read more in that thread and will post the interesting things here.

And i´ll try that ground thing, thank you!

more to learn, more to come soon...


Feb 16, 2008, 01:37 am Last Edit: Feb 16, 2008, 01:39 am by agent_orange Reason: 1
That define thing is handy, saves all my hacking in the library, much neater this way!

This code should write 2 bytes to the SD card starting from memory location 0. Then read them back into the tempBytes array. If you were writing your NMEA string, then read it in from serial port into an array of correct length of the string(i.e. 16 bytes or 32 or whatever an NMEA string is) then write that array to a memory location.  It's pretty easy, try this example code.
Code: [Select]

// Define an array for storing data.
byte tempBytes[2];
// Store some example numbers

// Write the 2 bytes stored in tempBytes to memory location 0

// Zero the tempBytes array to make sure read works ok.

// Read 2 bytes starting from memory location 0 into tempBytes print to serial output.



that code really helped! thanks a lot! Works perfect!

At the moment i am still over it, run i a little question ... What about the 3.3V! I believe i read some time ago it´s only powered when connected to usb, got it from ftdi chip? Is that right? So i would need for sure an additional voltage regulator for external power supply.
Does someone know exactly?

Now i have arduino connected to usb with a kingston 1G card in the slot. Powered from diecimilia 3.3V supply and added a 0.47uF Elco to 3.3V power supply of the card. For the moment no problems with it.

First i will power the board with 9V alkaline for testing, later a 3.7VLiPo with stepUp. (does someone have a circuit for that? Will also add an Max1811 for LiPo charging when on usb. Have the max appnote for that.
But if someone has a working version for arduino would be fine.)

Nice sun at the moment here, hopefully get it working for a walk in the outside soon!


i will think before i post..  ;D

got the simple answer about 3.3V 2min later with measurement equipment: 3.3V pin works with a 9V alkaline.

Go Up