reading information from sd card

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

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.

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

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".

victorfb:
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.

1 Like

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.

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.

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.

1 Like

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.

I tried this code using a buffer called array.

/*
  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

If you are looking to parse a CSV file, this may help:

1 Like

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.

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.

It works! thanks a lot!!

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:

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.

 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.

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.

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.

"array2" is the name of the array.

In the Serial.print() call after the for loop, you are, as I showed before, referencing the array element at index 3.

this is all of my code,

Bullpoop. There ls no setup() function and no loop() function.

int counter;

Local variables, unlike global variables, are not initialized.

        if (counter >0){

At this point, counter could be 0, or it could be -28456 or 31874 or any other garbage left in that memory location.

          Serial.print(array);
          Serial.print("]");
          value = atoi(array);

The variable array is not NULL terminated. You should NOT be passing it to functions that expect a NULL terminated array of chars.

What is in this file you are trying to read? Why do you want to store one value in three different positions in the array?

Bullpoop. There ls no setup() function and no loop() function.

I forgot to put the begining of the setup, all the program runs on the setup that's why there is no loop() function

#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");
const int len = 4;
char array[len+1], c;
int counter;
int value, i, array2[3];;
counter=0;
  // if the file is available, write to it:
  if (dataFile) {
    while (dataFile.available()) {
      for (i=0; i<3; i++){     
        c = dataFile.read();
        if(c==','){
          if (counter >0){
          //Serial.print("Buffer: [");
          //Serial.print(array);
          //Serial.print("]");
            value = atoi(array);
            array2[i]=value;
            Serial.println(array2[i]);
          //Serial.print("value: ");
          //Serial.println(value);
          }
          counter=0;
          int minimum= min (array2 [0], min (array2 [1], array2 [2]));
          Serial.print("minimum: ");
          Serial.println(minimum);         
          }        
        else{
          if (counter<len){
            array[counter++] = c;
            array[counter] = 0;
            }
        } 
      }
    }
 dataFile.close();
 } 
// if the file isn't open, pop up an error:
 
}

void loop()
{
}

this is the full code, here I am trying to put 3 values on array2 and I want to find the smallest value on the array.

What is in this file you are trying to read? Why do you want to store one value in three different positions in the array?

I have a file with several numbers and I need to take them 3 at a time and I need to find the smallest value inside of the array.
This program works when it comes to read all the values from the array.

I have a file with several numbers and I need to take them 3 at a time and I need to find the smallest value inside of the array.

The way that you read the file has problems. You'd see them easier of you put each { on a new line and use Tools + Auto Format.

  if (dataFile)
  {
    while (dataFile.available())
    {
      for (i=0; i<3; i++)
      {     
        c = dataFile.read();

If there is a file, while not at the end of the file, loop three times, to read 3 characters from the file.

That is hardly going to get you 3 integer values read from the file. Ger rid of the for loop, and initialize and increment i just like you do counter, except at different places.

I tried to read the array on the loop but all I got was 0 on it. this is the code, is the idea right?

/*
  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");
const int len = 4;
char array[len+1], c;
int counter, counter2;
int value, i, array2[3];;
counter=0;
counter2=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);
            array2[counter2]=value;
            Serial.println(array2[counter2]);
          //Serial.print("value: ");
          //Serial.println(value);
          counter2++;
          counter=0;
          //if(counter2==2){
          //int minimum= min (array2 [counter2-2], min (array2 [counter2-1], array2 [counter2]));
          //Serial.print("minimum: ");
          //Serial.println(minimum);
          //counter2=0;
          //}         
          }        
        else{
          if (counter<len){
            array[counter++] = c;
            array[counter] = 0;
            }
        } 
      }
    }
 dataFile.close();
 } 
// if the file isn't open, pop up an error:
 
}

void loop()
{
}

The code is not working the way you want. And, yet you have commented out all the debug stuff. I'm sure that there is a good reason for that.

You've been asked to put all the { on a new line, and use Tools + Auto Format. You have not done so. I'm sure that there is a good reason for that.

What does the file you are reading from look like?