Go Down

Topic: reading information from sd card (Read 2424 times) previous topic - next topic

victorfb

I have a text file stored on a sd card with information that I need to use on my program. How can I read the values one by one so I can use this information?
Thank you

PeterH

You need to know how the numbers are encoded in the file (one number per line? comma separated list? etc) and then read the relevant bytes from the file into a char array and parse the resulting string.
I only provide help via the forum - please do not contact me for private consultancy.

victorfb

they are separated by commas. but how can I do that, is there a code or command to do that?

PaulS

Quote
but how can I do that, is there a code or command to do that?

What is "that"? Google returned an overwhelming number of hits when searching for "that".

PeterH


they are separated by commas. but how can I do that, is there a code or command to do that?


There are various approaches open to you, but the simplest one is to read the file character by character. If the character is not a comma, append it to a char array buffer. If it is a comma, parse the content of the buffer to a number and clear the buffer. This will give you a sequence of numbers read from the file. I assume you know what to do with the numbers from there on.
I only provide help via the forum - please do not contact me for private consultancy.

victorfb

Quote
What is "that"? Google returned an overwhelming number of hits when searching for "that".

If you read the whole topic you will know what "that" is.
Quote
There are various approaches open to you, but the simplest one is to read the file character by character. If the character is not a comma, append it to a char array buffer. If it is a comma, parse the content of the buffer to a number and clear the buffer. This will give you a sequence of numbers read from the file. I assume you know what to do with the numbers from there on.

My difficulty is how to read character by character, after it is all the values are printed on the serial monitor I don't know how to read them.

PaulS

Quote
My difficulty is how to read character by character

The File::available() method tells you whether there is still data to read. The File::read() method reads one character. The examples show how to use them to read an entire file.

It is up to you, then, whether to print the data to the serial port or do something else with the data is up to you.

victorfb

Quote
The File::available() method tells you whether there is still data to read. The File::read() method reads one character. The examples show how to use them to read an entire file.

which examples, arduino examples? I tried to look at them and they only show how to get the values and print on the serial monitor.

victorfb

I tried this code using a buffer called array.
Code: [Select]
/*
  SD card file dump

This example shows how to read a file from the SD card using the
SD library and send it over the serial port.

The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4

created  22 December 2010
by Limor Fried
modified 9 Apr 2012
by Tom Igoe

This example code is in the public domain.

*/

#include <SD.h>

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 10;

void setup()
{
// Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
 
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
 
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("path.txt");
char array[4];
int counter;
int value;
counter=0;
  // if the file is available, write to it:
  if (dataFile) {
    while (dataFile.available()) {
      array[counter] = dataFile.read();
      if(array[counter] =','){
        value = atoi(array);
        Serial.print(value);
        }
     counter++;
    }
    dataFile.close();
  } 
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}

void loop()
{
}

but all the code returns is a bunch of 0s

SurferTim

If you are looking to parse a CSV file, this may help:
http://arduino.cc/forum/index.php/topic,132519.msg1001919.html#msg1001919

PeterH

You've got the basic idea but there are a couple of details wrong.

When using 'C' strings, you need to put a null character after the last character in the string. The functions such as atoi() that operate on strings use this to know where the end of the string is. Make your buffer array one element bigger, and write a null character at the end of the string. The easiest way to ensure this is always done is to write the null whenever you append a character.

You have a typo - you used '=' (assignment) instead of '==' (test for equality).

You don't really need to append the ',' to the buffer. It probably won't hurt, but to avoid any doubt test the character before you decide what to do with it.

So that you know what's going on, print out the content of the buffer as well as the value that atoi() gave you from it.

Just to be on the safe side, you should add a check that you aren't adding more characters to the buffer than it has space for.

Code: [Select]


const int LEN = 4;
char array[LEN+1]; // +1 allows space for the null terminator
int counter = 0;

...

while (dataFile.available())
{
   char c = dataFile.read();
   if(c == ',')
   {
       if(counter > 0)
       {
           Serial.print("Buffer: [");
           Serial.print(array);
            Serial.println("]");
           value = atoi(array);
           Serial.print("Value: ");
           Serial.println(value);
       }
       counter = 0;
   }
   else
   {
       if(counter < LEN)
       {
           array[counter++] = c; // append the character
           array[counter] = 0; // null-terminate the array
       }
   }
}


It would probably be a good idea to check for any other characters and not just assume that anything that isn't a comma must be a digit, but if you wrote the file and know it doesn't have any spaces or line feeds or anything else in it then you might decide not to bother.
I only provide help via the forum - please do not contact me for private consultancy.


victorfb

I have one more question, how can I use the values stored in "value"? I need to put three values in an array at a time to compare these values, I tried to do this:
Code: [Select]
File dataFile = SD.open("path.txt");
const int len = 4;
char array[len+1], c;
int counter;
int value;
counter=0;
  // if the file is available, write to it:
  if (dataFile) {
    while (dataFile.available()) {
      c = dataFile.read();
      if(c==','){
        if (counter >0){
          Serial.print("Buffer: [");
          Serial.print(array);
          Serial.print("]");
          value = atoi(array);
          Serial.print("value: ");
          Serial.println(value);
        }
        counter=0;
      }
      else{
        if (counter<len){
          array[counter++] = c;
         
          array[counter] = 0;
        }
      }
    }
int i, array2[3];
for (i=0; i<3; i++){
   array2[i]=value;
   Serial.print("array2 [i]: ");
   Serial.println(array2[i]);
}
Serial.println(array2[3]);
     
    dataFile.close();
  }

but all I get on the on array2 is 0s.

PaulS

Code: [Select]
Serial.println(array2[3]);
The valid index values for an array of three elements are 0, 1, and 2.

We'd need to see ALL of your code AND your serial output.

victorfb

Code: [Select]
The valid index values for an array of three elements are 0, 1, and 2.
on the for loop I just use 0, 1 and 2 "array2" is the name of the array.
Quote
We'd need to see ALL of your code AND your serial output.

this is all of my code, I need to put the values stored in "value" on an array of 3, find the minimum value between them and then store another 3 to compare them.

Go Up