Arduino Forum

Forum 2005-2010 (read only) => General => Exhibition => Topic started by: agent_orange on Mar 30, 2008, 12:57 pm

Title: SD card read/write with Arduino
Post by: agent_orange on Mar 30, 2008, 12:57 pm
I started a topic in the development section a while ago about getting an excellent sd/mmc card library (http://www.roland-riegel.de/sd-reader/index.html) working in Arduino. After lots of tinkering, and some help from another user (strohhalm who found some fixes in the german forum for the roland-reigel library) it seems to work ok. FAT reading and writing will have to wait until some larger memory arduinos are available as it uses almost all of the memory, leaving no space for further code.

The schematic uses some resistors in a voltage divider to drop down the arduino 5v logic to the sd cards 3v3 logic. So all outgoing signals from the arduino are dropped to 3v3. Incoming signals to the arduino are fine because 3v3 is above logic 1 for arduino. The 3v3 voltage supply from the decimelia was used to supply power to the sd card.

The schematic (all top resistors are 1.8k, all bottom resistors are 3.3k):

(http://img441.imageshack.us/img441/2391/schematicuo7.jpg)

The circuit built on a prototype board. I desoldered an sdcard socket from a broken memory card reader and then soldered pins onto the bottom. There is a thermistor connected to analog1 with some resistors for testing purposes. (The other stuff is a real time clock and its parts)

(http://img187.imageshack.us/img187/9002/sdcardrl9.jpg)

I've cutout all the unnecessary files from the roland reigel library and applied the fixes to leave just raw sd card reading and writing. This lets you write and read byte values from an sd card. It's very simple to use. I haven't tried to convert it to a cpp library. Copy the files into the library directory in the arduino build environment. (e.g. for me it is arduino-0011/hardware/libraries/SDcard ). Once you do that and restart the build environment you should be able to select SDcard as an added library and it will add the necessary includes.

The library can be downloaded here: http://www.mediafire.com/?2belzmmnzml
Title: Re: SD card read/write with Arduino
Post by: agent_orange on Mar 30, 2008, 01:02 pm
Here is the code for a very basic data logger which shows how to use the library. When the library starts it reads the card info and prints it out. It takes samples from analog in 1 and writes them to the sd card when you send an 's' over serial.  You can read back the sd card by sending an 'r'. Sending 'q' stops sampling.

I haven't done much testing about read and write speeds or buffer size, in this example I'm only storing 2 bytes in a temporary buffer and then writing them to the card.  

Code: [Select]

#include <sd-reader_config.h>
#include <sd_raw.h>
#include <sd_raw_config.h>





int print_disk_info();
int sample();
int readDisk();

byte incomingByte;
void printWelcome();
long int address;
byte tempBytes[2];


void setup()
{
 
 Serial.begin(9600);
 delay(1000);

 printWelcome();
 if(!sd_raw_init())
 {
    Serial.println("MMC/SD initialization failed");      
 }
 print_disk_info();
}



void loop()
{
   int i;    
   
   if(Serial.available()>0)
   {
        incomingByte=Serial.read();
   
      switch(incomingByte)
      {
          case 114:
                    readDisk();
                    break;
          case 115:
                    sample();
                    break;
          default:
                    break;
      }
   }    
}

int sample()
{
   int i,j;
   int temp;
   byte low;
   byte high;
   byte inByte;
   
   Serial.println();
   Serial.println();
   Serial.println("Sampling..");
   for(i=0;i<500;i=i+2)
   {
       if(Serial.available()>0)
       {
           inByte=Serial.read();
           if(inByte==113) return 0;
       }
       temp=analogRead(0);
       Serial.print(temp,DEC);
       Serial.print(" ");
       
       //Convert int to 2 bytes
       low=temp&0xFF;
       high=temp>>8;
      // Serial.print(temp,DEC);
       //Serial.print(low,DEC);
       //Serial.print(high,DEC);
   
       tempBytes[0]=low;
       tempBytes[1]=high;
       
       if(!sd_raw_write(i,tempBytes,2))
       {
         Serial.print("Write error");
       }
       //sd_raw_sync();
       delay(5000);
       
 Serial.println();
     
   }
   
   return 1;
}


int readDisk()
{
   byte low;
   byte high;
   byte info[2];
   int i;
   int  result;
   Serial.println();
   for(i=0;i<50;i=i+2)
   {
       sd_raw_read(i,info,2);
 
       //Serial.print(info[0],DEC);
       //Serial.print(" ");
       //Serial.print(info[1],DEC);
       low=info[0];
       high=info[1];
       result=high<<8;
       //result<<8;
       Serial.print(" ");
       Serial.print(result+low,DEC);
       Serial.print(" ");
   }
 
}

void printWelcome()
{
   Serial.println("------------------------");
   Serial.println("Data sampling system");
   Serial.println("send r to read disk");
   Serial.println("send s to start sampling");
   Serial.println("send q to stop sampling");
   Serial.println("Ready.....");
   Serial.println("-------------------------");
}


int print_disk_info()
{


   struct sd_raw_info disk_info;
   if(!sd_raw_get_info(&disk_info))
   {
       return 0;
   }

   
   Serial.println();
   Serial.print("rev:    ");
   Serial.print(disk_info.revision,HEX);
   Serial.println();
   Serial.print("serial: 0x");
   Serial.print(disk_info.serial,HEX);
   Serial.println();
   Serial.print("date:   ");
   Serial.print(disk_info.manufacturing_month,DEC);
   Serial.println();
   Serial.print(disk_info.manufacturing_year,DEC);
   Serial.println();
   Serial.print("size:   ");
   Serial.print(disk_info.capacity,DEC);
   Serial.println();
   Serial.print("copy:   ");
   Serial.print(disk_info.flag_copy,DEC);
   Serial.println();
   Serial.print("wr.pr.: ");
   Serial.print(disk_info.flag_write_protect_temp,DEC);
   Serial.print('/');
   Serial.print(disk_info.flag_write_protect,DEC);
   Serial.println();
   Serial.print("format: ");
   Serial.print(disk_info.format,DEC);
   Serial.println();
   Serial.print("free:   ");
 
   return 1;
}




Title: Re: SD card read/write with Arduino
Post by: tvdbon on Mar 30, 2008, 08:03 pm
Will this work on the atmega8 ?
Title: Re: SD card read/write with Arduino
Post by: unsped on Mar 31, 2008, 04:45 am
excellent, given the fat / sketch size limitation ... could you fit the sd/fat library on a atmega, then interface that chip with simple commands via i2c?

like have a master arduino and a slave arduino, the slave only handling sd/fat interactions.
Title: Re: SD card read/write with Arduino
Post by: The_Bongmaster on Mar 31, 2008, 05:56 am
would this be a good project for the dual core in this same section?
Title: Re: SD card read/write with Arduino
Post by: agent_orange on Mar 31, 2008, 12:00 pm
You have plenty of space if you don't use the fat library and just the raw sd card commands. Its just like having a 1G eeprom that is easy to use  :). Probably the best thing to do would be to wait until the atmega328p chip is available and works in the arduino and then you would have more than enough for the fat library and any code you want.
Title: Re: SD card read/write with Arduino
Post by: BigMike on Apr 04, 2008, 12:07 pm
That's good work, Mr Orange, and thanks for sharing.

Regards,

Mike
Title: Re: SD card read/write with Arduino
Post by: bisceglie on Jun 05, 2008, 05:40 pm
I'm having some trouble getting it working on a arduino Mini04. Everything worked when I tested it out on the Diecimila, but I'm getting the "MMC/SD initialization failed" message on the Mini.

Any ideas?

Regardless of my troubles, this is great!
Title: Re: SD card read/write with Arduino
Post by: melka on Jun 06, 2008, 03:53 am
Really nice! I was hoping to see something like that, that will really help me debugging my projects. For instance, for the monome clone, I can finally dump the serial received (well, I could have done it to the eeprom) as the serial communications isn't with the arduino IDE but with monomeserial, so I can't see real time what is received. This way, I save it, upload a new sketch, read the SD, and hopefully finish to implement the monome protocol ^^

Thanks again ^^
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Jun 26, 2008, 11:23 pm
You could also use my uFat library.

It's a kind of halfway-house solution between a full-fat and a fat-free solution. (Sorry couldn't resist it.) Basically you get to read and write sectors within files that you pre-allocate on a PC.

It's a really simple interface. 1. Get the base sector for a named file on the card. 2. Use it!

Naturally there's a couple of minor restrictions, but that's how trade-offs work, right ;)

Read more about uFat here: http://arduinonut.blogspot.com/2008/04/ufat.html

I'll be happy to help with any queries. PM or mail me.

Charlie
Title: Re: SD card read/write with Arduino
Post by: ladyada on Jun 28, 2008, 05:32 pm
if you just want to log data (and not necessarily read it) i have an sdlogging library that saves to fat16 formatted SD cards.  i use it to log GPS & sensor data: http://www.ladyada.net/make/gpsshield/download.html
Title: Re: SD card read/write with Arduino
Post by: worldgnat on Jun 28, 2008, 05:43 pm
If you want fat support, couldn't you theoretically throw it on the first portion of the SD card itself and then access it that way? I'm not intelligent enough to implement such a thing, but I thought I'd throw it out there. Would you have to modify the Arduino bootloader in order to get it to read a sketch from a foreign memory source? Is it even possible?
Title: Re: SD card read/write with Arduino (uFAT)
Post by: creatrope on Jul 02, 2008, 10:34 pm
Hi Charlie - your uFAT library looks interesting, but I haven't been successful with it so far.

Has anyone else gotten it working?

I have an SD setup just as described at the top of this thread. I am able to demonstrate 'raw' SD I/O successfully using the SD raw library and the demonstration sampling app with two different SD cards.

I have downloaded and built mmc1.rar and it compiles and upload successfully. You don't directly state the pinouts, but they appear the same as the schematic above from the code. It correctly detects the presence of the SD card (or its removal), but it never gets past mmc::initialize.

I'd love to get this working - any ideas for me to try?

Thanks, harry
http://www.creatrope.com/blog/make/uduino-arduino-board-support/

Title: Re: SD card read/write with Arduino
Post by: ducttapepro6 on Jul 04, 2008, 12:34 am
Mr. Orange-

I had no trouble getting your code up and running in 15 minutes - happily logging, saving, and reading the input to analog1.

However, after hitting the arduino reset button, I found that the read function returns junk(from the SD card).

Shouldn't the SD card retain data after a power cycle? or, is it a function of the code that you so nicely supplied to get me started - and I just don't understand it, yet?
Title: Re: SD card read/write with Arduino
Post by: creatrope on Jul 07, 2008, 09:51 am
Hi - I wanted you to know that I got the mmc1.rar code for uFAT working, just as advertised. My problem was that a makeshift 3.3v supply from a voltage divider seemed to work for the raw SD write, but not for the full uFAT mmc code.  

I cobbled together a 'real' variable power supply capable of producing 3.3v from http://www.ladyada.net/library/equipt/diypsupp.html, which worked flawlessly and the uFAT code worked correctly.

A few 'tricks':

Your card must be formatted FAT16, not FAT32. Under windows, if you see FAT32 and FAT, the 'FAT' is FAT16 and the partition must be less than 2G.

It hasn't been explicitly mentioned but the wiring for uFAT is indeed the same as the raw SD write above.

The demonstration file that uFAT writes to is fred.txt . If you just create fred.txt in windows be sure you really get fred.txt and not fred.txt.txt!  If necessary, enter the command shell and mv fred.txt.txt to fred.txt.

To answer ducttapepro6, I verified that the newly written files are 'static' on the SD card using uFAT as one would expect.
Title: Re: SD card read/write with Arduino
Post by: rickrcomm on Jul 15, 2008, 07:16 pm
Mr. Orange,

Thanks.  I plan to use to log a battery charging session to see what the profile is on my DeWalt battery charger.

Any chance you would post the real time clock circuit you have on there?

Thanks,

Rick
Title: Re: SD card read/write with Arduino
Post by: zumbi on Nov 05, 2008, 01:46 pm
Hello,

I'm trying to interface arduino uC to a microSD card thru pin 8-13 and GND.

I have been googling and i found this post, ladyada's code[1] based on roland's code[2] and some arduino's vendor code[3].

I have not been able to use SD card yet. The closest i got it is with this post and ladyada's code, but i can not initialize correctly the SD card.

As i read in this post, some people is having same issues, did you resolve it?

I'll be waisting some time on this and kick it, if somebody wants to join, it is welcome.

(I can not post active links)

--

Troubleshooting

Code: [Select]


------------------------                            
Data sampling system                                
send r to read disk                                  
send s to start sampling
send q to stop sampling
Ready.....
-------------------------
MMC/SD initialization failed



How should i format SD card? I have tried without partitions and with FAT16
Title: Re: SD card read/write with Arduino
Post by: Cybot_Rules on Nov 07, 2008, 12:19 am
Can you use this with a micro sd card?
Title: Re: SD card read/write with Arduino
Post by: zumbi on Nov 10, 2008, 10:20 am
No, I have not been able to use it yet. It compiles safely but it does not initialize the SD card, so I can not write nor read from it.
Title: Re: SD card read/write with Arduino
Post by: Timmmm on Dec 10, 2008, 07:38 pm
I don't think it will work with microSD. According to wikipedia the SPI mode that this library uses is optional for microSD but required for SD:

http://en.wikipedia.org/wiki/MicroSD

How hard would it be to use the SD mode instead of SPI? And what about SDHC support?
Title: Re: SD card read/write with Arduino
Post by: dbunting on Dec 11, 2008, 03:12 pm
this might be an incredably stupid question, but im new here.
(you can thank ladyada her GPS data logger kit got me addicted)

someone mentioned using the SD card as a 1gig EEPROM.
would it be possible to use the SD card as the storage location for the sketch code?

maybe in a dual core setup. using one arduino as the access medium to the SD card and then having the second arduino execute the resulting code from the first?

like i said probebly a really stupid question, but im still new, and a bit of a dreamer
Title: Re: SD card read/write with Arduino
Post by: kg4wsv on Dec 11, 2008, 04:13 pm
Quote
would it be possible to use the SD card as the storage location for the sketch code?

Technically, since the ATmega is capable of self-programming, the answer is yes.

Practically, the answer is no. Since there is no way to run code from the external device, you would be required to copy code from the SD card to flash, run the code, then reprogram the flash with whatever code you need to run next.  This is slow, complicated, and the flash has a limited number of write cycles, which means the ATmega would die an early death.

Quote
maybe in a dual core setup.


I think this has more potential, but not in the way you say.  The dedicated ATmega would provide  FAT filesystem support and interface to the SD card.  FTDI has already done this with the Vinculum, although with a USB interface and not directly to SD.

-j
Title: Re: SD card read/write with Arduino
Post by: dbunting on Dec 11, 2008, 04:38 pm
now is there no way because the arduino isnt currently capable (ie not part of the core code) if thats the case could a custom core be written.

or is there no way because of the technical limitations of the chip and execution enviroment?

and why limit it to fat if raw works fine?
Title: Re: SD card read/write with Arduino
Post by: kg4wsv on Dec 11, 2008, 05:07 pm
Quote
and why limit it to fat if raw works fine?

Because raw is difficult to deal with if you want to pop the SD card out of the arduino and put it into a computer to exchange data.  If you use FAT on the SD card, you already have FAT filesystem drivers on all major operating systems.  If you use some raw format, you must write custom code for every possible operating system that you wish to exchange data with.

-j

Title: Re: SD card read/write with Arduino
Post by: Cybot_Rules on Dec 13, 2008, 06:49 am
If we could store the code on the SD card then could we make it able to have 2 sets of code files and a switch to switch between them and their code?
Title: Re: SD card read/write with Arduino
Post by: triffid.hunter on Dec 13, 2008, 02:51 pm
AVR 8-bit microcontrollers are (modified) harvard architecture. that means that the program and data memory are completely separate except for the special ability to load program data into ram such as string constants, so you can't load anything into ram then run it as if it was code, like you can on von neumann architectures such as desktop PCs.

This basically means that we can only use SD for data. If you want to store code on one, you will have to write your own language and interpreter, or use a microcontroller with a von neumann architecture instead of the atmega168 on your arduino.
Title: Re: SD card read/write with Arduino
Post by: kg4wsv on Dec 13, 2008, 03:50 pm
Sorry, Triffid, but as I said the ATmega is capable of self-programming, so yes it is technically possible for it to pull code from the SD card, write it to flash, and execute it.  This really isn't any different conceptually  from pulling the data from a serial port and writing it to flash, which is exactly what the Arduino bootloader does for us, allowing us to program the ATmega without a hardware programmer.

As I said earlier I don't think it's terribly practical, but it absolutely is possible.

-j

Title: Re: SD card read/write with Arduino
Post by: Timmmm on Dec 13, 2008, 09:23 pm
So back on topic... SD mode IO? SDHC support?
Title: Re: SD card read/write with Arduino
Post by: danneman on Jan 01, 2009, 11:58 am
ducttapepro6---

I do also experience som trouble after resetting Arduino. Everything works fine to read and write to the SD Card but after resetting the Arduino the SD Card data is blank.

Have you found any solution for this?

//Daniel
Title: Re: SD card read/write with Arduino
Post by: smelios on Jan 12, 2009, 05:29 am
Zumbi, I am having the same problem as you. I cannot get the SD card to initialize. If anyone has some pointers I would be grateful. :    ::)
Title: Re: SD card read/write with Arduino
Post by: wiji on Jan 12, 2009, 04:14 pm
Is it possible to change the Arduino pins that are used by the library? I can't seem to find any reference to the pin numbers in the library source code.

Thom

*EDIT*

I've found out you need to use the SPI pins, so cannot change the pins in use by the SD card reader... time to get rewiring :D
Title: Re: SD card read/write with Arduino
Post by: jbennett on Jan 14, 2009, 12:31 pm
Hi everyone,

Earlier, ducttapepro6 wrote:

Quote
Mr. Orange-

I had no trouble getting your code up and running in 15 minutes - happily logging, saving, and reading the input to analog1.

However, after hitting the arduino reset button, I found that the read function returns junk(from the SD card).

Shouldn't the SD card retain data after a power cycle? or, is it a function of the code that you so nicely supplied to get me started - and I just don't understand it, yet?

Along with Daniel, I'm hoping that someone can explain why the card starts up with the same junk data each time, if the first thing I do when the sketch runs is hit 'r'.

agent_orange says that it's like having a 1G (or whatever) EEPROM, which is IDEAL for my situation. My arduino will be sitting in a box, on top of a pole, powered by a solar panel for up to 3 months at a time. I have it successfully writing the date and max & min temperatures to the EEPROM, which I can read back out as desired. The EEPROM data is only overwritten after a new sketch is started. This is the functionality that I require from the SD card, but the supplied code appears to wipe the card each time the sketch is started. (I tried commenting out the if(!sd_raw_init()) but that didn't help).

agent_orange, thanks so much for supplying this work, it's fantastic & there's no WAY that I'd be able to work this out on my own. But if anyone can show me a way (even if it's a seperate sketch) to access the data on the card without destroying it, it would be GREATLY appreciated!!

I guess the other option would be if someone could recommend a Windows-based program which could access the data on the SD card?

Thanks for reading everyone!!
Title: Re: SD card read/write with Arduino
Post by: sunnymag on Jan 16, 2009, 08:15 pm
    I am using the same simple logging code that you have posted with just the raw read and write.  The initialization seems to go fine, and then it acts like it is reading and writing even when i have the SD card removed from the slot.  I enter the 'r' command, and it prints the same info, not zeros or junk. when i reset, it loses the info. It is as if it is just storing it in on board memory until it resets, like it isn't even using the sd card at all, and then loses the data when it resets. 

Any ideas?

PS...
Thank you Agent Orange for working on this project.  
Title: Re: SD card read/write with Arduino
Post by: bobemoe on Jan 22, 2009, 07:13 pm
Same here... at first it looks like it's working fine, it appears I can sample data to the card and read it back. But once I've reset the board and try and read the data back I am presented with all zero's.  :(

I too can confirm that reading and writing appears to work even without a card in the slot, despite the fact that it says initialisation failed and doesn't show any card statistics.  :-/

With a card in the slot I get reasonable looking card statistics (size: 125698048 for a 128MB card) which suggests it can see the card.

Which again raises the question, what are we missing here? Any ideas?

I will be sure to post if I make any further discoveries.

Thanks all! :)
Title: Re: SD card read/write with Arduino
Post by: danneman on Jan 22, 2009, 10:22 pm
Hi there.

I found another solution that I think is much better for storing large amount of data and it is Fat16+32 compatible. You can communicate with the card with normal serial, read more: http://www.roguerobotics.com/ uMMC datastorage.

Regards /Daniel :)
Title: Re: SD card read/write with Arduino
Post by: jbennett on Jan 22, 2009, 11:11 pm
Hi Daniel,

That's certainly a nice-looking solution! Might be a bit of overkill for me though; using a 16Mb SD card that came with my camera, I worked out that if I store 10 bytes of data every minute, I've got over 2.5 YEARS worth of storage capacity...

Just for my curiosity, how would you communicate with this uMMC device? I'm guessing that you'd have to Serial.print() commands like "O 1 R /LOGS/JANUARY/JAN03.LOG{cr}" to it in it's own language?

Thanks!
Title: Re: SD card read/write with Arduino
Post by: bobemoe on Jan 23, 2009, 03:03 pm
Okay, I am getting somewhere...  

I thought I would try the uFat library that was mentioned fairly early on in this thread, which straightaway gave me a directory listing of all the files on this card. But hang on a minute, I thought I had formatted the card! So I popped it back into the computer, deleted all the files and created the required data.bin file, but to my amazement my new file disappeared and all the old ones came back! No amount of deleting formatting or mortifying seemed to affect this card any more, so I have scrapped it and got myself a new one.

uFat seemed very temperamental with my new card, failing to initialise nine out of 10 times. I put a simple loop round the initialising statement with a delay, so it would retry if it failed instead of just showing an error and halting. This seemed to work a treat, no matter how much delay before or after it always seems to fail once and then initialise fine on the second attempt without fail. Reading and writing then worked perfectly :D

I think I am going to stick with uFat over the raw library as it isnt any bigger and I still can't get the raw library to work even with my new card (same problems as described before), also I like being able to read my data back on the computer. :)

The only downside is that the code for using uFat isn't as friendly as the raw library, and I can't seem to get it to write one byte at a time, it has to be written in 512byte sectors, but I can live with this.

Hopefully this information helps someone out, I am thinking to get the raw library working perhaps something needs to be inside a retry loop much like I had to do with the uFat library to get it working.

Thanks everyone who has contributed, especially agent_orange for the circuit diagram (which needs no modification to work with uFat), and sirmorris for the uFat library.
Title: Re: SD card read/write with Arduino
Post by: smelios on Jan 23, 2009, 06:23 pm
Hey bobemoe this sounds good. I've tried the RAW program and haven't had any luck. I'm currently attepmting SirMorris's code and am not getting anywhere there either. I get some errors when I try to compile.

o: In function `microfat::initialize(unsigned char*)':
multiple definition of `microfat::initialize(unsigned char*)'hardware\libraries\uFat\microfat.o:C:\arduino-0010/hardware\libraries\uFat\microfat.cpp:17: first defined here


o: In function `microfat::locateFileStart(char const*, unsigned long&, unsigned long&)':
o: In function `main':


Any sugggestions?
I have the required header files and I'm trying to run the microfat program.

My apologies if this has already been resolved somewhere else 8-)
Title: Re: SD card read/write with Arduino
Post by: bobemoe on Jan 23, 2009, 06:43 pm
Hi smelios,

It doesn't look like you are using the latest version, try downloading uFat2.zip rather than mmc1.rar, hopefully that will fix the problem.
Title: Re: SD card read/write with Arduino
Post by: smelios on Jan 23, 2009, 07:11 pm
Fresh code mmmmmm.

Still having problems. Bobemoe, did you encounter an error like this?

error: 'directory_entry_t' was not declared in this scope In function 'bool showDirectory_walkerfn(directory_entry_t*, unsigned int, void*)':
In function 'void showDirectory()':

Or did yours compile with no problems?

Sorry to keep asking you questions i'm a noob.  ;D
Your help is greatly appreciated!
Title: Re: SD card read/write with Arduino
Post by: bobemoe on Jan 23, 2009, 07:21 pm
Mine compiled fine.

I can get a similar error if i remove the #include lines from the top of the example which makes me think its a problem with your includes.

Did you delete the files you copied to /hardware/libraries/ for version 1? they may be conflicting.
Title: Re: SD card read/write with Arduino
Post by: smelios on Jan 23, 2009, 09:29 pm
Found my error, I was on arduino10. Morris said he developed this in Arduino12 so i downloaded that and it complied. Now i just can't init the sd card. Oh well work for another day :P
Thanks again for helping
Title: Re: SD card read/write with Arduino
Post by: bobemoe on Jan 24, 2009, 12:51 pm
Excellent, now you are at the same stage that I was. Try making it retry the initialisation.  This is what fixed it for me, I changed:
Code: [Select]
 if (mmc::initialize() != RES_OK)
 {
   error(PSTR("mmc init failed.\n"));
 }

Changed to:
Code: [Select]
 while(mmc::initialize() != RES_OK){
   pprint(PSTR("mmc init failed. retrying...\n"));
   delay(100);
 }

I find it always fails once. If that doesn't fix it I am all out of ideas. Good luck.
Title: Re: SD card read/write with Arduino
Post by: jbennett on Jan 30, 2009, 01:29 am
Hi again,

After further reading (ie that uFat basically takes up the same space as the sd_raw instructions) I've headed down the uFat track. I've downloaded the uFat2 files from SirMorris's blog (http://groups.google.com/group/micro-hacker
) and have integrated them into my program, although I have a few problems...

First, the sketch seems to 'interfere' with my DS1307 real time clock data. With the SD card connected as per the diagram at the beginning of this thread (and the clock connected to analog pins 4 & 5), the clock output is 'mixed up', e.g. the day comes through as the hour, year comes through as day of the month, etc. Leaving the hardware connected and loading up a sketch which ONLY displays output from the RTC, I get the correct output from the clock.

Secondly, I'm not too sure as to exactly how the reads/writes work. Am I correct in thinking that if (RES_OK == mmc::writeSectors(sector_buffer, sector, 1)) simply checks that a 1-byte write to sector (which=0) of sector_buffer works? Is it just the digitalWrite(13, (millis() / 1000) & 1) which writes sector_buffer out to the SD card? If that's correct, can anyone explain how this works for me? I'm very much learning as I go...

I'd like to be able to write data out to the SD card 10 bytes at a time (is this possible, or does the buffer have to be 512 bytes?), and be able to read them back & display them when prompted. Is this also possible, or am I only going to be able to check the output by checking the data.bin file on the PC?

Thanks again for everyone's thoughts...

JB
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Jan 30, 2009, 11:05 am
Hi JB.

The line:

if (RES_OK == mmc::writeSectors(sector_buffer, sector, 1))

writes 1 sector's worth of data stored at sector_buffer in the arduino's SRAM to the specified sector on the card. Once this routine returns your data is stored. The line:

digitalWrite(13, (millis() / 1000) & 1)

has nothing to do with the workings of the program. It simply flashes the LED on port 13 to let you know all's done.

All reads and writes in uFat are 512 bytes. This is the size of a sector on the card. It would be possible to write a function that allows arbitrarily-sized writes but that would add to the size.

Do you only want to ever have 10 bytes stored? Or are you saving a stream? When you want to read it back would you be showing all the data stored thus far? What's the expected data rate? If it's a slow dribble of data to the card that would warrant a different approach than if you're going for realish-time.

If you can describe your program requirements I'll see wht I can do to help you out.

There's no obvious reason why uFat should interfere with your RTC. It sounds like you're using 2wire for the clock. I have a board that uses I2C components simultaneously with hardware SPI without a problem, I may need to look over your code.

Charlie
Title: Re: SD card read/write with Arduino
Post by: jbennett on Feb 01, 2009, 11:02 pm
Hi Charlie,

Thanks for clarifying that for me, I think I get it now.

I think I can probably work with the 512 byte write each time... My program is monitoring a temperature reading and the voltages of a battery and a solar panel, in an enclosure housing a camera to take a few photos each day, producing 10 bytes of data per minute. I could probably drop this down to 8 bytes if writing 10 bytes/min causes problems with the 512 byte sector size, but I'd prefer not to.

Here's my code (over 2 posts):
Code: [Select]
#include <Wire.h>
#include <math.h>
#include <DateTime.h>
#include <avr/pgmspace.h>
#include <wprogram.h>
#include <microfat2.h>
#include <mmc.h>

#define ThermistorPIN 0            // input read pin for LM335 is Analog Pin 0
float temperature = 0;                 // variable which will be calculated in process
long val=0;                       // variable to store the value coming from the thermistor
float temp;

unsigned long sector = 0;
unsigned long byteSize;

unsigned long WriteAddress = 0;    // initial address for writing to the SD card.
byte value;                        // will be used...
int incomingByte = 0;                 // ...for incoming serial data
byte tempBytes[10];                // for sending data to the SD card
byte sector_buffer[512];           // for sending AND retrieving data to/from the SD card

int hour;
int minute;
int second;
int month;
int day_of_week;
int day;
int year;

char* dow[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

float Thermistor(int RawADC) {  //  Inputs ADC Value from Thermistor and outputs Temperature in Celsius
long Resistance;
float Temp;                                      // Dual-Purpose variable to save space.
Resistance=((10240000/RawADC) - 10000);          // Assuming a 10k Thermistor.  Calculation is actually: Resistance = (1024/ADC)
Temp = log(Resistance);                          // Saving the Log(resistance) so not to calculate it 4 times later. "Temp" means "Temporary" on this line.
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));   // Now it means both "Temporary" and "Temperature"
Temp = Temp - 273.15;  // Convert Kelvin to Celsius                                            Now it only means "Temperature"
return Temp;           // Return the Temperature
}

void print_prompt_P(const char *data) {         // print prompts and messages from program flash to save SRAM
  while (pgm_read_byte(data) != 0x00)
    Serial.print(pgm_read_byte(data++));
}

void TakePhoto() {
 digitalWrite(3,HIGH); // first, switch on the fans to blow away dust or bugs...
 delay(10000);
 digitalWrite(3,LOW);
 delay(2000);
 digitalWrite(9,HIGH); // then send power to the camera
 delay(500);           // time for current to get to camera - not sure if this is needed...
 digitalWrite(6,HIGH); // trigger the solenoid for 100 msec
 delay(100);
 digitalWrite(6,LOW);
 delay(15000);         // wait 15 seconds for the camera to take a photo then shutdown
 digitalWrite(9,LOW);  // stop sending power to the camera.
}

void DataDump () {
 int DaysToDump = WriteAddress;
 Serial.println("");
 print_prompt_P(PSTR("          Data dump initiated: dumping "));
 Serial.print(DaysToDump/10);
 print_prompt_P(PSTR(" days of data.\n"));
   print_prompt_P(PSTR("Date,Time,Temp,VBatt,VPanel\n"));
     for(int p=0;p<DaysToDump;p=p+10) {
       sector_buffer[p]=digitalRead(13);
       Serial.print(sector_buffer[p]);

       Serial.print(analogRead(0));  // this bit dumps the date in 'dd/mm/yy' format...
         print_prompt_P(PSTR("/"));
//          ++f;
         Serial.print(analogRead(0));
         print_prompt_P(PSTR("/"));
         delay(50);
         Serial.print(analogRead(0));
         print_prompt_P(PSTR(","));
         Serial.print(analogRead(0));  // this bit prints the time, as ',HH:MM,'...
         print_prompt_P(PSTR(":"));
//          ++f;
         Serial.print(analogRead(0));
         print_prompt_P(PSTR(","));
//          ++f;
         delay(50);
         Serial.print(analogRead(0));  // this bit prints the temperature...
         print_prompt_P(PSTR(","));
//          ++f;
         delay(50);
         Serial.print(analogRead(0));  // this bit prints the Battery Voltage in 'VV.vv,' format...
         print_prompt_P(PSTR("."));
//          ++f;
         Serial.print(analogRead(0));
         print_prompt_P(PSTR(","));
//          ++f;
         delay(50);
         Serial.print(analogRead(0));  // this bit prints the Solar Panel Voltage in 'VV.vv,' format...
         print_prompt_P(PSTR("."));
//          ++f;
         Serial.print(analogRead(0));
//          ++f;
         delay(50);
       Serial.println();
     }
 WriteAddress = 0;
}

void error(const char* s)
{
 print_prompt_P(PSTR("Error: "));
 print_prompt_P(s);
 print_prompt_P(PSTR("<press reset>\n"));
 for( /* ever */ ; ; )
 {
   digitalWrite(13, (millis() / 250) & 1);
 }
}

void SDWrite() {
 // Pass in the sector-sized buffer we'll be using ourselves later.
 // uFat doesn't own it, it just needs to use it temporarily.
 // We also pass in the address of a function that is used to read
 // sectors from our device.
 //  
 if (!microfat2::initialize(sector_buffer, &mmc::readSectors))
 {
 error(PSTR("uFat init failed.\n"));
 }
 prog_char string_0[] PROGMEM = "DATA    BIN";

 if (microfat2::locateFileStart(PSTR("DATA    BIN"), sector, byteSize)) // check if the target file exists
 {
   if (byteSize >= 512)                                                 // check it's bigger than 512 bytes
   {
     if (RES_OK == mmc::readSectors(sector_buffer, sector, 1))          // checks a single-SECTOR read works OK
     {
         print_prompt_P(PSTR("Data read test SUCCESSFUL.\n"));
         delay(500);
       if (RES_OK == mmc::writeSectors(sector_buffer, sector, 1))       // checks a single-SECTOR write works OK
       {
         print_prompt_P(PSTR("Data write test SUCCESSFUL.\n"));
         delay(500);
       }
       else
       {
         print_prompt_P(PSTR("Failed to write updated data."));         // if the write fails, end here...?
       }
     }
     else
     {
       print_prompt_P(PSTR("Failed to read data.bin."));
     }
   }
   else
   {
     error(PSTR("Found data.bin, but it's too small."));
   }
 }
 else
 {
   print_prompt_P(PSTR("data.bin not present on card."));
 }
 Serial.println("Initialisation COMPLETE!!");
}

void setup() {

pinMode(3,OUTPUT);       // FANS control - YELLOW wire
digitalWrite(3,LOW);
pinMode(6,OUTPUT);       // SOLENOID power control - WHITE wire
digitalWrite(6,LOW);
pinMode(9,OUTPUT);       // CAMERA power control - BLUE wire
digitalWrite(9,LOW);
// pinMode(13,OUTPUT);
Serial.begin(115200);
Wire.begin();

// The rest of this setup() procedure is checking that the SD card is present & working.

 while(mmc::initialize() != RES_OK)
 {
   print_prompt_P(PSTR("SD init failed. retrying...\n"));
   delay(100);
 }
 SDWrite;
}

void loop() {

// Below required to reset the register address to 0.
Wire.beginTransmission(104); // transmit to device #104, the ds 1307
Wire.send(0x00);
Wire.endTransmission();      // stop transmitting

Wire.requestFrom(104, 7);    // request 7 bytes from slave ds1307, we'll assume it'll send them all even though it doesn't have to
second = Wire.receive();
minute = Wire.receive();
hour = Wire.receive();
day_of_week=Wire.receive();
day = Wire.receive();
month = Wire.receive();
year = Wire.receive();

// Convert all the BCD values that might have "tens" to decimal.
second = second/16 * 10 + second % 16;
minute = minute/16 * 10 + minute % 16;
hour = hour/16 * 10 + hour % 16;
day = day/16 * 10 + day % 16;
month = month/16 * 10 + month % 16;
year = 2000 + year/16 * 10 + year % 16;

// Change times below to desired photo times. Copy & paste to add more photos per day.
// NOTE: for some reason, 8's & 9's cause an error, so don't use them on their own below;
// 18 & 19 work fine, but 08 & 09 do not.

if (hour == 6) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
if (hour == 12) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
if (hour == 14) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
if (hour == 18) { if (minute == 00) { if (second == 00) { TakePhoto();}}}

Serial.print(hour);
print_prompt_P(PSTR(":"));
if (minute < 10) { print_prompt_P(PSTR("0")); }
Serial.print(minute);
print_prompt_P(PSTR(":"));
if (second < 10) { print_prompt_P(PSTR("0")); }
Serial.print(second);
print_prompt_P(PSTR(" on "));
Serial.print(dow[day_of_week]);
print_prompt_P(PSTR(", "));
Serial.print(day);
print_prompt_P(PSTR("/"));
Serial.print(month);
print_prompt_P(PSTR("/"));
Serial.print(year);
Serial.println();
 byte span = 20;  int aRead = 0;
 for (byte i = 0; i < span; i++) {        //loop to get average of 20 readings
   aRead = aRead + analogRead(ThermistorPIN);
   }
 aRead = aRead / span;
 temperature = Thermistor(aRead);


...continued next post...
Title: Re: SD card read/write with Arduino
Post by: jbennett on Feb 01, 2009, 11:05 pm
...rest of the code:
Code: [Select]
if (second == 0) {  // this code writes data to the sector_buffer every minute
  Serial.println("Writing data...");
  sector_buffer[WriteAddress] = day;
//   Serial.print(sector_buffer[WriteAddress]);
//   Serial.print(", day = ");
//   Serial.println(day);
  ++WriteAddress;
  sector_buffer[WriteAddress] = month;
//   Serial.print(sector_buffer[WriteAddress]);
//   Serial.print(", month = ");
//   Serial.println(month);
  ++WriteAddress;
  sector_buffer[WriteAddress] = (year-2000);
  ++WriteAddress;
  sector_buffer[WriteAddress] = hour;
  ++WriteAddress;
  sector_buffer[WriteAddress] = minute;
  ++WriteAddress;
  sector_buffer[WriteAddress] = byte(temperature);
  ++WriteAddress;
     span = 50;  unsigned int VBatt = 0;
     for (byte b = 0; b < span; b++) {        //loop to get average of 50 readings
       VBatt = VBatt + analogRead(1);
       }
     VBatt = VBatt / span;
  sector_buffer[WriteAddress] = byte(VBatt/79);
  ++WriteAddress;
  sector_buffer[WriteAddress] = byte(VBatt%79);
  ++WriteAddress;
// Note:
// The battery voltage on the divider ranges from 0 to 13.5 volts.
// The voltage on the arduino pin ranges from 0 to 5 volts using 2200- & 3900-ohm resistors.
// So an analogRead value of 1023 = 13 volts on the divider
// Therefore one bit is equal to 1024 divided by 13V = 78.769, rounded to 79.
     span = 50;  unsigned int VPanel = 0;
     for (byte P = 0; P < span; P++) {        //loop to get average of 50 readings
       VPanel = VPanel + analogRead(2);
       }
     VPanel = VPanel / span;
// *** NEED TO FIND OUT max V output of solar panel, divide 1024 by this, then replace 79 with the result. ***
  sector_buffer[WriteAddress] = byte(VPanel/79);
  ++WriteAddress;
  sector_buffer[WriteAddress] = byte(VPanel%79);
  ++WriteAddress;
  if (WriteAddress > 512) {
    SDWrite;
    ++sector;
    WriteAddress = 0;
  }
 }

 // check for any incoming serial input, then Dump Data only if 'd' is pressed
 if (Serial.available() > 0) {
   incomingByte = Serial.read();      
   if (incomingByte == 100) {
     DataDump();
   }
 }
delay(1000);
}

There are a few redundunt bits & pieces, & lots of comments for my own benefit, but it shouldn't be real hard for the rest of you who are as new to this as I am to follow! :)

Sorry, I've got to head out of the office now so this is a bit of a rushed response... If more info is required I'll check in again later today/tonight.

Thanks again,

JB.

-* EDIT *- After having a bit more time to digest your response I've made a couple of modifications to the code; it probably still has some gaping errors but it's semi-functional & allows for testing...
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 02, 2009, 09:41 pm
Howdy

Thanks for posting the code - it helps everyone in the end. I realise it can be a bit like exposing your very soul but we're all in this together.

I have a few questions. Do you only want to collect the last 50 or so readings or would you prefer to keep a rolling record?

When you dump the data do you just want to see the currently buffered entries or all of the data on the card or would you prefer to be able to say 'last 10 entries' or similar?

From reading the code I can't quite make out what your requirements are. Do you think you could write a few paragraphs about this? Try and be condescendingly pedantic :)

One thing you could consider is trading code volume for end-result readability. Specifying that you require the data file to be human-readable might add an up-front code cost but could give you huge benefits...

C
Title: Re: SD card read/write with Arduino
Post by: jbennett on Feb 03, 2009, 12:23 am
Hi Charlie,

I'ts probably more accurate to say that 'my' code is exposing about half a dozen forum poster's souls - there's not too much in there that I've written myself but rather cobbled together from this wonderfully supportive community!  :)

The original rundown of my project was as follows:
So, basically the sketch as originally conceived was designed to:However, on implementing a prototype system, we have found that the enclosure & heat-shield we've employed makes the temperature control functionality redundant - the interior temperature is the same as the external temp, so the fans don't actually provide any cooling effect. I'll now use them to just blow air over the camera aperature a few times a day, in order to remove dust and/or insects.

We thought that it would be helpful to record daily maximum & minimum temperatures, so I set up a sketch which would record the date (dd/mm/yy) & max & min temps in 5-byte chunks once each day in EEPROM. The data dump procedure was initially set up to read the EEPROM & display it in a table-like output like this:
         Data dump initiated:

  Date      MaxTemp      MinTemp
1/1/2009         20         12
2/1/2009         21         9
3/1/2009         29         12
4/1/2009         30         11
5/1/2009         25         13
6/1/2009         29         16
7/1/2009         23         14
8/1/2009         21         10
9/1/2009         23         10
10/1/2009         24         12
11/1/2009         22         13
12/1/2009         28         17
13/1/2009         43         18

which I could cut & paste to Excel or a simple text file. However, with uFat I'm thinking that a data dump procedure may be a bit redundant, if I can simply pull out the SD card, plug it into my laptop & copy the file. One thing that I do need to keep in mind in this project is that it won't always necessarily be ME who services these cameras, so I need to keep their operation as user-friendly as possible...

Anyway, the idea with writing data to the SD card is that I may as well use the huge amount of capacity available & write data to it every minute. At this stage, I'm looking at recording data in the following manner:

Date, Time, Temp, VV.vv (Battery voltage), VV.vv (Solar Panel voltage)

where Date = DD/MM/YY (3 bytes)
         Time = HH:MM (2 bytes)
         Temp = degrees C (1 byte)
         VV.vv = voltages to 2 decimal places - (2 bytes each)

So, I'm left with 10 bytes of actual data going onto the SD card. However, in keeping with the spirit of simplicity mentioned above, I'm thinking that ideally the data written to the SD card would be in comma seperated value (.csv) format; that way we can easily import it into a spreadsheet for viewing & manipulation. This would add another 10 bytes or so for /'s, commas, decimal points etc.

My concern here is that 10 or 20 bytes obviously don't divide too well into 512; what happens when the buffer is full? Do I lose some data there? I'm not up to speed on exactly how sectors work, so forgive me if this is a stupid question... Could I make sector_buffer a 520-byte array (for example), write 512 bytes to SD card sector 0, then put bytes 513-520 back into the first 8 bytes of the array, to be written to sector 1 when the array is full again? Will a computer see this as one continuous file?

I think I'll leave it there for now - hopefully this answers most of your questions, and since this post is getting a bit(!) lengthy now I'll let you digest this lot & ask any more questions as required.

Cheers

JB
Title: Re: SD card read/write with Arduino
Post by: bobemoe on Feb 03, 2009, 02:01 am
I have written a simple library based on uFat which allows you to write to the SD file as many bytes as you want at a time. It buffers the data until you have a full sector and then writes that to the card, and then starts buffering for the next sector.

You can download it from http://code.jhodges.co.uk/SDWriter/SDWriter.zip (unzip to arduino/hardware/libraries/)

I have only just finished this, and it definitely is not polished, and probably lacks some error checking. There are also some Serial.print's in the library itself that I used for testing which you will probably want to remove if you are using serial yourself.

I have posted this in its infancy as it looks like it could be of use to the posters on this thread, JB especially ;)

There is a commented example of usage in there.

Hope this is of help. :)
Title: Re: SD card read/write with Arduino
Post by: jbennett on Feb 03, 2009, 02:35 am
Downloaded & tried, thanks bobemoe!

Here is what is in my data.bin file after running the sketch:

(http://C:\arduino-0012\output.jpg)
-< edit >- bugger - how do I put a photo in here?!? There should be a bmp of strange shapes & symbols instead of numbers here...

Do you know why I'm getting this wierd stuff instead of numbers?

Thanks for your help anyway!!

JB
Title: Re: SD card read/write with Arduino
Post by: bobemoe on Feb 03, 2009, 04:07 am
Hi JB,

You wont be able to open it in a text editor... its saved as binary - the actual bytes rather than an ASCII representation of those numbers.

Each byte (value 0-255) in a TEXT file represents one character.  So a file containing the string "123", consists of 3 bytes of value: 49,50 and 51, which represent the characters 1,2 and 3 (see http://www.asciitable.com/)

If we write the single byte value 123 to a file we get a file which consists of 1 byte of data, value 123.  But if we view this as TEXT we will see only 1 character, a { in this case, which is represented by the value 123.  Which is why you are seeing funny characters, as a lot of the ASCII set is symbols and other weird stuff!

I will add a writeString() function to the library, but I think you would probably have trouble converting your byte's and int's to a string, I did look into this briefly (something to do with stdio.h, sprintf() and bigger code!) but quickly decided I will stick to writing values not strings to the file.

I wrote a simple PHP script that converts the raw data into a CSV.  What operating system are you using? I can share this with you, and help you with it if your on Mac or Linux, but wouldn't be able to help so much if on Windows.

I understand you want relatively user-friendly access to your data. This conversion process could be packaged into a single command or double clickable file, data.bin goes in, data.csv comes out.

It seems you are at a bit of a fork in the road, and I am not sure the best route for you. What does everyone else think? I thought string manipulation looked a little tricky in Arduino/C.  I've only had my Arduino a few weeks, also I am more used to PHP/Java/BASH. Is this conversion a sensible trade-off for avoiding strings in this case?

If you were writing lots of data, and fast, you would most certainly want to write byte values rather than ASCII strings, as this will keep file sizes much smaller and reduce the amount of time spent writing to the card (exactly what I need).

In your case trying to figure out this string thing (its actually an array of chars) might be an idea.

Let me know which route you choose.

I will add the writeString() function. Can anyone link us to any good tutorials on strings and sprintf?

Title: Re: SD card read/write with Arduino
Post by: jbennett on Feb 03, 2009, 05:32 am
Thanks for explaining the weird characters, your post is very informative!!

Unfortunately (for me) I'm using Windows... don't get much choice with the Government!!  ;D

I guess that's another option to look at; does anyone know of an existing Windows program which could convert the raw data to CSV or just plain text? I had hoped to have been able to just pull the SD card out, plug it into the laptop & view the output in 'real' numbers, but I now understand that I can't do that currently. I can't get over how generous the Arduino community is in terms of writing & sharing code with people like me, and I would be deeply grateful to have a look at a writeString() function if you were to play around with one!

Since my data is only taken once a minute, and the capacity of SD cards provides essentially unlimited storage in my case, speed and file size are not really an issue. Your comment:
Quote
In your case trying to figure out this string thing (its actually an array of chars) might be an idea.

...has got me thinking though, so I'll start playing around with that & see where it takes me...

Thanks again!
Title: Re: SD card read/write with Arduino
Post by: Nachtwind on Feb 03, 2009, 10:45 am
I could help you by writing a small Windows script or program for it.. sooner or later i will have to do that anyway.

I think i got the basic idea of how those values are written but bobemoe could you though give me your php code so i could simple rewrite it for windows?
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 03, 2009, 10:53 am
I think the way to go is to use the code already present in the libraries. Check out .\hardware\cores\arduino\Print.cpp

This base class provides the 'printing' functionality. Since you're already wearing the cost of the code whenever you use the Serial library it can be used virtually free. All you need to do is provide a subclass which provides a write byte function which puts a byte to the MMC buffer and writes the sector when necessary.

What you get is the ability to write strings using the exact same functions as you'd use for Serial! How cool is that.

As a super bonus, you could interchangeably use the MMC output with the Serial output for testing..

Here's how. (Please forgive typos, I'm away from arduino right now so I can't test)

Code: [Select]
class MMCWriter : public Print
{
 public:
   void begin( .. )
   {
      // initialise the mmc byte-by-byte writer here
   }

   void flush(void)
   {
      // flush the buffer to the card here
   }

   virtual void write(uint8_t theByte)
   {
      // call the function that puts a byte in the buffer here
   }
};

MMCWriter MMCio;

void setup(void)
{
 MMCio.begin();
 MMCio.println("Hello! This string will go to the buffer!");
 MMCio.println(123, DEC);
 MMCio.flush();
}

That's it. I'll leave the serial/mmc swaperoo trick for another post (or you could work it out if you've got 5 mins).

There's a huge amount of power in the arduino core - take some time to have an explore and who knows what you might find :)

C
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 03, 2009, 11:23 am
Here's a few general notes that I've been meaning to make for a while.

One thing to remember is that uFat simply overwrites data that is pre-allocated on the card. This needs to be a contiguous file else wierdness will ensue. One way to ensure this is to format the card before writing your proxy file to it. Deleting files from the card can leave holes in the FAT which your operating system will use next time a file is created on the card leading to a fragmented file.

Unfortunately resizing a file isn't a simple case of adjusting a value in the directory structure. It entails re-linking the FAT table chains, which means a lot more code in uFat, which is counter to its design criteria. I think it's a reasonable trade-off. Actually, thinking about it, if people were happy with yet another trade off then we might be able to come up with a small extension that can work with one or two files on a card and set their lengths in a one-off manner... But I digress.

The length of the file indicated in the directory is the raw size of the original proxy file, not the number of bytes you've written. Its size remains constant no matter how you write to the space it occupies.

If you write binary data to the file then you'll no doubt have a client application that understands it.

If you write ascii data then things are a little (but only a tiny bit) harder. When the file is written to and later removed to the computer and viewed in a text editor, there may well be a warning that the file is corrupt (at best) to a refusal to load it at all (at worst). This is to do with non-ascii ranged bytes in the file, as explained in a previous post. Warnings can be ignored on the whole. It's best practice to empty the buffer before writing data to it. You could fill it with character 0x20 (ascii for 'space') but that would mean a bloated file when editing. You could fill with 0x0d (carriage returns), which might be better. I'd go with 0 myself, unless it was making editing hard.

Thoughts encouraged.
C
Title: Re: SD card read/write with Arduino
Post by: bobemoe on Feb 03, 2009, 01:45 pm
Nachtwind, and those who want it, my PHP for converting to CSV:

Code: [Select]

<?php
$packet
=array(3,2,2); //the number of bytes to read for each value of the 'packet' of data to be converted to a csv line.

$f=fopen('data.bin','r');
while(!
feof($f))&#123; //repeat until end of file
      
$csv_line='';
      foreach(
$packet AS $bytes)&#123; // loop through the packet and generate the CSV line
            
if($csv_line$csv_line.=","//append a comma if needed
            
$csv_line.=getVal($f,$bytes); //append the next value
      
&#125;
      
echo $csv_line."\n"//echo the line
&#125;

//reads $bytes bytes from file $f and convert them to a value
//does this by reading each bite as a character, and converting it to its ASCII value
function getVal($f,$bytes)&#123;
      
$val=0;
      for(
$i=0;$i<$bytes;$i++)&#123; // loop for however many bytes we require
            
$b=ord(fgetc($f)); // read a character and convert it to it's ASCII byte value with ord()
            
$val=($val<<8)+$b// shift the current value left eight bits (8 bits == 1 byte) and then add the byte we just read to the value
      
&#125;
      
return $val;
&
#125;
?>



You must adjust $packet to reflect the number of bytes used for each value. (This is currently configured to read the data generated from my example in SDWriter)

The magic of joining the bytes into larger values happens on this line: $val=($val<<8)+$b
this shifting of bits is how we join two bytes back into an int
this could also be achieved by multiplying by 256: $val=($val*256)+$b;






valbyte2byte1example values and how they would be stored in multiople bytes
255255as we probably know, 255 is the most one byte to contain
25610to store 256 or more we need another byte to store multiples of 256.  (1*256) + 0  =256
26115(1*256) + 5 =261
65535255255(255*256) + 255 = 65535  //max value of an int (2 bytes)

you could now add a third byte to store multiples of 65536
this can be done for as many bytes as you need to contain your range of numbers, with only a few more bytes you can store over billions!

sirmorris, I find the functionality of uFat is excellent and the trade-offs are not a problem, especially as it seems we are all really only wanting to log data, I can't really see the need for more functionality. If I wanted to do much more I think I would probably want a full FAT filesystem. But only the future can tell ;)  

Also your method of printing to the buffer looks really cool, I haven't got time to study it greatly now, but it looks like it's exactly what JB needs and wouldn't require my suggested writeString function.  In fact I guess I could extend my SDWriter in the same way to add the print/println functionality to it :D

Thanks!
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 03, 2009, 01:59 pm
It looks like SDWriter would just pop right on top there!

Great stuff. I'm thrilled that uFat is finding some use.

C
Title: Re: SD card read/write with Arduino
Post by: bobemoe on Feb 03, 2009, 03:18 pm
I had to change about two lines and now my SDWriter supports .print() and .println() in the same way Serial does, thanks to sirmorris' genius idea :)

The new code is available in the same place at: http://code.jhodges.co.uk/SDWriter/SDWriter.zip

There is a new example in there called Print_Data that creates a CSV style file.

The old example is still there as writing byte values is still supported.
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 03, 2009, 05:29 pm
If I may I'd like to offer a couple of comments on the writer.

Having the write function which is used by the print() calls go through a general-purpose write function is less efficient than making things work the other way viz:

Code: [Select]
void SDWriter::write(uint8_t theByte)
{
 sector_buffer[buffer_pos]= theByte;
 ++buffer_pos;
 if(buffer_pos==512)
 {
   flush();
 }
}

void SDWriter::write(unsigned long val,int bytes)
{
 for(int b=bytes-1;b>=0;--b)
 {
   write((val>>(8*b)) & 0xff);
 }
}


This way the print calls all go through the minimal version.


Title: Re: SD card read/write with Arduino
Post by: bobemoe on Feb 03, 2009, 05:44 pm
Good point. I guess it is the little things that count when you only have a little processor and memory ;)

The library is updated with that change.

Thanks again.
Title: Re: SD card read/write with Arduino
Post by: jbennett on Feb 03, 2009, 10:58 pm
You guys are AMAZING!!  :D

I've only had time this morning to quickly compile & try bobemoe's Print_Data example, but I can see that it's EXACTLY what I was after. I should be able to incorporate this code to 'format' the data stream in the most user-friendly way possible, which will make life so much easier for my workmates (and me!).

I'll be away from my computer today so I won't be putting much time into this, but in the next couple of days I'll let you know exactly how things have gone.

Charlie & bobemoe - you're work here will be extremely valuable to many others like myself I'm sure; we can't thank you guys enough.

Oh, one last thing - Charlie, did you have any thoughts on why my RTC data is being 'corrupted'?

Thanks again everyone!!

JB
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 03, 2009, 11:08 pm
I've looked at the code and there are a couple of things that I'd like to go over with you - as they're application specific maybe you should PM me and we'll take it offline via email. We can post final findings but the interim comms might be a little noisy for this topic.

Title: Re: SD card read/write with Arduino
Post by: acquisition on Feb 09, 2009, 01:00 am
Is there any hope on getting the read from SD to work?
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 09, 2009, 10:58 am
Hi

Reading from SD is a solved problem. The discussion happening here was to do with a specific problem sketch.

Charlie

Title: Re: SD card read/write with Arduino
Post by: acquisition on Feb 09, 2009, 06:46 pm
But does it read/write FAT? Will it be added to the official Arduino library page?
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 12, 2009, 03:33 pm
Hi

Kind-of, and no. The library is intended for tight memory situations where you are willing to accept limitations in usage. uFat allows you to find the starting sector and length of a file on a fat12 or fat16 formatted device.

You can then read data from and write data to those sectors. It doesn't understand the filing system more than it needs to, which in this case is only reading the boot sector, partition table and directory.

In most cases this has been quite enough for me!

Charlie

Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 12, 2009, 03:38 pm
A few posts ago bobemoe posted code to use the Arduino library print routines to output strings to an mmc card. I've spoken with him and used his code as a basis for DevicePrint. It has been modified to fit my usual criteria - small & tight with few (if any) dependencies.

Get it herehttp://arduinonut.blogspot.com/2009/02/libraries.html along with some of my usual written drivel about whatever and stuff.

Commentary and questioning welcomed as usual. Enjoy.

C
Title: Re: SD card read/write with Arduino
Post by: Nachtwind on Feb 12, 2009, 06:17 pm
wow,that looks very interestering, gonna have to finish soldering my sd card thingy ;0)

Anyway - is there a chance you could also write a function for reading stuff from an uFat File?
Title: Re: SD card read/write with Arduino
Post by: jbennett on Feb 13, 2009, 01:32 am
Hi again everyone!

After numerous emails, pulling of hair & re-writes, sirmorris has helped to get my SD card logging dreams up & running. You can get the 'final' sketch here: http://docs.google.com/Doc?id=dqhc6fg_0gmk96kdd. It's certainly not the prettiest sketch, and I can't claim much of it at all as my own work, but it does what I hoped it would (although real-world testing hasn't happened yet).

Here's a photo of my current test setup...
(http://lh4.ggpht.com/_A8zP9wg19y4/SZS79_HIO_I/AAAAAAAABro/_lGx18-rpjs/s800/SD%20setup.JPG)
Needs a LOT of work before it's ready for final implementation!!  ;D

Please feel free to suggest code improvements/rip my sketch to shreds - I'm no programmer, I've got thick skin, and any help is greatly appreciated!!

One last thanks to sirmorris & bobemoe for their work here - it's amazing how generous you've been with your help & knowledge.

I'll pop a note in here when I get something up in the exhibition area.

JB.

Title: Re: SD card read/write with Arduino
Post by: Nachtwind on Feb 13, 2009, 01:18 pm
Hi Sirmorris.. unfortunately i dont have much luck compiling your code - i am using 011 of the IDE with a 328 Chip..

Errors are:
Code: [Select]

In file included from C:\Documents and Settings\Administrator\Desktop\arduino-m328-win_current\arduino-0011-m328\hardware\cores\arduino/WProgram.h:6,
                from DevicePrint.cpp:1:
c:/documents and settings/administrator/desktop/arduino-m328-win_current/arduino-0011-m328/hardware/tools/avr/lib/gcc/../../avr/include/avr/signal.h:36:2: warning: #warning "This header file is obsolete.  Use <avr/interrupt.h>."
In file included from DevicePrint.cpp:3:
/DevicePrint.h:20: error: expected class-name before '{' token
23: error: microfat2.h: No such file or directory In function 'uint8_t proxyWriter(const uint8_t*, long unsigned int, uint8_t)':
In function 'void setup()':
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 13, 2009, 03:49 pm
As it stands the libraries don't compile under 11 - the Print functionality hasn't been abstracted from the serial library in this version.

You'll need to upgrade to version 0013. http://arduino.cc/en/Main/Software.

It also looks from this error that the mmc, microfat and deviceprint folders haven't been copied to the folder

arduino-00XY\hardware\libraries

which is where they should live.

I hope the upgrade won't cause you too many problems, but there are issues with some sketches - the libraries changed significantly during the 11-12 transition. You can keep both versions side-by-side though, so if you have a problem sketch just compile it under 0011. For all new work, start out in the 0013 IDE.

If you do need to port code then the rule seems to be - if it's an .h file then add

#include <WConstants.h>

and if it's a cpp file, add

#include <WProgram.h>

Good luck. If you need any help just yell.

C

Title: Re: SD card read/write with Arduino
Post by: Nachtwind on Feb 13, 2009, 04:08 pm
well... i thought it had to do with 0011.. alright.. so i upgraded.. lets see if it works now ;0)

So far it compiles and runs - did i miss something or do you use the same wiring as on the first post shown? Either that has changed or my Card reader is not soldered properly ><
Title: Re: SD card read/write with Arduino
Post by: jbennett on Feb 13, 2009, 11:46 pm
Just for the record - everything is working fine with 0012. Will upgrade to 0013 soon to keep up with the community!
Title: Re: SD card read/write with Arduino
Post by: omikun on Feb 15, 2009, 02:23 am
Hey guys, I've been following this very helpful thread but haven't made much progress. I've figured out it's not detecting the card is in since I get STA_NOINIT and STA_NODISK from the MMC init function. I'm using the 012 arduino software.

I've measured the pins with a multimeter and I suspect one of the ground pins isn't connected quite right. So I was wondering how you guys have it hooked up? I bought just the SD card holder and stuck a breakaway thing with the side with the long pins going in to the holder and wires soldered to the short pin side as shown below. I'm using a seeduino which has a 3v3 switch and it's hooked according to the diagram in the OP.

edit>oh right and the question: how do you guys have your card holder hooked up? Is there a better way of doing it? I could have gotten the card holder with a pcb soldered on from sparkfun but it was $15 but I want to use it in a final pcb design too. If nothing works I guess I'll have to suck it up and buy that sd holder board.

(http://i40.tinypic.com/fvinvk.jpg)

Any help would be great!
Thanks!
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 15, 2009, 11:36 am
Hi

I always reach for this diagram:
http://www.interfacebus.com/Multi_Media_Card_Pinout_MMC.html

SI on the diagram  =  arduino MOSI
SO on the diagram  =  arduino MISO

I always ground pin6 even though it says NoConnect.

So wire it like so:

sdCARD    ARDuino
1         10
2         11
3         gnd
4         +3v3
5         13
6         gnd
7         12


It looks like a great harness you've got there but I suspect that the little legs aren't making a good contact with the socket. Try making a plug-in board - you'll use it over and over.

When it comes time to attach it to protoboard I usually bend the little pins down a bit and use them to locate to the card solidly. I tack them, then solder the tabs at the sides to lock the holder in place. As you might expect really.

Check out some of the photos on a few of the posts on my blog, especially http://arduinonut.blogspot.com/2008/09/lash-up.html and http://arduinonut.blogspot.com/2008/09/programmer-redux.html

Test your wiring by writing a sketch to make all of the signal lines high, measure them (without a card in place!!) and then make them low, measure again. Test for shorts.  

I hope there's something here that helps.

Charlie
Title: Re: SD card read/write with Arduino
Post by: Nachtwind on Feb 15, 2009, 06:24 pm
Thank you, that sure was helpful, but my first thought that it might be really damn simple to connect a card to the arduino is more or less destroyed. If i look at your pics, especially those close-ups of your shield makes me realise that i need more than a few pins and cables to connect the card to the arduino.. do you have a schemata of what is connected what way to what else? I ask becuase this looks much different to what i have seen in the first post of this thread... and i am quite confused now ><
Title: Re: SD card read/write with Arduino
Post by: Nachtwind on Feb 15, 2009, 09:13 pm
Alright, after builidng it like done on the first post but using the same pins as in your post i was finally able to get to the point that the Serial window says: Done!

Unfortunately 'Done' is not exactly anything.. although it finds the file (or not) nothing is written into it ><

SDCard is formatted in FAT with 2GB Space - everything that is on it is just the 0byte data.txt

*edit* sectorsavailable() return 0
*edit2* you may chose to ignore the whole post.. somehow it seems my SD card is done with the world ;0) - it cant be written with anything ><

Title: Re: SD card read/write with Arduino
Post by: jbennett on Feb 15, 2009, 10:46 pm
I had to 'fill up' my data.csv file with junk data so that it was bigger than 512 bytes before it would write anything. One of the sketches which was presented in this post recommended at least 15kb file size; having a data.txt file of 0 bytes would lead to sectorsavailable() returning 0 & there being not enough space in the file to write any data. As I understand it, you will only be able to write data to the file up until the original file size; more data will NOT increase the file size as required, it will just fail to write to the file.  (I think - sirmorris will correct me if this is wrong! :))

Try making your file larger... fill it with anything you like as it will be overwritten anyway. You could even take any other old .txt file & rename it if you wanted, saves the hassle of making stuff up!

Hope this helps,

JB.
Title: Re: SD card read/write with Arduino
Post by: Nachtwind on Feb 15, 2009, 10:54 pm
wow, thats been exactly it :0)

Finally i can save stuff :0)))
Title: Re: SD card read/write with Arduino
Post by: jbennett on Feb 16, 2009, 08:15 am
Hooray - I've been able to give something BACK to the forums instead of just using everyone else's knowledge!!

Glad it's working for you!!

JB
Title: Re: SD card read/write with Arduino
Post by: JustinHoMi on Feb 17, 2009, 06:20 am
Quote
if you just want to log data (and not necessarily read it) i have an sdlogging library that saves to fat16 formatted SD cards.  i use it to log GPS & sensor data: http://www.ladyada.net/make/gpsshield/download.html


Is anybody using this library? It overcomes some of the limitations of the libraries everyone is discussing here.

I came across this one too, which supports fat32 and sdhc: http://code.google.com/p/wavehc/
Title: Re: SD card read/write with Arduino
Post by: Nachtwind on Feb 17, 2009, 09:54 am
I have played arround with LadyAdas code for a while, but as i was not able to set up the wiring right for it i could not really test it.. but what i noticed was quite a big overhead.. if i remember right it took quite a bunch of space on the arduino.. yet it seemed really good from its limitation/options.
Title: Re: SD card read/write with Arduino
Post by: JustinHoMi on Feb 17, 2009, 01:00 pm
Is the wiring not the same as the others? I haven't taken time to examine the schematic yet.
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 17, 2009, 09:58 pm
Hi all.

I'm back from a short break - I'm glad to see things happening.

The wiring should be the same for the ladyada code - the arduino's hardware SPI support works on a certain set of pins only. I tried my code out on a ladyada GPS board at dorkbot London a few weekends ago and it worked without modification.

As for using the ladyada code 'to get around the limitations of uFat' - well we're going full circle ;) uFat is my way of getting around the limitations of having very little RAM and flash left after using the full FAT library..!

If your sketch is quite small and you can use the more fully featured library then I would suggest doing so as it makes your life really easy! uFat was designed for situations when this isn't quite the case :) I've traded simplicity for RAM. A full sketch of uFat, MMC & deviceprint will use under 5k. You have to make compromises - this is a classic trade-off!

The DevicePrint code will work with anyone's library. You do need the arduino IDE version 0012/0013 though.

@JB - you're spot on. The file needs to be stuffed beforehand. And contiguous! Else strange results are going to happen  :P



Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 17, 2009, 10:09 pm
@NachtWind -

Quote
If i look at your pics, especially those close-ups of your shield makes me realise that i need more than a few pins and cables to connect the card to the arduino..


The board there 'has a lot more than the requisite 6 resistors and a regulator' :)

It also has a monostable multivibrator to drive an LED which flashes when there's a positive transition on the clock line.  That accounts for about 6/7 components  :D
Title: Re: SD card read/write with Arduino
Post by: Nachtwind on Feb 17, 2009, 10:29 pm
hehe, nice idea ^^

Well, i got mine to work at last and thats more than i had ever expected ;0)

Title: Re: SD card read/write with Arduino
Post by: trialex on Feb 17, 2009, 11:26 pm
Awesome!

Can I make a request?

It would be awesome to have a single post that has a schematic, a link to the library, and a small example sketch.

That way everyone could be confident they are on the same page.

Thanks again for everyone's efforts!
Title: Re: SD card read/write with Arduino
Post by: Nachtwind on Feb 18, 2009, 02:55 pm
... or simply pushing the most needed infos to the playground?
Title: Re: SD card read/write with Arduino
Post by: JustinHoMi on Feb 18, 2009, 03:43 pm
Has anybody experimented with higher/lower resistor values in the voltage divider?
Title: Re: SD card read/write with Arduino
Post by: Nachtwind on Feb 19, 2009, 11:14 am
minimally different ones - i have used 3.3k and 1.6k, it still worked.
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 19, 2009, 11:45 am
The voltage requirements at the MMC card inputs (MOSI, CLK, /SS) are defined in the MMC card product manual:

VDD in this case must be between 2.7 and 3.6v.

Input HIGH voltage:
min:  0.625 * VDD
max:  VDD + 0.3

Input LOW voltage:
min:  VSS - 0.3
max:  0.25 * VDD

As long as the voltage tapped off the divider falls within this range, all should be well.

The document to read is here:
http://www.sandisk.com/Assets/File/OEM/Manuals/ProdManRS-MMCv1.3.pdf

Title: Re: SD card read/write with Arduino
Post by: sirmorris on Feb 20, 2009, 11:25 am
I've summarised all of this good stuff in a new thread:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235125412

I'm sure I've missed something :P
Title: Re: SD card read/write with Arduino
Post by: pickles on Feb 24, 2009, 03:20 am
All,

I had struggled with the DOSonCHIP module for a week or so. I stumbled upon this thread and uFAT2 solved all of my problems. Thanks to everyone who posted.
Title: Re: SD card read/write with Arduino
Post by: DMerriman on Mar 22, 2009, 05:24 pm
Just tried to download the library file on a Linux box using Firefox, and MediaFire promptly threw up by telling me to either sign in or use a supported browser (Internet Exploder?).
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Mar 22, 2009, 06:09 pm
Read to the end or hop over here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235125412/
:)
Title: Re: SD card read/write with Arduino
Post by: smelios on Mar 24, 2009, 02:22 am
Hello everyone
Does anyone know to make the raw program write in blocks smaller than 512?
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Mar 24, 2009, 07:45 am
512 bytes is the sector size of the device.

Why do you want to write smaller blocks?
Title: Re: SD card read/write with Arduino
Post by: smelios on Mar 24, 2009, 07:38 pm
I'm trying to sample a guitar signal and store it to the SD card. It looks like when the Arduino writes the recorded signal to the SD card it takes up some time. Which means that the input signal gets ignored for awhile. I was hoping that if i could shorten the number of bytes being sent to the card it wouldn't ignore the sinput signal to a point that it wouldn't be noticed by the user. If this is to vauge I will gladly go into more detail later. Thanks for taking interest  ::)
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Mar 24, 2009, 08:04 pm
I did find that I'm not setting high speed mode  :-[

This might improve matters.

Another thing you might consider is setting up a 'double buffer' system, where you're reading values into one buffer under interrupt control whilst writing the other. You can tune the sampling rate so that you get a consistent period.

Another thing to do might be to break the 'write sector' function so that you can write bytes at a time... You'd have to re-send a command every 512 bytes or so, but that shouldn't take long - there's a latency of about 12 bytes as the write is finished up, then the next sector is primed.

Sorry if that all sounds quite complicated - but it has to be. You don't get something for nothing on a microcontroller  :P

Title: Re: SD card read/write with Arduino
Post by: smelios on Mar 24, 2009, 10:09 pm
Well to be honest i'm using the sd-raw program at the beginning of this thread so its notihng to do with your code. I have been following your code and will probably try to use it if I can't figure out my current idea. Thanks again you have been a big help to everyone here who is implementing sd to thier projects ;D
Title: Re: SD card read/write with Arduino
Post by: sirmorris on Mar 25, 2009, 12:10 pm
Thanks :)

This procedure would likely be the same with whichever library you use. The SPI protocol for writing to the card goes like this:

1. Send 'write sector command' - 0x58 a b c d 0x00
2. Await command acceptance - ie you receive 0x00
3. Send data token - 0xFE
4. Send 512 bytes
5. Send dummy checksum - 0x00 0x00
6. Await 'done' status code - ie you receive 0x00

Mostly these 6 steps are all wrapped up in a function. What I suggest is that 1-3 are split out into one function, 4 in another, and 5-6 in yet another.

StartWrite() - does 1-3
WriteByte - actually would be the existing 'xfer byte' routine
EndWrite() - does 5 & 6


Start the write with steps 1,2,3.

Then write bytes at a time (step 4) until you've sent 512 of the blighters.

Do 5 & 6. If you want to continue, start again at the next sector with steps 1-3.

Let me know how you get on!
Title: Re: SD card read/write with Arduino
Post by: breenmachine on Apr 06, 2009, 03:23 am
A little late and not extremely relevant with all this new UFat stuff but...

For those still curious about just using the SD card in good old raw mode (hey, I found it useful...) and having your writes persist, read on.

A few people have noticed that your writes to the card "dissappear" after restarting the Arduino. The block size is set up to be 512 bytes, and in the code on the first page, a 512 byte buffer is kept, once it is full, it is written out to the card.

This can be trivially disabled so that all writes are written to the card immediately (no buffering). Just open up "sd_raw_config.h" and look for the line:
#define SD_RAW_WRITE_BUFFERING 1
change it to
#define SD_RAW_WRITE_BUFFERING 0

and you should be all set...dunno if someone else already posted this but I saw the question asked and couldn't find the answer myself so I decided to take a look at the code.
Title: Re: SD card read/write with Arduino
Post by: potatohead on Apr 06, 2009, 04:16 am
Quote
Posted by: breenmachine
For those still curious about just using the SD card in good old raw mode


What is meant by using the SD card in "raw mode"?  Is it similar to saving data in an external EEPROM chip?

How is the saved data read from the card?

Thank you
Title: Re: SD card read/write with Arduino
Post by: breenmachine on Apr 06, 2009, 04:37 am
Using it in raw mode is reading and writing directly from/to the bytes on the card. It is like if you're SD card was a very large array of bytes.

The original code on page 1 of this thread only worked in raw mode.

One of the drawbacks is, it is not as easy to access the data that you write to the card on a computer (with UFat you can open it up in a text file).

The upside is, you can get away with running the SD card at 5v in raw if you dont have the correct resistors to get it down to 3.3 (for a while anyways!). Also it probably takes slightly less code memory on the arduino.
Title: How to attribute another pin  for SlaveSelect ?
Post by: harima2 on Apr 07, 2009, 08:30 pm
Hi everybody..

I would like to change the pin select  SS 10 (because 10,11,12,13 is yet busy );

for example define Slave Select 8

..do you know how to make this...?  
Title: Re: SD card read/write with Arduino
Post by: smelios on Apr 08, 2009, 05:28 am

Quote
Posted by: breenmachine
A few people have noticed that your writes to the card "dissappear" after restarting the Arduino. The block size is set up to be 512 bytes, and in the code on the first page, a 512 byte buffer is kept, once it is full, it is written out to the card.

This can be trivially disabled so that all writes are written to the card immediately (no buffering). Just open up "sd_raw_config.h" and look for the line:
#define SD_RAW_WRITE_BUFFERING 1
change it to
#define SD_RAW_WRITE_BUFFERING 0

and you should be all set...dunno if someone else already posted this but I saw the question asked and couldn't find the answer myself so I decided to take a look at the code.



If this is true you just saved me a lot of trouble  ;D
Can this be done with the read function as well? I think a 512 byte buffer gets filled there too.
Title: Re: SD card read/write with Arduino
Post by: smelios on Apr 08, 2009, 10:53 pm
I tried changing

#define SD_RAW_WRITE_BUFFERING 1
to
#define SD_RAW_WRITE_BUFFERING 0

with no luck, does that header file need to be recompiled or can i just change it and save?
Title: Re: SD card read/write with Arduino
Post by: reg.arvidson on Apr 08, 2009, 10:58 pm
recompile recompile, restart the arduino IDE
Title: Re: SD card read/write with Arduino
Post by: smelios on Apr 08, 2009, 11:50 pm
Sorry im a noob when it comes to this stuff. I opened sd_raw_config.h in microsoft visual c++ 2005 and the option to recomplie isn't available. What should I do?
Title: Re: SD card read/write with Arduino
Post by: reg.arvidson on Apr 09, 2009, 12:14 am
Err... I meant to restart the Arduino executable... that you use to write code and upload to the board with.
Title: Re: SD card read/write with Arduino
Post by: wyojustin on Apr 12, 2009, 02:13 am
You rock!

I just got this working out of the box.  Nice job and thanks!

Justin
:D
Title: Re: SD card read/write with Arduino
Post by: zklapow on Aug 08, 2009, 12:53 am
im wondering if would be possible to bootload the arduino from the SD card. The arduino recieves its sketch through the tx and rx pins right so theoretically if you had a 2 cores one to read the sketch and transmit it to the arduino and the arduino itself it could be used as a bootloader.
Title: Re: SD card read/write with Arduino
Post by: florinc on Aug 08, 2009, 02:56 am
What would be the benefit of this? The sketch residing on SD card instead of internal flash memory?
Title: Re: SD card read/write with Arduino
Post by: BroHogan on Aug 08, 2009, 03:45 am
I could think of one advantage. If you had a commercial product the users could upload "new versions" themselves. Dribbleware!  :D
Title: Re: SD card read/write with Arduino
Post by: florinc on Aug 08, 2009, 03:03 pm
Right, good point. A user upgrade would consist in copying the hex file on the SD card, easier than asking the user to go through the Arduino IDE.
Title: Re: SD card read/write with Arduino
Post by: ReCreate on Sep 20, 2009, 05:58 am
Ummm...
I tried the example code after installing the library, and i get:
Code: [Select]

from D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:13:

D:\Program Files\arduino-0017\hardware\libraries\SDcard\/sd_raw_config.h:86:6: error: #error "no sd/mmc pin mapping available!"

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp: In function 'uint8_t sd_raw_init()':

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:167: error: 'configure_pin_mosi' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:168: error: 'configure_pin_sck' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:169: error: 'configure_pin_ss' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:170: error: 'configure_pin_miso' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:172: error: 'unselect_card' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:198: error: 'select_card' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp: In function 'uint8_t sd_raw_read(uint32_t, uint8_t*, uint16_t)':

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:418: error: 'select_card' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:423: error: 'unselect_card' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:455: error: 'unselect_card' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp: In function 'uint8_t sd_raw_write(uint32_t, const uint8_t*, uint16_t)':

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:663: error: 'select_card' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:668: error: 'unselect_card' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:689: error: 'unselect_card' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp: In function 'uint8_t sd_raw_get_info(sd_raw_info*)':

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:809: error: 'select_card' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:814: error: 'unselect_card' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:863: error: 'unselect_card' was not declared in this scope

D:\Program Files\arduino-0017\hardware\libraries\SDcard\sd_raw.cpp:908: error: 'unselect_card' was not declared in this scope


Its a Shame it didn't work...Can someone tell me what i did wrong?
Also, I have a question, What would happen if you disconnect the card and connect it into a card reader?
Would it show up as a TXT file or a file without extension or will you have to use a "disk editor" to manually see the bytes and sectors of the stick?
Title: Re: SD card read/write with Arduino
Post by: ReCreate on Sep 20, 2009, 06:37 am
And i have another question, How do i connect my SD card?
Do i need to buy one of the shields out there?
Title: Re: SD card read/write with Arduino
Post by: Montspy on Sep 26, 2009, 08:07 am
Hi ! I'm new in the forum.
First : thanks for this tutorial It looks like very easy to follow.
I just have 2 questions :
I have a handful of 470 and 180 Ohms resistors, is that possible to replace the 1.8kO by a 180O  and the 3.3kO by a 510O. In theory it's OK :
Vout = Vin x R2/(R2+R1)
Vout = 5 x 470/(470 + 180)
Vout = 3.62V

My 2nd question : Is the Arduino has a 3.3V output to connect the 4th pin of the SD card ?

Bye.
Montspy.
Title: Re: SD card read/write with Arduino
Post by: fritzbrause on Sep 30, 2009, 10:40 pm
I have followed the instructions 1:1, compiled the demo sketch, but can never manage to get over "MMC/SD initialization failed". Is there a problem with Arduino Duemilanove ATMega328?

The SD Card is fat16 formatted...

In desparate need for an answer,
fritz
Title: Re: SD card read/write with Arduino
Post by: florinc on Oct 01, 2009, 03:16 pm
Try multiple SD cards. The one you have may be defective. It happened before.
Title: Re: SD card read/write with Arduino
Post by: fritzbrause on Oct 01, 2009, 04:30 pm
Hi, I did try multiple cards. All of them work on my notebook though.

It is really frustrating...

I would be even willing to pay if somebody could compile a zip-file with all libraries and sketches required to run the SD-demo with an off-the-shelf Arduino duemilanove.
Title: Re: SD card read/write with Arduino
Post by: Mart on Oct 16, 2009, 05:09 pm
What library has the smallest footprint? ( I need to create new file and to oread/write :) )
Title: Re: SD card read/write with Arduino
Post by: BroHogan on Oct 16, 2009, 09:25 pm
Without regard to the footprint, the ability to read from the card narrows the field. The ability to create new files from scratch narrows the field again.

The Fat16 lib (http://code.google.com/p/fat16lib/). does both and is well documented. So it's definitely worth looking at.
Title: Re: SD card read/write with Arduino
Post by: pixeldoc2000 on Oct 29, 2009, 03:10 am
For all who still have problems with SD-Card, here is some infos...

1. Pull-Ups
add 10K pull-ups to 3.3V for "CS" (CMD) and "DO" (DAT0) line. (refer to sd/mmc datasheets (http://www.digitalspirit.org/file/index.php/obj/docs/sd/)).

(http://pixeldoc.kicks-ass.net/public_stuff/electronic/sdmmc/sdcard_pullup.png)
This is from  Sandisk SD Card Product Manual (http://www.digitalspirit.org/file/index.php/obj/docs/sd/).




2. Partition and Filesystem
Ensure your SD-Card contains one primary FAT16 partition.

Windows: Use Active@ Partition Manager (http://www.pcdisk.com/), Acronis Disk Director, Paragon Partition Manager or simular to verify your Card is correctly set up.
Don't rely on Windows Partiton info, because windows shows "FAT" filesystem for FAT16 and FAT12 (only with small SD-Cards like 16MB).
(http://pixeldoc.kicks-ass.net/public_stuff/electronic/sdmmc/sdcard_apm_fat16.png)

Linux: Use cfdisk and mke2fs.




3. Updated Schematic
(http://pixeldoc.kicks-ass.net/public_stuff/electronic/sdmmc/pd_arduino_sdmmc_simple_v1.jpg)




4. Arduino Library
I also recommend Fat16 (http://code.google.com/p/fat16lib/) lib. Its really nice and well documented.
Work right out of the box for me with Arduino 0017, Arduino Duemilanove and three 16MB SD-Card for my digi-cam.




Anyway, this is a very basic solution for (very) low speed SD-Card access.
Its recommended to use a real bi-directional level shifter (5.0V <-> 3.3V). Read more about it here (http://www.shop.display3000.com/wichtiges-zubehoer/experimentierplatinen/sd-speicherkartenplatine.html) (German).




:) don't give up...
Title: Re: SD card read/write with Arduino
Post by: tep on Nov 01, 2009, 12:17 pm
Hi!

Is this compatible with the SD slot of the Ethernet Shield?
Title: Re: SD card read/write with Arduino
Post by: hs92 on Dec 02, 2009, 02:20 pm
Just wondering if someone could give me some advice, I am looking at using data logging on an Arduino board, a 3D accelerometer for postion sensing and then an SD card to store the data. Having read this post i understand it is possible to do this, but I would be very grateful if someone could maybe outline how i would go about doing this as i am relatively new to the Arduino.

Thanks...

(sorry if this is maybe not the best post to have posted in!)
Title: Re: SD card read/write with Arduino
Post by: GH_Blackout on Dec 17, 2009, 02:58 pm
(http://photo.promisehosting.net/images/365_IMG_0410_tn.jpg) (http://photo.promisehosting.net/view-365_IMG_0410.jpg)

hi guys --- Do i fail the wiring? dont work
Title: Re: SD card read/write with Arduino
Post by: PaulS on Dec 17, 2009, 03:54 pm
There appear to be 6 resistors that look like they are trying to form voltage dividers. Three have one end on the ground bus, with a red wire going to the ground pin on the freeduino.

Red is supposed to be used for +V, not ground. Although the electrons don't care what color the insulation is, people make assumptions about the purpose of a wire based on it's color.

There are pairs of resistors, with wires leading from the center point to some Freeduino pins. It's hard to be certain that the resistors and wires are on the same bus, but I'll assume that they are.

The other end of the resistors do not all share a common +5V bus, so it would appear that you are not getting any power to the voltage dividers.

I also don't see an SD card reader/writer in the picture. So, the purpose of the wires and non-functioning voltage dividers is not apparent.

So, I guess I'd have to say that, yes, you fail the wiring.

What are you trying to do?
Title: Re: SD card read/write with Arduino
Post by: GH_Blackout on Dec 17, 2009, 05:46 pm
@Pauls: thanks

Your advice about colors is right : thanks.
For Resistors dimesions im following a http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1206874649/8

For voltage i have linked SD_pin_4 of 3.3V of freeduino (like as combatduino or experimentduino).

Freeduino works, but the software return me :
"MMC/SD initialization failed"

I think isnt sofware problem but "wiring problem" because i'm eletronic-newbie (only teoric)


update:
(http://photo.promisehosting.net/images/361_IMG_0412_tn.jpg) (http://photo.promisehosting.net/view-361_IMG_0412.jpg)
Title: Re: SD card read/write with Arduino
Post by: PaulS on Dec 17, 2009, 06:11 pm
Quote
For voltage i have linked SD_pin_4 of 3.3V of freeduino


I don't understand this statement. The freeduino appears to be a 5V device, just like the Arduino. You should have a wire from +5V to the buss that one end of three of the 3 resistors are on. The other 3 resistors have one end on a bus which is connected to ground on the freeduino. There should be three bars (like you have) where two resistors and a wire come together. The three wires go to digital pins on the freeduino.

There is also a wire from +5V on the freeduino to the SD card, to power it.
Title: Re: SD card read/write with Arduino
Post by: GH_Blackout on Dec 17, 2009, 07:29 pm
@pauls:
do u have wiring planning?
i have tried roland lib and arduinonut lib --- not work

i wiring wrong .... is a fact
but i have copyied the roland riegel wiring :-(
Title: Re: SD card read/write with Arduino
Post by: PaulS on Dec 17, 2009, 07:49 pm
No, you haven't copied the wiring correctly.

You have resistors plugged into C1, C2, and C5. These are on three separate bars. Nothing else is connected to those three bars. You need to connect them together, and to +5V.

You have a yellow wire in E7, going to the freeduino. Nothing else is connected to the 7 bar. What is that wire (supposed to be) for?

What are the ground wires on the #6 bar for?

Where is the SD card reader?
Title: Re: SD card read/write with Arduino
Post by: GH_Blackout on Dec 17, 2009, 08:09 pm
rows c1 c2 c5 are wired through by - column

i have measured power con b1 b2 b5 and power is 3V3

rows #3 and #6 are wired through and they are wired in - column

c7 going to digital pin 12 of freeduino

(http://photo.promisehosting.net/images/474_IMG_0415_tn.jpg) (http://photo.promisehosting.net/view-474_IMG_0415.jpg)
Title: Re: SD card read/write with Arduino
Post by: GH_Blackout on Dec 17, 2009, 08:25 pm
thx pauls .. work nice

(the problem is manual SD sock)
Title: Re: SD card read/write with Arduino
Post by: Syntetik on Dec 25, 2009, 11:25 pm
OMG! At last I've get info from SD card. That was painful :) At the begining I used HP card 16 MB (card comes with my HP PhotoSmart 850 photocamera) and my Duemilanove don't initialize it. Then I tried with SanDisk SD 128 MB card and yes - it works! I use fat16 library.

I've get my Duemilanove some weeks ago and I preffer to write in Assembler, so I will try to put all this stuff in that language, because, if compiled C sketch (.PDE & .CPP) have length of 9 KB, then Assembler output will be smaller ~10 times and more. So I think Assembler code will be better choice for our small friend - Arduino with 16-32 KB memory onboard.

Thank You guys! I'm very happy!  ;)

Now my fantasies about robots and machines are going deeper and deeper.

One question - isn't there problems for FAT16 reading card with big capacity? isn't there a limitations?

I search in google and got answer - "The size limit for logical drives using the FAT16 file system in Windows Me/98/95 and MS-DOS is 2GB." Is it because of these systems, or FAT16 structure cannot hold values bigger?
Title: Re: SD card read/write with Arduino
Post by: sirus20x6 on Dec 31, 2009, 09:23 pm
Sorry to resurrect such an old thread but mother google informs me that this is the definitive place to discuss "arduino sdcard" :)

so I've loaded up the sketch and I get
Code: [Select]

                from /home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:13:

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw_config.h:86:6: error: #error "no sd/mmc pin mapping available!"

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp: In function 'uint8_t sd_raw_init()':

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:167: error: 'configure_pin_mosi' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:168: error: 'configure_pin_sck' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:169: error: 'configure_pin_ss' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:170: error: 'configure_pin_miso' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:172: error: 'unselect_card' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:198: error: 'select_card' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp: In function 'uint8_t sd_raw_read(uint32_t, uint8_t*, uint16_t)':

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:418: error: 'select_card' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:423: error: 'unselect_card' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:455: error: 'unselect_card' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp: In function 'uint8_t sd_raw_write(uint32_t, const uint8_t*, uint16_t)':

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:663: error: 'select_card' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:668: error: 'unselect_card' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:689: error: 'unselect_card' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp: In function 'uint8_t sd_raw_get_info(sd_raw_info*)':

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:809: error: 'select_card' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:814: error: 'unselect_card' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:863: error: 'unselect_card' was not declared in this scope

/home/sirus/arduino/hardware/libraries/SDcard/sd_raw.cpp:908: error: 'unselect_card' was not declared in this scope


Title: Re: SD card read/write with Arduino
Post by: sirus20x6 on Dec 31, 2009, 10:57 pm
I think that my issue is that i have a 328 :(
Title: Re: SD card read/write with Arduino
Post by: pixeldoc2000 on Jan 04, 2010, 08:46 pm
@Syntetik
Quote
One question - isn't there problems for FAT16 reading card with big capacity? isn't there a limitations?

I search in google and got answer - "The size limit for logical drives using the FAT16 file system in Windows Me/98/95 and MS-DOS is 2GB." Is it because of these systems, or FAT16 structure cannot hold values bigger?

You can't address more than 65.535 Cluster (= 16 Bit) with FAT16.
It also depends on a few other things like Clustersize, Bootsector, Backup Sectors...

@sirus20x6
Which library are you using?
Look like your library "SDcard" does not compile correctly.
Maybe try to "clear" library directory. delete all *.o files in /home/sirus/arduino/hardware/libraries/SDcard/ and try again.

Quote
I think that my issue is that i have a 328

You mean an ATmega328 on your Arduino?
I don't think thats the problem. Arduino first compiles all basic stuff and libraries. Than it compiles your sketch.
Title: Re: SD card read/write with Arduino
Post by: nandhakumar on Jan 21, 2010, 12:25 pm
Hai
Title: Re: SD card read/write with Arduino
Post by: nandhakumar on Jan 21, 2010, 12:25 pm
Hello everyone. I m from India and currently doing my final year project.
I m trying to interface an SD card with Arduino atmega8 for datalogging. I dont have any shield for the interface,since it is not affordable for me. and i m following this schematic

www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1206874649/8

I tried the DevicePrint library, File Logger library.

But watever I try , I get only the following error msg "card Failed initialising". :(

I m using Arduino-0017 IDE in Linux.

could any one help me.

Thanks in advance.

Nandhakumar
Title: Re: SD card read/write with Arduino
Post by: pixeldoc2000 on Jan 25, 2010, 10:23 pm
Quote
Hello everyone. I m from India and currently doing my final year project.
I m trying to interface an SD card with Arduino atmega8 for datalogging. I dont have any shield for the interface,since it is not affordable for me. and i m following this schematic

www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1206874649/8

I tried the DevicePrint library, File Logger library.

But watever I try , I get only the following error msg "card Failed initialising". Sad

I m using Arduino-0017 IDE in Linux.


Have you read my post: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1206874649/124#124 ?

- How many different SD-Card have you tested (some card are much more picky than others)
- i've had good results with two old 16mb sd-card (came with my canon digital camera) and one 256MB Card
Title: Re: SD card read/write with Arduino
Post by: carl47 on Jan 26, 2010, 08:02 am
Quote
Nandhakumar


If dataloging does not require you to access the sd card
data on your pc using a FAT.

If you just want to log data straight to and from the sd card using the arduino.

Then look at:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1259789744/0#0
Title: Re: SD card read/write with Arduino
Post by: unic on Feb 03, 2010, 06:13 pm
Hi, i just want to test this uFAT, but i cant find the mmc1.rar from http://groups.google.com/group/micro-hacker

has anyone the files i need ?

btw, heres my idea of an Cardslot:
(http://img52.imageshack.us/img52/5448/20100203180701240.jpg)
Its just a mini or micro SD-Cardadapter
Title: Re: SD card read/write with Arduino
Post by: cemath on Feb 08, 2010, 08:38 am
To Nnk:

I've had problems initializing a card also, it turned out I had a bad contact between my card reader board and the header it was sitting upon. I soldered everything and it works perfectly now. You might want to verify all the electrical contacts, just to be sure.

Good luck!

Note: I use the very same circuit that you are using, except for 2 additional 100nF and 47uF capacitors between the 3.3V and GND pins next to the card (it probably works without that). I use a 2GB SD San Disk card.
Title: Re: SD card read/write with Arduino
Post by: SirPoonga on Feb 08, 2010, 09:01 pm
Has anyone used the fat16 library SparkFun (http://www.sparkfun.com/commerce/product_info.php?products_id=9520) mentions?

I went back a couple of pages here but didn't see this mentioned.  I am looking for a way to read files off a removable storage device.  The files will have some commands.  A push of the button on the arduino will cycle through the files/commands.  I need to be able to read and write tot eh storage device from windows or mac.  I think hooking up microSD and using that library will work.
Title: Re: SD card read/write with Arduino
Post by: nandhakumar on Mar 04, 2010, 10:58 am
This is Nnk again .

Thanks to carl47 and Cemath for the response . I tried the way u said in ur posts. But it did not work. I also tried re-building and re-testing the connections too.But still the same.

I am really confused and not clear on how to proceed with SD card interfacing with Arduino . Here I will tell the real need or requirement of my project and the purpose for which I need a SD card interfacing.

My project name is Tran-Duino , the purpose of the project is to track a moving vehicle,say ,a Bus using GPS and display the upcoming or the next stop names in the route by placing a display inside the Bus.

Inorder to store the latitude, longitude and location names , I will be using a SD card. The SD card will contain these information in the form of a textfile with fields separated by commas and one location name per line.

for example A line in the file may hv values like

13.119697 , 80.218537 , kolathur

Now , when the bus moves in the route , I ll get the GPS values from a GPS receiver module about the bus curent location frequently, I ll also fetch the values from the sd card , compare it , if it matches then the location name is sent to the display unit.

All these processing are done using the arduino. Now the work of the SD card is

[must be able to store values when i go to locations and get the GPS positions (for storing purpose) ]
[must be able to read from the card for comparing it with received values from GPS]
[/list]

So , please tell me your suggestions on how to achieve this task. If it is possible to do this task without a shield for SD card it will be more useful.

Thanks in advance

N.Nandhakumar
Title: Re: SD card read/write with Arduino
Post by: pineapple2010 on Mar 07, 2010, 01:22 pm
Hi,
   I'm new to Arduino. Tried to search for micro SD/regular SD card adapter/holder to solder it into PCB without any results. >:( :o Could somebody help me to find where to buy it?
Thanks.
Title: Re: SD card read/write with Arduino
Post by: pineapple2010 on Mar 09, 2010, 12:35 am
Already found it at SparkFun.com  :) ;)

http://www.sparkfun.com/commerce/product_info.php?products_id=136
Title: Re: SD card read/write with Arduino
Post by: gdgtfiend on Mar 16, 2010, 05:30 am
Hello all,

I am relativly new to all of this (I just joined the forum 30 seconds ago), and I was wondering if I could use this to read/write Replicator G files.

I have a makerbot, and I have been trying to find a way to use it without hooking my computer up to it every time I want to print. I have found the serial commands given by the computer to initiate Build form SD, and so I wanted to set up my arduino to take an SD card with the file on it, transmit that file to my Makerbot, and then send the Build from SD command.  Does this sound feasible to you all?
Title: Re: SD card read/write with Arduino
Post by: nnnn on Mar 25, 2010, 07:01 am
hi friends i am doing an data logger project i'am using the below code... when i interact with harware i could'nt inizilaise the card this is ma error could any one help me out....

#include <Spi.h>
#include <sd-reader_config.h>
#include <sd_raw.h>
#include <sd_raw_config.h>

int print_disk_info();
int sample();
int readDisk();

byte incomingByte;
void printWelcome();
long int address;
byte tempBytes[2];


void setup()
{

 Serial.begin(115200);
 delay(1000);

 printWelcome();
 if(!sd_raw_init())
 {
    Serial.println("MMC/SD initialization failed");
 }
print_disk_info();
//sd_raw_init();
}



void loop()
{
   int i;

   if(Serial.available()>0)
   {
        incomingByte=Serial.read();

      switch(incomingByte)
      {
          case 114:
                    readDisk();
                    break;
          case 115:
                    sample();
                    break;
          default:
                    break;
      }
   }
}

int sample()
{
   int i,j;
   int temp;
   byte low;
   byte high;
   byte inByte;

   Serial.println();
   Serial.println();
   Serial.println("Sampling..");
   for(i=0;i<20;i=i+2)
   {
       if(Serial.available()>0)
       {
           inByte=Serial.read();
           if(inByte==113) return 0;
       }
       temp=analogRead(0);
       Serial.print(temp,DEC);
       Serial.print(" ");

       //Convert int to 2 bytes
       low=temp&0xFF;
       high=temp>>8;
      // Serial.print(temp,DEC);
       //Serial.print(low,DEC);
       //Serial.print(high,DEC);

       tempBytes[0]=low;
       tempBytes[1]=high;

       if(!sd_raw_write(i,tempBytes,2))
       {
         Serial.print("Write error");
       }
       //sd_raw_sync();
       delay(1000);

 Serial.println();

   }

   return 1;
}


int readDisk()
{
   byte low;
   byte high;
   byte info[2];
   int i;
   int  result;
   Serial.println();
   for(i=0;i<50;i=i+2)
   {
       sd_raw_read(i,info,2);

       //Serial.print(info[0],DEC);
       //Serial.print(" ");
       //Serial.print(info[1],DEC);
       low=info[0];
       high=info[1];
       result=high<<8;
       //result<<8;
       Serial.print(" ");
       Serial.print(result+low,DEC);
       Serial.print(" ");
   }

}

void printWelcome()
{
   Serial.println("------------------------");
   Serial.println("Data sampling system");
   Serial.println("send r to read disk");
   Serial.println("send s to start sampling");
   Serial.println("send q to stop sampling");
   Serial.println("Ready.....");
   Serial.println("-------------------------");
}


int print_disk_info()
{


   struct sd_raw_info disk_info;
   if(!sd_raw_get_info(&disk_info))
   {
       return 0;
   }


   Serial.println();
   Serial.print("rev:    ");
   Serial.print(disk_info.revision,HEX);
   Serial.println();
   Serial.print("serial: 0x");
   Serial.print(disk_info.serial,HEX);
   Serial.println();
   Serial.print("date:   ");
   Serial.print(disk_info.manufacturing_month,DEC);
   Serial.println();
   Serial.print(disk_info.manufacturing_year,DEC);
   Serial.println();
   Serial.print("size:   ");
   Serial.print(disk_info.capacity,DEC);
   Serial.println();
   Serial.print("copy:   ");
   Serial.print(disk_info.flag_copy,DEC);
   Serial.println();
   Serial.print("wr.pr.: ");
   Serial.print(disk_info.flag_write_protect_temp,DEC);
   Serial.print('/');
   Serial.print(disk_info.flag_write_protect,DEC);
   Serial.println();
   Serial.print("format: ");
   Serial.print(disk_info.format,DEC);
   Serial.println();
   Serial.print("free:   ");

   return 1;
}


Title: Re: SD card read/write with Arduino
Post by: bozz01001 on Mar 26, 2010, 10:43 am
Hi all, I was tryning without success to install a Libelium Sd Module on a Arduino Mega (ATMEGA1280) :'(. I've searched on the net for some information; everyone say that this module doesn't work with Arduino Mega and nobody has a solution :o.
So anyone tried to use this circuit and this library with Arduino Mega?
Thank you for help.
Title: Re: SD card read/write with Arduino
Post by: cadrogui on Mar 27, 2010, 01:14 am
anyone make the pcb of this???

tnks
Title: Re: SD card read/write with Arduino
Post by: cadrogui on Mar 27, 2010, 11:38 pm
if anyone want the PCB file, send me a PM, its make on eagle software

;)
Title: Re: SD card read/write with Arduino
Post by: jonnyboy323 on Mar 28, 2010, 01:51 am
Hello All!
I'm am new to the Sd card phase. My question is which of the libraries and setups do you recommend for logging gps data strings to an sd card. Yes I know about Ladyadas shield and code but I am overwhelmed. I bought the sparkfun arduino sd shield without realizing it was a failed product. Through the forums I found how to wire it up and got the sparkfun code working but I'm still having small issues. So i'm coming here to find out where i should start.

Jon
Title: Re: SD card read/write with Arduino
Post by: SirPoonga on Mar 29, 2010, 05:53 pm
I am looking for a library that solves my needs or information on how to do it.  I have a project that will use asynclab's wishield and a microsd card.  All I need to do is read files from an SD card.  There can be any number of files on the SD card so I think uFAT is out.  I can do what I want with sdlaftlib after I make my own read function.  I need to be able to read a byte at a specific position in a file.  The files will be created on a PC.

When I include both the wishield and sdfatlib they don't leave much memory left for the program.  In fact, right now my program is 1.3k over the limit of a 368 arduino.  I went through the sdfatlib and took out everything that deals with writing to files as I don't need that.  I also went through my code and made sure I didn't allocate memory when I didn't need to.  I got it down to 1k over the limit.

Since I just need to read from a microsd I was wondering if there is a library that takes up a smaller footprint that will do that.
Title: Re: SD card read/write with Arduino
Post by: Jardim_lucas on Apr 03, 2010, 08:19 pm
I was not sucessfull in write/read SD Card using this schematics and library. Could someone give a help? I'm using an Kingston 1GB SD Card, and an Freeduino v1.0.  I had connected the SD Card like this picture, but I was not sucessful.

Title: Re: SD card read/write with Arduino
Post by: cadrogui on Apr 04, 2010, 12:43 am
someone might use it? (the circuit and the lib)

tnks
Title: Re: SD card read/write with Arduino
Post by: paddywwoof on Apr 13, 2010, 06:47 pm
Just to say thanks. I got a seeeduino a couple of days ago, tried using a card holder hacked from a broken camera and couldn't get the DevicePrintDemo to work (mmc::initialize() returned 3). All the connections tested ok with a multimeter on beep but I noticed a (2k) short on one of the connections. So I took the advice elsewhere in this or parallel thread and soldered wires directly to a micro-adapter, set the + to 3v3 and it just worked - no resistors needed!!

The adapter seemed to have pin 3 connected to pin 6 internally so that saved one of the connections.
Title: Re: SD card read/write with Arduino
Post by: alecjcook on Apr 21, 2010, 08:43 pm
Hi,
  as soon as I try and run this example I receive the following error:
My Documents\arduino-0018\libraries\SDcard\arduino sd card example.cpp:161: error: 'DEC' was not declared in this scope

This makes no sense to me as "DEC" seems to be used in the correct way throughout the example. Can anyone help?

Many thanks!

NOTE: I'm using Arduino_0018 and the "libraries" folder is not within the "hardware" folder, does this matter?
Title: Re: SD card read/write with Arduino
Post by: nandhakumar on May 04, 2010, 07:59 pm
Hi to all,

This is N.Nandhakumar again. After a lot of struggle I have purchased the EM-406a GPS module, Adafruit GPS shield V1.1, Freeduino ATMega328 for my project.
I soldered the GPS shield , interfaced it with the Arduino and the GPS logged data successfully into the SD card.
Now, I have a problem. I want to read back the logged data from the log file stored in SD card for doing some processing, comparison with the data. I made use of SdFat library's SdFatRead example code and I was able to read back the file contents .

Code: [Select]
/*
* This sketch reads and prints the file
* PRINT00.TXT created by SdFatPrint.pde or
* WRITE00.TXT created by SdFatWrite.pde
*/
#include <SdFat.h>
#include <SdFatUtil.h>

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))
void error_P(const char *str)
{
 PgmPrint("error: ");
 SerialPrintln_P(str);
 if (card.errorCode()) {
   PgmPrint("SD error: ");
   Serial.print(card.errorCode(), HEX);
   Serial.print(',');
   Serial.println(card.errorData(), HEX);
 }
 while(1);
}
void setup(void)
{
 Serial.begin(9600);
 Serial.println();
 Serial.println("type any character to start");
 while (!Serial.available());
 Serial.println();
 
 // initialize the SD card
 if (!card.init()) error("card.init");
 
 // initialize a FAT volume
 if (!volume.init(card)) error("volume.init");
 
 // open the root directory
 if (!root.openRoot(volume)) error("openRoot");
 
 // open a file
 if (file.open(root, "PRINT00.TXT", O_READ)) {
   Serial.println("Opened PRINT00.TXT");
 }
 else if (file.open(root, "WRITE00.TXT", O_READ)) {
   Serial.println("Opened WRITE00.TXT");    
 }
 else{
   error("file.open");
 }
 Serial.println();
 
 // copy file to serial port
 int16_t n;
 uint8_t buf[7];// nothing special about 7, just a lucky number.
 while ((n = file.read(buf, sizeof(buf))) > 0) {
   for (uint8_t i = 0; i < n; i++) Serial.print(buf[i]);
 }
 /* easier way
 int16_t c;
 while ((c = file.read()) > 0) Serial.print((char)c);
 */
 Serial.println("\nDone");
}

void loop(void) {}


The problem is that the file contents are read in raw format using uint8_t [ I googled about this datatype . But I am not clear with this datatype and how it works  :( ] . It will be more useful If I could read the data from the file in char or string format .

I searched for a better way to convert the uint8_t data to char datatype. But I get only junk characters.

I need the forum's help to solve this issue. Please give your suggestions on this.
Please help me out. Waiting for your valuable suggestions.

My works on the project at : http://walkingwithtux.wordpress.com/2010/05/02/tran-duino-under-progress/

Regards

N.Nandhakumar  :)
Title: Re: SD card read/write with Arduino
Post by: cemath on May 04, 2010, 08:33 pm
Hi,

Do you think you could post here what is the content of the file you are reading and what you are seeing in the serial window? I'm not sure if I can help you out, but I think that information would be helpful.

Good luck!


Title: Re: SD card read/write with Arduino
Post by: nandhakumar on May 05, 2010, 11:37 am
Hi cemath,

Thanks for the reply. THe code which I edited in the SdFatRead Example is

Code: [Select]
 int16_t n;
 char msg;
 uint8_t buf[7];// nothing special about 7, just a lucky number.
 while ((n = file.read(buf, sizeof(buf))) > 0)
 {
   for(uint8_t i=0;i < n;i++)
      msg = (char)buf[i];
      Serial.print(msg);
 }
 Serial.println("\nDone");


I am trying to read the file contents , convert them to char type from uint8_t type.

The file which I am trying to read from SD card is the GPSLOG00.TXT . the file contains GPS sentences logged into a text file from GPS.
The contents are

Code: [Select]

$GPRMC,112209.290,A,1307.3214,N,08013.3322,E,,,030510,,*0D
$GPRMC,112210.290,A,1307.3089,N,08013.3367,E,,,030510,,*02
$GPRMC,112211.290,A,1307.3299,N,08013.3306,E,,,030510,,*07
$GPRMC,112212.290,A,1307.3512,N,08013.3207,E,,,030510,,*00
$GPRMC,112213.290,A,1307.3630,N,08013.3141,E,,,030510,,*03
$GPRMC,112214.290,A,1307.3468,N,08013.3262,E,,,030510,,*09
$GPRMC,112215.290,A,1307.3531,N,08013.3234,E,,,030510,,*06
$GPRMC,112216.290,A,1307.3595,N,08013.3207,E,,,030510,,*0B
$GPRMC,112217.290,A,1307.3534,N,08013.3249,E,,,030510,,*0B
$GPRMC,112218.290,A,1307.3502,N,08013.3273,E,,,030510,,*08
$GPRMC,112219.290,A,1307.3489,N,08013.3282,E,,,030510,,*05
$GPRMC,112220.290,A,1307.3705,N,08013.3196,E,,,030510,,*0E
$GPRMC,112221.290,A,1307.3383,N,08013.3295,E,,,030510,,*05
$GPRMC,112222.290,A,1307.3405,N,08013.3251,E,,,030510,,*07
$GPRMC,112223.290,A,1307.3420,N,08013.3292,E,,,030510,,*0E
$GPRMC,112224.290,A,1307.3526,N,08013.3229,E,,,030510,,*0E
$GPRMC,112225.290,A,1307.3553,N,08013.3228,E,,,030510,,*0C
$GPRMC,112226.290,A,1307.3535,N,08013.3259,E,,,030510,,*09
$GPRMC,112227.290,A,1307.3417,N,08013.3269,E,1.42,312.24,030510,,*0B
$GPRMC,112228.000,A,1307.3425,N,08013.3270,E,0.33,308.80,030510,,*04
$GPRMC,112229.000,A,1307.3422,N,08013.3278,E,0.04,240.51,030510,,*0F
$GPRMC,112230.000,A,1307.3417,N,08013.3283,E,0.23,173.43,030510,,*00
$GPRMC,112231.000,A,1307.3416,N,08013.3285,E,0.34,164.87,030510,,*0E
$GPRMC,112232.000,A,1307.3413,N,08013.3285,E,0.53,166.36,030510,,*01
$GPRMC,112233.000,A,1307.3410,N,08013.3286,E,0.63,159.12,030510,,*09
$GPRMC,112234.000,A,1307.3406,N,08013.3288,E,0.72,157.94,030510,,*07
$GPRMC,112235.000,A,1307.3404,N,08013.3290,E,0.78,157.79,030510,,*04
$GPRMC,112236.000,A,1307.3400,N,08013.3295,E,1.01,158.20,030510,,*0A
$GPRMC,112237.000,A,1307.3394,N,08013.3298,E,0.58,151.13,030510,,*08
$GPRMC,112238.000,A,1307.3391,N,08013.3302,E,0.23,124.27,030510,,*09
$GPRMC,112239.000,A,1307.3392,N,08013.3305,E,0.23,144.30,030510,,*0C
$GPRMC,112240.000,A,1307.3393,N,08013.3306,E,0.19,0.60,030510,,*0D
$GPRMC,112241.000,A,1307.3391,N,08013.3308,E,0.55,344.99,030510,,*0D
$GPRMC,112242.000,A,1307.3393,N,08013.3309,E,0.65,346.12,030510,,*0F
$GPRMC,112243.000,A,1307.3391,N,08013.3311,E,0.58,327.75,030510,,*0D
$GPRMC,112244.000,A,1307.3392,N,08013.3312,E,0.31,315.15,030510,,*02
$GPRMC,112245.000,A,1307.3390,N,08013.3311,E,0.43,334.94,030510,,*0D
$GPRMC,112246.000,A,1307.3393,N,08013.3305,E,0.45,322.00,030510,,*04
$GPRMC,112247.000,A,1307.3396,N,08013.3301,E,0.76,330.60,030510,,*01
$GPRMC,112248.000,A,1307.3397,N,08013.3297,E,0.27,314.78,030510,,*0A
$GPRMC,112249.000,A,1307.3400,N,08013.3295,E,0.36,20.55,030510,,*3B
$GPRMC,112250.000,A,1307.3400,N,08013.3290,E,0.29,263.99,030510,,*0D
$GPRMC,112251.000,A,1307.3397,N,08013.3288,E,0.48,229.59,030510,,*09
$GPRMC,112252.000,A,1307.3398,N,08013.3284,E,0.41,316.03,030510,,*02
$GPRMC,112253.000,A,1307.3398,N,08013.3280,E,0.80,313.98,030510,,*0D
$GPRMC,112254.000,A,1307.3401,N,08013.3277,E,1.11,318.17,030510,,*00
$GPRMC,112255.000,A,1307.3403,N,08013.3274,E,1.02,322.50,030510,,*08
$GPRMC,112256.000,A,1307.3406,N,08013.3268,E,0.51,310.56,030510,,*03
$GPRMC,112257.000,A,1307.3405,N,08013.3265,E,0.20,172.19,030510,,*07
$GPRMC,112258.000,A,1307.3405,N,08013.3265,E,0.25,131.33,030510,,*02
$GPRMC,112259.000,A,1307.3405,N,08013.3263,E,0.50,286.05,030510,,*0D
$GPRMC,112300.000,A,1307.3405,N,08013.3263,E,0.43,318.18,030510,,*08
$GPRMC,112301.000,A,1307.3406,N,08013.3262,E,0.14,166.60,030510,,*0D
$GPRMC,112302.000,A,1307.3403,N,08013.3263,E,0.23,93.57,030510,,*31
$GPRMC,112303.000,A,1307.3400,N,08013.3267,E,0.58,150.75,030510,,*05
$GPRMC,112304.000,A,1307.3396,N,08013.3268,E,0.73,157.31,030510,,*0B
$GPRMC,112305.000,A,1307.3395,N,08013.3270,E,0.23,144.14,030510,,*00
$GPRMC,112306.000,A,1307.3395,N,08013.3272,E,0.21,139.18,030510,,*05
$GPRMC,112307.000,A,1307.3393,N,08013.3272,E,0.28,356.23,030510,,*08
$GPRMC,112308.000,A,1307.3391,N,08013.3272,E,0.12,3.89,030510,,*0F
$GPRMC,112309.000,A,1307.3390,N,08013.3273,E,0.15,342.02,030510,,*0C
$GPRMC,112310.000,A,1307.3388,N,08013.3272,E,0.03,14.17,030510,,*3F
$GPRMC,112311.000,A,1307.3388,N,08013.3272,E,0.51,352.24,030510,,*08
$GPRMC,112312.000,A,1307.3389,N,08013.3272,E,0.43,339.14,030510,,*07
$GPRMC,112313.000,A,1307.3389,N,08013.3272,E,0.11,290.20,030510,,*04
$GPRMC,112314.000,A,1307.3388,N,08013.3270,E,0.21,235.81,030510,,*07
$GPRMC,112315.000,A,1307.3388,N,08013.3270,E,0.17,241.13,030510,,*0B
$GPRMC,112316.000,A,1307.3386,N,08013.3272,E,0.18,122.90,030510,,*06
$GPRMC,112317.000,A,1307.3385,N,08013.3275,E,0.25,29.10,030510,,*3F
$GPRMC,112318.000,A,1307.3385,N,08013.3277,E,0.07,201.14,030510,,*0E
$GPRMC,112319.000,A,1307.3385,N,08013.3278,E,0.48,0.37,030510,,*09
$GPRMC,112320.000,A,1307.3385,N,08013.3281,E,0.40,346.95,030510,,*04
$GPRMC,112321.000,A,1307.3387,N,08013.3281,E,0.78,340.65,030510,,*05
$GPRMC,112322.000,A,1307.3388,N,08013.3282,E,0.23,328.18,030510,,*00
$GPRMC,112323.000,A,1307.3388,N,08013.3283,E,0.79,341.04,030510,,*0D
$GPRMC,112324.000,A,1307.3389,N,08013.3282,E,0.48,321.94,030510,,*07
$GPRMC,112325.000,A,1307.3390,N,08013.3280,E,0.11,297.44,030510,,*01
$GPRMC,112326.000,A,1307.3390,N,08013.3275,E,0.27,211.88,030510,,*03
$GPRMC,112327.000,A,1307.3389,N,08013.3270,E,0.43,291.88,030510,,*05
$GPRMC,112328.000,A,1307.3388,N,08013.3266,E,0.57,203.58,030510,,*0F
$GPRMC,112329.000,A,1307.3386,N,08013.3265,E,0.12,265.01,030510,,*0E
$GPRMC,112330.000,A,1307.3389,N,08013.3261,E,0.10,192.25,030510,,*02
$GPRMC,112331.000,A,1307.3391,N,08013.3259,E,0.37,338.75,030510,,*03
$GPRMC,112332.000,A,1307.3392,N,08013.3257,E,0.36,345.45,030510,,*05
$GPRMC,112333.000,A,1307.3392,N,08013.3256,E,0.19,286.73,030510,,*03
$GPRMC,112334.000,A,1307.3395,N,08013.3254,E,0.52,327.34,030510,,*07
$GPRMC,112335.000,A,1307.3395,N,08013.3253,E,0.21,248.92,030510,,*01
$GPRMC,112336.000,A,1307.3395,N,08013.3252,E,0.21,301.84,030510,,*08
$GPRMC,112337.000,A,1307.3395,N,08013.3252,E,0.09,264.22,030510,,*0D
$GPRMC,112338.000,A,1307.3396,N,08013.3252,E,0.16,346.95,030510,,*02
$GPRMC,112339.000,A,1307.3397,N,08013.3252,E,0.11,277.62,030510,,*0E
$GPRMC,112340.000,A,1307.3396,N,08013.3252,E,0.31,346.83,030510,,*0F
$GPRMC,112341.000,A,1307.3394,N,08013.3253,E,0.23,330.10,030510,,*05
$GPRMC,112342.000,A,1307.3394,N,08013.3254,E,0.20,327.85,030510,,*08
$GPRMC,112343.000,A,1307.3392,N,08013.3255,E,0.12,193.25,030510,,*08
$GPRMC,112344.000,A,1307.3391,N,08013.3256,E,0.29,347.05,030510,,*0E
$GPRMC,112345.000,A,1307.3389,N,08013.3257,E,0.40,340.46,030510,,*08
$GPRMC,112346.000,A,1307.3388,N,08013.3258,E,0.20,327.57,030510,,*02
$GPRMC,112347.000,A,1307.3388,N,08013.3258,E,0.35,339.64,030510,,*08
$GPRMC,112348.000,A,1307.3389,N,08013.3259,E,0.13,322.44,030510,,*0B
$GPRMC,112349.000,A,1307.3389,N,08013.3260,E,0.08,272.78,030510,,*01
$GPRMC,112350.000,A,1307.3388,N,08013.3260,E,0.12,204.95,030510,,*01
$GPRMC,112351.000,A,1307.3387,N,08013.3261,E,0.05,209.98,030510,,*08


When I uploaded the code , The serial monitor contents are,
Code: [Select]


Opened GPSLOG00.TXT



,.11023*R2,.,3,0$12391,00M1A302,,G190,3E53C4,4860,P207N.,1
,.19073*R2,.,3,0$12321,00M1A302,,G190,3E5EC1,3890,P207N.,1
,.12023*R2,.,3,0$12331,00M2A302,,G190,3E30,P207N.,03*R2,.,30000M3A302..50C1,488381
,.1105360$10301,,,,G100,3E10,P207N.,53*R2,.,31800M3A302..58C8,380221
,.1905300$10331,,3*R2,.,30400M4A303..5FC3,381571
,.1902150$10301,,,,G100,3E30,P207N.,33*R2,.,30400M4A302.51
,.1000990$10371,,,,G100,3E30,P207N.,13*R2,.,31800M5A302..58C6,486551
,.1005090$10351,,,,G100,3E20,P207N.,13*R3,.,30600M0A302.51
,.1007850$10361,,,,G100,3E10,P207N.,33*R3,.,30600M0A302.90$10301,,,,G100,3E13*R3,.,30200M1A302..57C3,387121
,.1800110$10381,,,,G100,3E10,P207N.,903M1A302..5EC9,3874,,G100,3E30,P207N.,43*R3,.,30800M2A302..5DC4,388491
,.1900140$10301,,,,G100,3E20,P207N.,03*R3,.,30500M3A302..52C1,385371
,.1907650$10321,,,,G100,3E30,P207N.,43*R3,.,30100M3A302..5DC8,385191
,.1902120$10361,,,,G100,3E30,P207N.,23*R3,.,30300M4A302..5EC5,385441
,.1808070$10381,,,,G100,3E30,P207N.,73*R3,.,30400M5A302..58C2,386241
,.1807940$10311,,0,P207N.,.5FC6,387180$10381,,3*R3,.,30.5FC9,388160$10371,,,,G100,3E10,P207N.,63*R4,.,30700M0A302..5BC5,389131
,.1603360$10311,,,,G100,3E10,P207N.,903M1A303..58C1,380401
,.1604860$10301,,0,P207N.,53*R4,.,30.52C6,380430$10331,,0,P207N.,73*R4,.,30.5FC0,380121
,.1601750$10311,,,,G100,3E10,P207N.,33*R4,.,30800M2A303.71
,.15093,,G100,3E10,

Done



The contents in the serial monitor are of different format [ I think its of HEX type]
and the full contents are also not fully converted and displayed in the serial monitor. Please help me out and tell me where I made wrong in the code. I also need to convert the full contents into char, since the log file is very huge.

Thanks in advance
N.Nandhakumar
Title: Re: SD card read/write with Arduino
Post by: cemath on May 07, 2010, 08:00 pm
Hi Nnk,

I found a pattern while comparing the data in your file and the data that is displayed in the monitor window. If you break the file data in blocks of 7 characters (the last caracter of a line, break line, counts as a caracter), and you keep only the last caracter of each block, then you can reconstruct what you are seeing in the monitor window. The problem must be in the example code you use to display the caracters, but I do not see it. I suspect that by reading a single byte at a time (using uint8_t buf[1] instead of uint8_t buf[7]) it should correct the problem, but that doesnt not explain it.

I suggest that you debug the code step by step by displaying the value of 'n' and other variables to verify that the program is doing what it should.

Also, I think that going throught the 'char' intermediate step is not necessary, because the formats 'uint8_t' and 'char' are very similar. I think uint8_t is equivalent to the format 'byte', which is 8 bits unsigned, and char is 8 bits signed. But since the caracters in ASCII are encoded on a range from 0 to 127, signed or unsigned bytes make no difference.

I hope that you find the solution to your problem quickly!

Good luck,

cemath
Title: Re: SD card read/write with Arduino
Post by: max88poon on May 19, 2010, 03:59 am
Hi guys

i am in a serious situation, i can't graduate if i don't get done with the datalogging...
so please, help , i very appreciate it
here is the case:
i am having a project that display a speed and record it
the former part is done, however, the later part is very difficult to me
i am trying to save the speed into the SDcard, don't need to read or copy, just write.
here is the code for the former part:
Code: [Select]
#define FREQ_PIN 3
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void setup() {
 pinMode(FREQ_PIN, INPUT);
lcd.begin(16, 2);
}

void loop()
{

unsigned long t1 = pulseIn(FREQ_PIN, HIGH);// Time how long it takes to go HIGH again
unsigned long t2 = pulseIn(FREQ_PIN, LOW); // and how long it takes to go low again.
double t = t1 + t2;
        double f = 1000000.0/t;
          double w = 2 * 3.14 * f;
          double v = w * 0.05;
      lcd.setCursor(0,0);
        lcd.println(v);
        delay(2000);
}    


Help please, I very very appreciate it.

i have the exactly the same circuit with this post, but i don't know how to write, thanks a lot

The code above is created by members, they are Pauls, Groove, AWOL and mem, i couldn't do this without their help, thanks a lot  :)
Title: Re: SD card read/write with Arduino
Post by: nandhakumar on Jun 01, 2010, 02:20 pm
Hi

Thanks for the reply Cemath. Really sorry the late post. I tried out as you said. But still I am not getting the expected output. I found that increasing or decreasing the buffer size [ default 7 ] as no effect on the output. The only change is that suppose if I set buffer[10], then while reading the data, I get a junk character or symbol after each tenth character. So, I googled again and seeked help from other forums too. Finally I found the sdfatlib library doing the GPS logging and SDcard read/write functionality. http://code.google.com/p/sdfatlib/.
I tried the examples provided by that library and it worked fine. I was able to read data in char datatype. But since, the GPS sentences logged by GPS are of varied length due to absence of some fields, I had problems in parsing the sentence from the file and extracting the latitude and longitude alone for further processing.
So, I tried the otherway around and modified the GPS logging code[ SdFatGPSLogger example from the sdfatlib library] to log only the latitude and longitude into the sdcard textfile. I worked fine. The log file has contents like below,
Code: [Select]
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1224,80.2223
13.1224,80.2223
13.1224,80.2223
13.1224,80.2223
13.1224,80.2223
13.1224,80.2223
13.1224,80.2223
13.1224,80.2222
13.1224,80.2222
13.1224,80.2222
13.1225,80.2222
13.1225,80.2222
13.1226,80.2222
13.1226,80.2222
13.1226,80.2222
13.1226,80.2222
13.1226,80.2222
13.1226,80.2222
13.1226,80.2221
13.1227,80.2221
13.1227,80.2221
13.1227,80.2220
13.1227,80.2220
13.1227,80.2219
13.1227,80.2219
13.1227,80.2218
13.1227,80.2218
13.1227,80.2217
13.1227,80.2217
13.1227,80.2216
13.1227,80.2216
13.1227,80.2215
13.1227,80.2215
13.1227,80.2214
13.1227,80.2214
13.1227,80.2214
13.1227,80.2213
13.1227,80.2213
13.1227,80.2213
13.1227,80.2213
13.1228,80.2213

Now, I stored this file in sdcard and tried to read it using the SdFatRead example. the example read the contents. Since, the file contents in each line are of same size, I used a fixed buffer size and used the comma delimiter to parse the data. I stored the latitude and longitude temporarily within the loop using two char arrays. I tried printing it as I read from the card. It worked.
Now, my problem is that , As I read the above data line by line from the card I need to compare it with another char array, so that If the arrays matches, I will send some data to print on the LCD display.
I used string functions. no use. Since the comparsion is between two char arrays, Inclusion of loops doesnot have data in it to compare. I really dont where is the mistake happening. I am stuck in this issue. I have posted the modified code here [ with no comparsion part] . Please help me out.
Code: [Select]
/*
* This sketch reads and prints the file
* PRINT00.TXT created by SdFatPrint.pde or
* WRITE00.TXT created by SdFatWrite.pde
*/
#include <stdio.h>
#include <SdFat.h>
#include <SdFatUtil.h>

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))
void error_P(const char *str)
{
 PgmPrint("error: ");
 SerialPrintln_P(str);
 if (card.errorCode()) {
   PgmPrint("SD error: ");
   Serial.print(card.errorCode(), HEX);
   Serial.print(',');
   Serial.println(card.errorData(), HEX);
 }
 while(1);
}
void setup(void)
{
 Serial.begin(4800);
 Serial.println();
 Serial.println("type any character to start");
 while (!Serial.available());
 Serial.println();
 
 // initialize the SD card
 if (!card.init()) error("card.init");
 
 // initialize a FAT volume
 if (!volume.init(card)) error("volume.init");
 
 // open the root directory
 if (!root.openRoot(volume)) error("openRoot");
 
 // open a file
 if (file.open(root, "GPSLOG00.TXT", O_READ)) {
   Serial.println("Opened GPSLOG00.TXT");
 }
 else if (file.open(root, "WRITE00.TXT", O_READ)) {
   Serial.println("Opened WRITE00.TXT");    
 }
 else{
   error("file.open");
 }
 Serial.println();
 
 // copy file to serial port
 int16_t n;
//  uint8_t buf[19];// nothing special about 7, just a lucky number.
 char buf[15];
 char lat[8],lon[8];
 char temp;
int linecount=494,count=0; // char *latitude="13.1224",*longitude="80.2222";
 char array1[linecount][8],array2[linecount][8];
while ((n = file.read((uint8_t *)buf, sizeof(buf))) > 0)
 {
   for(int i=0;i<n;i++)
   {
    if(buf[i]!=',')
     {
       lat[i]=buf[i];
       Serial.print(lat[i]); // This place is where comparsion will occur
     }
     else
     {
       i=i+1;
       lon[i]=buf[i]; // This place is where comparsion will occur
       Serial.print(lon[i]);
     }
   }
 }
 /* easier way
 int16_t c;
 while ((c = file.read()) > 0) Serial.print((char)c);
 */
Serial.println("\nDone");
}

void loop(void) {}


My doubt may be silly. But please help me out since I need to complete the project as part of my academics.
Thanks in advance
Regards
N.Nandhakumar
Title: Re: SD card read/write with Arduino
Post by: binooetomo on Jul 01, 2010, 12:21 pm
Dear All
I don't meant to hijack this thread, but I also got same problem with sdfatlib, and when I put sdfatlib as search keyword it refer to this thread.

So here we go.
I have a data file like this :
Code: [Select]

1474,254
1616,253
2998,254
3153,253
3925,254
4094,253
4642,254
4827,253
5255,254
5459,253
5810,254
6039,253
6336,254
6597,253
6851,254
7160,253
7379,254
7768,253
7957,254
8547,253
8705,254
10133,255
10293,254
10831,255
11031,254
11365,255
11617,254
11866,255
12210,254
12405,255
13096,254
13240,255
13600,256
13744,255
14413,256
14614,255
14931,256
15209,255
15431,256
15918,255
16077,256
16803,257
16963,256
17434,257
17664,256
17922,257
18298,256
18474,257
19442,258
19619,257
19981,258
20254,257
20468,258
21838,259
22057,258
22318,259
22746,258
22905,259
23336,260
23494,259
23917,260
24187,259
24395,260
25432,261
25643,260
25905,261
26455,260
26592,261
26613,262
26757,261
27244,262
27523,261
27721,262
28491,263
28690,262
28963,263
30133,264
30414,263
30605,264
31214,265
31406,264
31682,265
32712,266
32995,265
33180,266
33666,267
33852,266
34131,267
35051,268
35337,267
35517,268
35902,269
36082,268
36364,269
37199,270
37488,269
37662,270
37963,271
38138,270
38424,271
39185,272
39479,271
39648,272
39873,273
40042,272
40335,273
41035,274
41333,273
41497,274
41662,275
41826,274
42122,275
42768,276
43072,275
43231,276
43333,277
43491,276
43797,277
44401,278
44717,277
44870,278
44891,279
45039,278
45369,279
45949,280
46294,279
46436,280
46457,281
46621,280
46899,281
47374,282
47659,281
47817,282
47869,283
48025,282
48314,283
48764,284
49059,283
49211,284
49232,285
49389,284
49670,285
50078,286
50366,285
50518,286
50539,287
50699,286
50967,287
51327,288
51599,287
51754,288
51775,289
51932,288
52199,289
52528,290
52797,289
52951,290
52972,291
53133,290
53385,291
53673,292
53928,291
54086,292
54107,293
54268,292
54517,293
54773,294
55019,293
55179,294
55200,295
55361,294
55603,295
55835,296
56079,295
56238,296
56259,297
56427,296
56655,297
56844,298
57069,297
57236,298
57257,299
57418,298
57651,299
57837,300
58073,299
58231,300
58252,301
58427,300
58636,301
58760,302
58962,301
59140,302
59184,303
59356,302
59565,303
59682,304
59889,303
60061,304
60082,305
60251,304
60461,305
60567,306
60773,305
60943,306
60964,307
61139,306
61338,307
61406,308
61594,307
61777,308
61798,309
61965,308
62170,309
62247,310
62447,309
62617,310
62638,311
62827,310
63006,311
63027,312
63205,311
63392,312
63429,313
63616,312
63793,313
63814,314
64001,313
64177,314
64198,315
64391,314
64561,315
64582,316
64788,315
64947,316
64968,317
65219,316
65354,317
65375,318


and here is what I got from SdFatTail.pde
(http://i49.tinypic.com/21aa5bp.png)

Question :
How to put each "field" of the output into to different variable (ie: var1, var2) rather than printing it out.

here is the code (small edited from original sample)
Code: [Select]
/*
* This sketch reads and prints the tail of all files
* created by SdFatAppend.pde, SdFatPrint.pde, and
* SdFatWrite.pde.
*/
#include <SdFat.h>
#include <SdFatUtil.h>

Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))
void error_P(const char *str)
{
 PgmPrint("error: ");
 SerialPrintln_P(str);
 if (card.errorCode()) {
   PgmPrint("SD error: ");
   Serial.print(card.errorCode(), HEX);
   Serial.print(',');
   Serial.println(card.errorData(), HEX);
 }
 while(1);
}

void setup(void)
{
 Serial.begin(9600);
 Serial.println();
 Serial.println("type any character to start");
 while (!Serial.available());
 Serial.println();
 
 // initialize the SD card
 if (!card.init()) error("card.init");
 
 // initialize a FAT volume
 if (!volume.init(card)) error("volume.init");
 
 // open the root directory
 if (!root.openRoot(volume)) error("openRoot");
}

/*
* Print tail of all SdFat example files
*/
void loop(void)
{
 dir_t dir;
 char name[13];
 
 // read next directory entry
 if (root.readDir(dir) != sizeof(dir)) {
   Serial.println("End of Directory");
   while(1);
 }
 
 // check for file name "APPEND.TXT", "PRINT*.TXT"
 // or "WRITE*.TXT"
 // first 8 bytes are blank filled name
 // last three bytes are blank filled extension
 if ((strncmp((char *)dir.name, "MYSTEP", 6)) ||
     strncmp((char *)&dir.name[8], "TXT", 3)) {
       return;
 }
 // format file name
 SdFile::dirName(dir, name);
 
 // remember position in root dir
 uint32_t pos = root.curPosition();
 
 // open file
 if (!file.open(root, name, O_READ)) error("file.open");
 
 // restore root position
 if (!root.seekSet(pos)) error("root.seekSet");
 
 // print file name message
 Serial.print("Tail of: ");
 Serial.println(name);
 
 // position to tail of file
 //if (file.fileSize() > 100) {
 //  if (!file.seekSet(file.fileSize() - 100)) error("file.seekSet");
 //}
 int16_t c;
 // find end of line  
 //while ((c = file.read()) > 0 && c != '\n');
 
 // print rest of file
 while ((c = file.read()) > 0)
 {
   Serial.print((char)c);
 }
 file.close();
 Serial.println();
}


Sincerely
-bino-
Title: Re: SD card read/write with Arduino
Post by: 16951 on Jul 27, 2010, 05:53 pm
Does it work with a micro-SD ? I been trying use it but it didnt work out  :(
Title: Re: SD card read/write with Arduino
Post by: ookamijin on Aug 09, 2010, 05:10 am
I'm having the same problem as alecjcook.  when i put the #includes in an otherwise skeleton sketch i get:

C:\Program Files\arduino-0018\libraries\SDcard\arduino sd card example.cpp:161: error: 'DEC' was not declared in this scope

along with 'HEX' not declared, 'Serial' not declared, 'delay' not declared ...

does the cpp file need some tweaking maybe?
Title: Re: SD card read/write with Arduino
Post by: riscking on Oct 08, 2010, 12:46 am
Hi, delete #include <FatStructs.h> and the problems disappear.

I have other problem how i can change the pins 10-13 to 5-8?I modified Sd2PinMap but not working.

Thanks
Title: Re: SD card read/write with Arduino
Post by: Lennyh on Nov 08, 2010, 07:24 pm
Hi everyone,
I'm sorry to re-ressurect this, but this library seems to be the best (of the thousand SD Libraries) to fit my needs...

I've got the same problem as  post number 136 in page 10 (I would post the link, but I'm not allowed).

Seems like it is not compiling in Arduino 19. I tried out the soluton proposed in the next post, but it didn't help :(

EDIT: Ok, it's because it doesn't work on ATmega328...
Title: Re: SD card read/write with Arduino
Post by: WilliamK Govinda on Nov 18, 2010, 07:02 pm
Guys, how do I get this working with the Arduino Mega (Atmega1280) Thanks.
Title: Sometimes do not write
Post by: madepablo on Dec 04, 2010, 01:42 am
H there,

First of all, thanls so much for this great tutorial. Some weeks ago i developed my own SD Card shield and it runs perfectly.

However, now i have a problem: sometimes it does not write data into the SD.

Let me explain. I made a datalogger based on a RTC ds1337 and a SD card wired such as showed in this topic. No apparenty it is not the problem.
I have the arduino sleeping most of the time, and ones per hour the rtc get up the arduino and measure by different senors, and save the data into a SD.

From time to time i remove the SD card from its slot and check the new data. I observed that when i do it (remove and put the SD card into the slot again, it does not save the data). BUT if i remove the slot, but if i remove the power to arduino just immediately after to put the SD card into the slot, OR push the reset button (at the end it is the same)... the next data are saved. :-/

So, i am a little bit lost in this situation. It is not a big problem, because to remove the power and connecting it again is enough, or pushing the reset button but it is not ideal for my project..., right?

I use the filelogger library.

The code is prettly long, so i put here just only the essential lines..

Code: [Select]
#include <FileLogger.h>                      // Librería para almacenamiento de dtos en microSD
#include <DallasTemperature.h>               // Librería para el sensor de temperatura DS18B20
#include <OneWire.h>
#include <Wire.h>
#include <DS1337.h>                          // Librería para el RTC DS1307
#include <Sensirion.h>                       // Librería para el sensor de temperatura y humedad SH15
#include <avr/power.h>
#include <avr/sleep.h>                       // Librería para modo dormir del microcontrolado

// Definición de los pin analógicos
#define luz 0                                // Luminosidad LDR
#define suelo 1                              // Humedad del suelo
#define lluvia 2                             // Intensidad de la lluvia
#define bateria 3                            // Voltaje de entrada

// Definición de los pin digitales
#define alarma 2                             // Alarmas del RTC DS1337
#define viento 3                             // Anemómetro QRD1114
#define tempsuelo 4                          // Temperatura del suelo DS18B20
#define temphumdat 5                         // Temperatura/humedad/Punto de rocío SH15
#define temphumcl 6                          // Temperatura-humedad SH15
#define vida 7                               // Led de vida
#define power 8                              // Alimentación de los sensores
#define temp 9                               // Temperatura al sol DS18B20

// Activación de librerías
DS1337 RTC = DS1337();                       // Configuración librería RTC DS1337
OneWire oneWire(temp);                       // Configuración librería termómetro DS18B20
DallasTemperature sensors(&oneWire);
OneWire oneWire2(tempsuelo);                 // Configuración librería termómetro DS18B20
DallasTemperature sensors2(&oneWire2);
DeviceAddress tempDeviceAddress;             // Define la dirección de cada sensor de temperatura
Sensirion SH15 = Sensirion(temphumdat, temphumcl);          

// Definición de constantes
const float pi = 3.14159265;                 // Numero PI
const float volt = 0.0108480556;             // Resolución voltaje de entrada
const int periodo2 = 10000;                  // Periodo de medida del anemómetro (ms)
const int radio = 65;                        // Radio de anemómetro (mm)
const int temp_precision = 12;               // Resolución de los sensores de temperarura (bits)
const int sensibilidad = 30;                 // Sensibilidad del disdrometro
const float area=0.001654;                   // Area de medida del sensor disdrómetro (m^2)

// Definición de variables
long contador = 1;                           // Contador de datos almacenados
unsigned int year = 0000;                    // Año
int month = 00;                              // Mes
int day = 00;                                // Día
int hora = 00;                               // Hora
int minuto = 00;                             // Minuto
int segundo = 00;                            // Segundos
float batt = 0;                              // Voltage de entrada
float innerVcc;                              // Voltaje interno
float innertemp;                             // Temperarura interna
float ambtemp = 0;                           // Temperatura ambiental SH15 (ºC)
float humedad = 0;                           // Humedad ambiental SH15 (%)
float TRocio = 0;                            // Punto de rocio (ºC)
unsigned long BWCounter = 0;                 // Pulsos Blanco/Negro del anemómetro
float velviento = 0;                         // Velocidad del viento (m/s)
long lux = 0;                                // Luminosidad (LUX)
float tempext = 0;                           // Temperatura (ºC)
float suelohum = 0;                          // Humedad del suelo (%)
float TSAr = 0;                              // Temperatura del suelo arriba (ºC)
float TSAb = 0;                              // Temperatura del suelo abajo (ºC)
unsigned long intensidad = 0;                // Intensidad de lluvia (gotas/horas/m2)


void setup(){
 // Inicializacion RTC
 RTC.start();
 // Configuración de la alarma
 RTC.enable_interrupt();
 RTC.setSeconds(55);
 RTC.setMinutes(59);
 RTC.setAlarmRepeat(EVERY_HOUR);
 RTC.writeAlarm();
 pinMode(alarma, INPUT);                   // Receptor de alarmas
 digitalWrite(alarma, HIGH);
 // Configuración de pins
 pinMode(power, OUTPUT);                    // Alimentacion de sensores
 pinMode(vida, OUTPUT);                     // Led de vida
 // Inicializacion del puerto serie
 Serial.begin(9600);                        // Inicia comunicaciones
 // Inicialización de sensores
 sensors.begin();                           // Inicia el sensor de temperatura DS18B20
 sensors2.begin();
 // Mostrar cabecera por puerto serie (*)
 SplashScreen();
}

void loop(){
 digitalWrite(power, HIGH);
 delay(5000);
 digitalWrite(vida, HIGH);                // Enciende el led mientras realiza las lecturas
 tiempo();                                // Toma la hora
 delay(20);
 readVcc();                               // Lee el voltaje interior
 delay(20);
 midebateria();                           // Mide el voltaje de entrada
 delay(20);
 readTemp();                              // Mide la temperatura interna
 delay(20);
 midegotas();                             // Mide la intensidad de lluvia (disdrómetro)
 delay(20);
 temperatura();                           // Mide la temperatura exterior (DS18B20)
 delay(20);
 sueloH();                                // Mide la humedad del suelo
 delay(20);
 suelotemp();                             // Mide la temperatura del suelo
 delay (20);
 temphumroc();                            // Lee temperatura y humedad (SH15) y calcula el punto de rocío
 delay (20);
 luminosidad();                           // Mide la luminosidad (LDR)
 delay  (20);
 velocidadviento();                       // Mide la velocidad del viento (QRD1114)
 mostrar();                             // Muestra los datos a través del puerto serial
 grabar();                              // Graba los datos en formato ascii en un soporte microSD
 delay(5000);
 contador = contador + 1;                 // Actualiza el contador de medidas
 digitalWrite(vida, LOW);                 // Apaga el led al acabar el proceso
 digitalWrite(power, LOW);
 //attachInterrupt(0, Despertar, FALLING);
 delay(500);
 Dormir();
}


void Despertar(){
}

void Dormir(){
 attachInterrupt(0, Despertar, FALLING);
 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 sleep_enable();
 RTC.enable_interrupt();
 sleep_mode();
 // -->FASE DE BAJO CONSUMO DEL DISPOSITIVO<--
 sleep_disable();
 RTC.disable_interrupt();
 detachInterrupt(0);
}

// Lee el Reloj de Tiempo Real (DS1337)
void tiempo(){
 // Lee el RTC
 RTC.readTime();
 // Memoriza la fecha actual
 day = RTC.getDays();
 month = RTC.getMonths();
 year = RTC.getYears();
 //Memoriza la hora actual
 hora = RTC.getHours();
 minuto = RTC.getMinutes();
 segundo = RTC.getSeconds();
 return;
}

// Lee el voltaje de entrada
float midebateria(){
 batt = (analogRead(bateria))*volt;
 return batt;
}



Code follows with other functions to measure the different sensors. I think that they are not essential here...

[Sorry, comments are in Spanish]

So,any idea about what could be the idea and how could i solve it by software or hardware?

Thanks!!
Title: Re: SD card read/write with Arduino
Post by: Onions on Dec 04, 2010, 03:46 pm
I've been meaning to intergrate an SD card inot one of my projects a while
ago, only I had no idea how to. Now, all I need is to find somewhere that
sells the SD card holder. I do not have anything to dismantle so I would
have to buy one.
Title: Re: SD card read/write with Arduino
Post by: WilliamK Govinda on Dec 04, 2010, 09:11 pm
Here's the one I used:

http://www.sparkfun.com/products/10117

(http://static.sparkfun.com//images/products/10117-01_l_th.jpg)

This one is better, but more expensive:

http://www.sparkfun.com/products/204
Title: Re: SD card read/write with Arduino
Post by: WilliamK Govinda on Dec 04, 2010, 09:13 pm
And here's the sketch I used to test my SD card with direct write/reading. (no FAT) Its VERY fast to handle the SD card, as I needed speed, and not FAT16 or anything like that.

Code: [Select]
/*

 Basic instructions for recording data in an SD Card in native mode
 The SD card (3.3 V) must be properly interfaced to Arduino (5 V)
 Didier Longueville invenit et fecit February 2010
 
 
 Serial 115200
 
*/

// Ports for Arduino Mega //
int PIN_CS = PINB0;      // chip select
int PIN_MOSI = PINB2;    // master out slave in
int PIN_MISO = PINB3;    // master in slave out
int PIN_CLOCK = PINB1;   // clock

int blockPosition = 30;

/********************** SPI SECTION BELOW **********************/

// SPI Variables
byte clr;     // dummy variable used to clear some of the SPI registers
byte spi_err; // SPI timeout flag, must be cleared manually

// send an SPI command, includes time out management
// returns spi_err: "0" is "no error"
byte spi_cmd(volatile char data)
{
 spi_err = 0; // reset spi error
 SPDR = data; // start the transmission by loading the output byte into the spi data register
 int i = 0;
 while (!(SPSR & (1<<SPIF)))
 {
   i++;
   if (i >= 0xFF)
   {
     spi_err = 1;
     return(0x00);
   }
 }
 // returned value
 return(SPDR);
}

// initialize SPI port
void spi_initialize(void)
{
 SPCR = (1<<SPE) | (1<<MSTR); // spi enabled, master mode
 clr = SPSR; // dummy read registers to clear previous results
 clr = SPDR;
}

/********************** SD CARD SECTION BELOW **********************/

// SD Card variables
#define blockSize 512          // block size (default 512 bytes)
byte vBlock[blockSize];        // set vector containing data that will be recorded on SD Card
byte vBuffer[16];

#define GO_IDLE_STATE 0x00     // resets the SD card
#define SEND_CSD 0x09          // sends card-specific data
#define SEND_CID 0x0A          // sends card identification
#define READ_SINGLE_BLOCK 0x11 // reads a block at byte address
#define WRITE_BLOCK 0x18       // writes a block at byte address
#define SEND_OP_COND 0x29      // starts card initialization
#define APP_CMD 0x37           // prefix for application command

// Send a SD command, num is the actual index, NOT OR'ed with 0x40.
// arg is all four bytes of the argument
byte sdc_cmd(byte commandIndex, long arg)
{
 PORTB &= ~(1<<PIN_CS);   // assert chip select for the card
 spi_cmd(0xFF);           // dummy byte
 commandIndex |= 0x40;    // command token OR'ed with 0x40
 spi_cmd(commandIndex);   // send command
 for (int i=3; i>=0; i--)
 {
   spi_cmd(arg>>(i*8));   // send argument in little endian form (MSB first)
 }
 spi_cmd(0x95);           // checksum valid for GO_IDLE_STATE, not needed thereafter, so we can hardcode this value
 spi_cmd(0xFF);           // dummy byte gives card time to process
 byte res = spi_cmd(0xFF);
 return (res);  // query return value from card
}

// initialize SD card
// retuns 1 if successful
byte sdc_initialize(void)
{
 // set slow clock: 1/128 base frequency (125Khz in this case)
 SPCR |=  (1<<SPR1) | (1<<SPR0); // set slow clock: 1/128 base frequency (125Khz in this case)
 SPSR &= ~(1<<SPI2X);            // No doubled clock frequency
 // wake up SD card
 PORTB |=  (1<<PIN_CS);          // deasserts card for warmup
 PORTB |=  (1<<PIN_MOSI);        // set MOSI high
 for(byte i=0; i<10; i++)
 {
   spi_cmd(0xFF);                // send 10 times 8 pulses for a warmup (74 minimum)
 }
 // set idle mode
 byte retries=0;
 PORTB &= ~(1<<PIN_CS);          // assert chip select for the card
 while(sdc_cmd(GO_IDLE_STATE, 0) != 0x01)
 {
   // while SD card is not in iddle state
   retries++;
   if (retries >= 0xFF)
   {
     return(NULL); // timed out!
   }
 }
 // at this stage, the card is in idle mode and ready for start up
 retries = 0;
 sdc_cmd(APP_CMD, 0); // startup sequence for SD cards 55/41
 while (sdc_cmd(SEND_OP_COND, 0) != 0x00)
 {
   retries++;
   if (retries >= 0xFF)
   {
     return(NULL); // timed out!
   }
   sdc_cmd(APP_CMD, 0);
 }
 // set fast clock, 1/4 CPU clock frequency (4Mhz in this case)
 SPCR &= ~((1<<SPR1) | (1<<SPR0)); // Clock Frequency: f_OSC / 4
 SPSR |=  (1<<SPI2X);              // Doubled Clock Frequency: f_OSC / 2
 return (0x01); // returned value (success)
}

// clear block content
void sdc_clearVector(void)
{
 for (int i=0; i<blockSize; i++)
 {
   vBlock[i] = 0;
 }
}

// get nbr of blocks on SD memory card from
long sdc_totalNbrBlocks(void)
{
 sdc_readRegister(SEND_CSD);
 // compute size
 long C_Size = ((vBuffer[0x08] & 0xC0) >> 6) | ((vBuffer[0x07] & 0xFF) << 2) | ((vBuffer[0x06] & 0x03) << 10);
 long C_Mult = ((vBuffer[0x08] & 0x80) >> 7) | ((vBuffer[0x08] & 0x03) << 2);
 return ((C_Size+1) << (C_Mult+2));
}

// read SD card register content and store it in vBuffer
void sdc_readRegister(byte sentCommand)
{
 byte res=sdc_cmd(sentCommand, 0);
 while(res != 0x00) res=spi_cmd(0xFF); // retry

 // wait for data token
 while (spi_cmd(0xFF) != 0xFE);
 // read data
 for (int i=0; i<16; i++)
 {
   vBuffer[i] = spi_cmd(0xFF);
 }
 // read CRC (lost results in blue sky)
 spi_cmd(0xFF); // LSB
 spi_cmd(0xFF); // MSB
}

// write block on SD card
// addr is the address in bytes (multiples of block size)
void sdc_writeBlock(long blockIndex)
{  
 while(sdc_cmd(WRITE_BLOCK, blockIndex * blockSize) != 0x00) { }
 spi_cmd(0xFF); // dummy byte (at least one)
 // send data packet (includes data token, data block and CRC)
 // data token
 spi_cmd(0xFE);
 // copy block data
 for (int i=0; i<blockSize; i++)
 {
   spi_cmd(vBlock[i]);
 }
 // write CRC (lost results in blue sky)
 spi_cmd(0xFF); // LSB
 spi_cmd(0xFF); // MSB
 // wait until write is finished
 while (spi_cmd(0xFF) != 0xFF); // kind of NOP
}

// read block on SD card and copy data in block vector
// retuns 1 if successful
void sdc_readBlock(long blockIndex)
{
 byte res = sdc_cmd(READ_SINGLE_BLOCK,  (blockIndex * blockSize));
 while(res != 0x00) res=spi_cmd(0xFF); // retry
 // read data packet (includes data token, data block and CRC)
 // read data token
 while (spi_cmd(0xFF) != 0xFE);
 // read data block
 for (int i=0; i<blockSize; i++)
 {
   vBlock[i] = spi_cmd(0xFF); // read data
 }
 // read CRC (lost results in blue sky)
 spi_cmd(0xFF); // LSB
 spi_cmd(0xFF); // MSB
}

/********************** MAIN ROUTINES SECTION  BELOW **********************/

void setup()
{
 // Set ports
 // Data in
 DDRB &= ~(1<<PIN_MISO);
 // Data out
 DDRB |=  (1<<PIN_CLOCK);
 DDRB |=  (1<<PIN_CS);
 DDRB |=  (1<<PIN_MOSI);  
 // Initialize serial communication
 Serial.begin(115200);
 // Initialize SPI and SDC
 spi_err=0;        // reset SPI error
 spi_initialize(); // initialize SPI port
 sdc_initialize(); // Initialize SD Card
 Serial.print(sdc_totalNbrBlocks(), DEC);
 Serial.println(" blocks");
 Serial.print("Block Size: ");
 Serial.println(blockSize);
}  

void loop()
{
 unsigned long tx1 = 0;
 unsigned long tx2 = 0;
 
 if (true) // WRITE //
 {
   vBlock[0] = blockPosition;
   vBlock[1] = blockPosition+1;
   vBlock[2] = blockPosition+2;
   tx1 = micros();
   sdc_writeBlock(blockPosition);
   tx2 = micros();
 
   Serial.print("Time to write: ");
   Serial.println(tx2-tx1);
   
   delay(25);
 }
 
 vBlock[0] = 0;
 vBlock[1] = 0;
 vBlock[2] = 0;
 
 tx1 = micros();
 sdc_readBlock(blockPosition);
 tx2 = micros();

 Serial.print("Time to read: ");
 Serial.println(tx2-tx1);
 Serial.print("Values: ");
 Serial.print(vBlock[0]);
 Serial.print(" ");
 Serial.print(vBlock[1]);
 Serial.print(" ");
 Serial.println(vBlock[2]);
 
 delay(400);  
 
 blockPosition++;
}
Title: Re: SD card read/write with Arduino
Post by: Popsworld on Dec 14, 2010, 03:15 pm
Sorry newbie hear with a dump question again, can I use this file system with my 328 that's within my Arduino for midi file playing.

I not interested in recording any files just playing files that's on a fat 16 or fat 32 SD card.  
Title: Re: SD card read/write with Arduino
Post by: WilliamK Govinda on Dec 14, 2010, 04:11 pm
Sorry, you will need uFat or something that reads Fat16 files in a SD Card.

Take a look at this:
http://blushingboy.net/p/SDuFAT/

Wk
Title: Re: SD card read/write with Arduino
Post by: Popsworld on Dec 18, 2010, 10:39 am
Yes I understand that i will need more hardware, I've done all that now thanks: I was referring to software handling if it would handle it. So your post means it will thanks for that.
Got the software sorted now found what I needed on the net for my MIDI project, it's up and running but I need help with some parts of the programming still, editing mainly. I will be posting my project on this forum soon just need to find a suitable forum/place/thread.  
Title: Re: SD card read/write with Arduino
Post by: Syntetik on Dec 19, 2010, 08:00 pm
Hello!
Can I use the same voltage divider (1,8 K & 3,3 K resistors) to power SD card, when not using Arduino, but only Atmega chip on breadboard? Or maybe I must put there 3v3 zener diode at the SD side?
Title: Re: SD card read/write with Arduino
Post by: ryanteck on Jan 01, 2011, 10:31 am
How do i use this? all of the libarys dont seem to want to work with the original schematics. i have this board all done and made and wired up as the diagram is :)
Title: Re: SD card read/write with Arduino
Post by: Divyanshu on Jan 02, 2011, 07:27 am
This one seems cool, although my bad soldering skills will mess up everything :(

Title: Re: SD card read/write with Arduino
Post by: bretthall on Jan 10, 2011, 09:28 pm
I'm excited at the prospect of doing some datalogging with the arduino for my temperature control experiment which is already working, but the wiring/breadboarding to get the hardware solution in this forum going is a little daunting. I'd prefer to spend a few bucks and get something already built, and fool around with the software instead.

I saw the ethernet shield with sd reader, but it's kind of expensive at $45. The sparkfun $15 shield for sd cards had quite a variety of bad reviews.

Does anyone in this forum have suggestions for a reasonably inexpensive, but not particularly hardware challenging way to get SD cards (or microsd, or whatever) working?
Title: Re: SD card read/write with Arduino
Post by: SirPoonga on Jan 10, 2011, 09:56 pm
I am using the Gravitech microsd card in my project.

http://store.gravitech.us/adapterboards.html
http://www.youtube.com/watch?v=G2mqnwSYwIg
Title: Re: SD card read/write with Arduino
Post by: akumar5 on Jan 20, 2011, 10:10 pm
Hello everyone,

I'm new to the forum so I'd like to first say hi to everyone.

I recently began experimenting with wiring to the SD card on a breadboard and I had a thought. Why not connect the ground pins on the SD card to a 1.7v supply and use the 5V line for VCC? This way the card will see a 3.3V supply and see 3.3 level signals from the arduino.

I tried this and it seemed to work out fine. When I initially used the voltage dividers (since I didn't have the buffer IC), I started to get bad data after a certain speed because of the resistor delay. This was eliminated when I used the 1.7v supply. I am able to write 6 channels of analog data at 200 Hz. I haven't tried anything faster yet.

My question is does anyone think this is damaging the SD card? I've already ordered the buffer ICs but if this method works fine over a long time then I won't use them.

Thanks
Title: Re: SD card read/write with Arduino
Post by: slayer-marios on Jan 23, 2011, 01:50 am
Hello everyone! I have an arduino mega(atmega2560)+ ethernet shield+sd card http://www.arduino.cc/en/Main/ArduinoEthernetShield

To make the lib sd_raw work on my mega i added the following lines
in sd_raw_config.h where is checking for platform definitions.

Code: [Select]
#elif defined(__AVR_ATmega2560__)
     #define configure_pin_mosi() DDRB |= (1 << DDB2)
   #define configure_pin_sck() DDRB |= (1 << DDB1)
   #define configure_pin_ss() DDRB |= (1 << DDB0 )
   #define configure_pin_miso() DDRB &= ~(1 << DDB3)

   #define select_card() PORTB &= ~(1 << PB0)
   #define unselect_card() PORTB |= (1 << PB0)


without this i get error
Code: [Select]

   #error "no sd/mmc pin mapping available!"


i hope that help arduino atmega2560 users