Reading SD card with Arduino Duemilanove

Hi Guys,

I am trying to write a comma delimited file to an SD card FAT16 formatted and read the file (about 3k) into variables to be displayed on a GLCD and also transmitted to another Arduino via Xbee.

I have loaded SDuFAT and can write to the file and have it sent to the serial port but dont know how to capture the info to variables. The first line of the files is:-

IM, 228, P, 123, GGGM, 34

or similar. I want to assign each bit of info between the commas to a variable. Anyone out there that can help a dumbo like me? Cheers

The first line of the files is:-

IM, 228, P, 123, GGGM, 34

There are several possible things you need help with. They include reading from the SD card in general, storing the received bytes in an array of chars, NULL terminating that array so it can be processed as a string, or parsing the tokens from the NULL terminated array of chars.

Knowing which step is causing you problems would go a long way towards providing you a nudge in the right direction.

If it's just the last step, which seems most likely given that you are able to write to the SD card, then you need to look at the strtok function. It extracts tokens from the input string, up to one of several delimiters.

In your case, the delimiters include , and NULL (the end of the string).

To get the first token, pass a pointer to the string to strtok. To get the rest of the tokens , pass NULL to strtok. This is necessary for two reasons. First is because strtok stores some data about the string to be tokenized (a pointer to the last delimiter found). Second, because strtok modifies the input argument (that means you should pass it a copy of the string, not the string, if you still need the string for other purposes).

If you need something else, please try to be more explicit in your request.

Thanks for the prompt reply PaulS,

My problem is reading the string back from the SD card. I write the file with my PC to store data from an excel spreadsheet to the SD card in comma delimited form, no probs. Then, using SDuFAT, I can dump the file to serial by sending “R” and read the information but I need to capture it to store in variables.

The eventual project will have two buttons that scroll through the lines of the comma delimited file and display the values in that line on a GLCD, while also transmitting a couple of the values via xbee to another arduino with GLCD.

IM ,P,228,42,29,MH GL,MH GL 39,3

This is an actual line from the file. I need to transmit the number 42 and the string “MH GL 39” to the other arduino in this case, while displaying all the strings and numbers from the line on the GLCD in different formats. I can do all I need if the strings are already stored in an array but cant figure out how to read part of, or even the whole string from the SD card.

Any help would be greatly appreciated. I hope you can understand what I am trying to do! I’m new to Arduino, obviously, and in the past have only programmed in Visual basic and used Picaxe controllers, so am blundering along!

Then, using SDuFAT, I can dump the file to serial by sending "R" and read the information but I need to capture it to store in variables.

Why don't you show your code for doing this. Then, we could show you how to store the data in a character array, as a string, if you are not already doing so.

Parsing it, then, is pretty simple.

The code I am using is the SD_uFAT_basic sketch from this link.

http://blushingboy.net/p/SDuFAT/page/SDuFAT-basic/

I dont need any of the features available with this code such as list, delete, write, etc as all input to the file is done on PC. I just cant find any code to address the SD card to extract the info. All this software does is print the whole file to the serial port. I have tried other libraries, such as FAT16 but I am using a resistor voltage divider and this wont work reliably.

I have found in the file SDuFAT.cpp the following line

Serial.print(buffer*,BYTE);* that sends the data to the serial port and have added an array and the line gw[ii]=buffer*;* where gw is my array. I have then serial printed the variable gw to see the data is what I want but cant read this array back in my original sketch. I am probably missing something fundamental but I'm trying to do this the hard way, with no prior knowledge of C. Still, its fun learning!

I am probably missing something fundamental but I'm trying to do this the hard way, with no prior knowledge of C.

That's how everybody learns C.

The link is to a page that describes the library. I want to see [u]your[/u] code. It would be much easier to tell you how to modify your code to achieve some result than to tell you how to add a bunch of code that you may or may not need.

I have found in the file SDuFAT.cpp the following line

Serial.print(buffer*,BYTE);* that sends the data to the serial port and have added an array and the line gw[ii]=buffer*;[/quote]* The Serial.print line is sending one value from buffer to the serial port as a byte. You are making a copy of that character. That's good. > I have then serial printed the variable gw to see the data is what I want but cant read this array back in my original sketch./quote] > > Does it print correctly? What do you mean by reading it back in? Where did you write it out to, and how are you trying to read it back in? > > If it prints correctly, then that array is the one that you want to parse, using strtok.

OK. I really dont have any code relevant to what I am trying to do. All my code to date is related to displaying the variables on the GLCD and transmitting via xbee and are associated snippets from here and there.

What I have is this: I run the SDuFAT_basic demo which gives me an option of listing, deleting, writing, etc. By sending “R” through the serial port, this causes SDuFAT.cpp to respond as mentioned before by sending the data back to the serial port. This all works fine as intended and the only variation to the original code is that I set pin2 high to power up the SD card.

pinMode(2, OUTPUT); // Set pin 2 to control SD relay as output
digitalWrite(2, HIGH); // Relay on means read SD

I have also changed the file name from hola to digsheet. No rocket science so far.

In the SDuFAT.cpp program that is called, I have created an array called gw.

int gw[5000];
int ii =0;

Also, an integer ii for incrementing through the array.

Next, after the line

Serial.print(buffer*,BYTE);*
I have added
ii++; //increment the array by 1
gw[ii]=buffer*; //write the buffer into gw array*
Serial.print(gw[ii],BYTE); //print to serial port to see if it is right
All good up to here. It prints the file out to serial port twice, ie:-
IIMM ,PP ,222288 , …etc
which shows me the variables are being stored in the array as I require.
Once the file has been sent to the serial port, control goes back to the SDuFAT_basic sketch and I have tried to read the variables from there. eg:-
Serial.print(gw[1],BYTE);
which I would suspect would return “I” but I cant compile the sketch with the error “gw” not declared in this scope.
I then declare the array
int gw[5000];
and the sketch compiles but the array is empty.

I looked at the SDuFAT.cpp and SDuFAT.h files. They do not seem to have a way to read the card, one record at a time.

This may be because the library has no concept of what forms a record. As far as it's concerned, the file is simply an array of bytes.

It doesn't look like it would be that hard to add a method to the class that would return a string composed of all the bytes from some position in the file until some specific value was located (a carriage return, for instance).

A method to copy all of a file into memory would be even easier, but it is not likely that you have enough memory to do this.

Its going to be real hard to explain without some C knowledge. I suggest this text "Practical C Programming": http://oreilly.com/catalog/9781565923065 (Ch13)

You need to parse your strings, it will require you implement the 'line' read as mentioned above. You might also look at the library 'FAT16', but I cannot recall if the auther has a readline in there either.

Heres a teaser for string parsing in C. http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_5.html

So form your data by lines, then read it in by line, and parse it, sending or storing the data as needed. Its helpful if you can arrange the data in a 'known' format, then you can set an array to store the tokens in, and use a loop.