Offline
Newbie
Karma: 0
Posts: 21
|
 |
« on: November 13, 2012, 05:42:41 pm » |
Hi working on a program that needs to pull data from an SD card. The file is a .csv and i have 2 columns and multiple rows(about 400). The data is 4 or 5 digit numders eg 2568, 45876. I have a counter in my program and want to pull the first row at say count 5, then at count 10 pull the second row and so on. Any tips on how to do this, I have seen examples of 1 column and 1 row but not multiple. I could separate the columns into 2 files if that makes it easier.
Thanks for your help
|
|
|
|
|
Logged
|
|
|
|
|
Poole, Dorset, UK
Offline
God Member
Karma: 12
Posts: 781
|
 |
« Reply #1 on: November 13, 2012, 06:33:01 pm » |
The arduino does not under stand file types, at all, or at least in any thing like the way a PC does. Windows associates a file type with a program and then calls then calls that program to deal with the file. I can't think what application a .cvs file is for. But I would try this, Export the file from the application (and I mean export not save) as a text file. You can the see the format of data in the file with notepad. After that its not to hard (  ) to read the data from the file. Mark
|
|
|
|
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 51
Posts: 2192
|
 |
« Reply #2 on: November 13, 2012, 07:05:12 pm » |
You're going to need a state machine and basic string reading techniques to read in the values. Posting what code you have so far is going to make it a lot easier to help.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 100
Posts: 6787
-
|
 |
« Reply #3 on: November 13, 2012, 08:03:41 pm » |
Your sketch will read the file as a sequence of characters and it will need to step through it looking for line separators until it gets to the line of interest, then step through the line looking for column separators (i.e. commas) until it gets to the field of interest, and then extract the characters containing the decimal digits and parse them to get the corresponding number.
If you can separate the columns into separate files (one column per file) that reduces the amount of work needed to parse the file contents.
Do you have any performance constraints for this - do you care how long it takes to read the values?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 21
|
 |
« Reply #4 on: November 13, 2012, 08:19:47 pm » |
I am going to simplify the code and post it. As for speed it will need to be read in under .1 second.
Thanks for the replies
|
|
|
|
|
Logged
|
|
|
|
|
Jakarta
Offline
Newbie
Karma: 0
Posts: 10
Arduino rocks
|
 |
« Reply #5 on: November 13, 2012, 09:09:39 pm » |
Maybe this article will give you good clue to do that : Read Config File from an SD Card
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 336
Posts: 36476
Seattle, WA USA
|
 |
« Reply #6 on: November 14, 2012, 06:10:12 am » |
I can't think what application a .cvs file is for. It's csv, not cvs. The csv extension stands for comma-separated values, and is often used when the data is to be parsed by applications that don't need all the overhead of something like Excel, and don't need the data in binary format. csv files ARE text files. If you can separate the columns into separate files (one column per file) that reduces the amount of work needed to parse the file contents. But, since parsing is trivial, why bother?
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 100
Posts: 6787
-
|
 |
« Reply #7 on: November 14, 2012, 09:58:41 am » |
But, since parsing is trivial, why bother?
Once you know how to do it, sure. But getting it working the first time is not trivial. If the need can be avoided, why suffer the extra complexity?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 21
|
 |
« Reply #8 on: November 14, 2012, 05:07:36 pm » |
Yes I am a total noob, so parsing is not trivial to me. I had another idea but can't get it to work. If I could write one number in many files, I could open each file one at a time when needed. See this code - I can't index the file name, is this even possible? #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_TFTLCD.h> // Hardware-specific library #include <SD.h>
#define SD_CS 5 #define LCD_RESET A4
Adafruit_TFTLCD tft; int8_t saved_spimode;
void disableSPI(void) { saved_spimode = SPCR; SPCR = 0; }
void enableSPI(void) { SPCR = saved_spimode; }
const int buttonPin = 2; int cycles = 0; unsigned long serialTimer; int cyclecount = 0; int B = 0;
void setup() { Serial.begin (9600); pinMode (buttonPin, INPUT); tft.reset(); uint16_t identifier = tft.readID(); tft.begin(identifier); Serial.print("Initializing SD card..."); if (!SD.begin(SD_CS)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); disableSPI(); serialTimer =millis(); }
void loop () { cycles++; while (digitalRead(buttonPin) == HIGH); while (digitalRead(buttonPin) == LOW); delay (50); Serial.println(cycles); for (B=0; B<2000; B+=5){ if (cycles == B) test (); } }
void test () { enableSPI(); char D = (B); File myFile2; myFile2 = SD.open("(D).txt", FILE_WRITE); if (myFile2) { Serial.print("Writing to test.txt..."); myFile2.println(B); myFile2.close(); Serial.println("done."); } else { Serial.println("error opening test.txt"); } disableSPI(); }
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 100
Posts: 6787
-
|
 |
« Reply #9 on: November 14, 2012, 05:28:42 pm » |
See this code - I can't index the file name, is this even possible?
I'm not sure what you mean by 'index the file name', or in what respect the sketch fails to do it.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 21
|
 |
« Reply #10 on: November 14, 2012, 05:36:05 pm » |
File2 = SD.open("(D).txt", FILE_WRITE);
I want "D" to index.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 100
Posts: 6787
-
|
 |
« Reply #11 on: November 14, 2012, 07:24:03 pm » |
I want "D" to index.
And still I don't know what that means. Please try to describe what you're trying to do, without using the word "index".
|
|
|
|
|
Logged
|
|
|
|
|
Pittsburgh, PA, USA
Offline
Faraday Member
Karma: 33
Posts: 3020
I only know some basic electricity....
|
 |
« Reply #12 on: November 14, 2012, 07:35:38 pm » |
Unless SD.open() has special powers to read "(D).txt" and replace D with a value, you need to build a file name before the call to open. sprintf() is the easy way to format text into a char or byte array. I think you don't even need to include stdlib to use sprintf(). http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.htmlAs a beginner you would do well to look it up on a C++ website and screw around with it for a while, sprintf() can turn none to many numeric variables into tightly formatted text. The strtok() command is good for parsing buffered text. It will take a little longer to learn if you choose to use it. The reality is that strtok is both clean and simple in action. IIRC you need to include string.h to get strtok. http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html
|
|
|
|
|
Logged
|
Examples can be found at Learning in the Main Site and at the Playground
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 21
|
 |
« Reply #13 on: November 15, 2012, 10:13:09 am » |
Ok I know this code is a mess. But can someone shown me how it should look. Not sure how to arrange sprintf. void test () { enableSPI(); char D = (B); //B is a counter File newfile; File myFile2; myFile2 = SD.open((sprintf (newfile, "sensor%d.txt", (D) )) , FILE_WRITE); //know idea of how to arrange this, do I use D or B? if (myFile2) { Serial.print("Writing to test.txt..."); myFile2.println(B); myFile2.close(); Serial.println("done."); } else { Serial.println("error opening test.txt"); } disableSPI(); }
|
|
|
|
« Last Edit: November 15, 2012, 10:20:58 am by Crebsyn »
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 1
Posts: 83
|
 |
« Reply #14 on: November 15, 2012, 10:47:14 am » |
Try this instead: int D = 1; // obviously you can set D however you want, but it should be an int char fileName[13]; sprintf(fileName, "sensor%d.txt", D); myFile2 = SD.open(fileName, FILE_WRITE);
|
|
|
|
|
Logged
|
|
|
|
|
|