read from SD card and convert to float

Hi,

I tried to read a Dataset from a SD card on my Yun.
The Data is in a .txt doc with 4 columns (seperated with a HT) and I want to fill the first 1D array with the fisrt column and another 3D array with the other 3 columns.
I started with a unsinged char array for my incoming ASCII characters but the atof funtction can't convert it to a float number. The error message is

SD_read:59: error: invalid conversion from 'unsigned char' to 'const char*' [-fpermissive]

SerialUSB.println(atof(read_buffer[0]);

Am I using the atof function wrong?

#include <FileIO.h>

void setup() {
  // Initialize the Bridge and the Serial
  Bridge.begin();
  Serial.begin(9600);
  FileSystem.begin();

  while (!SerialUSB); // wait for Serial port to connect.
  SerialUSB.println("Filesystem datalogger\n");
}


void loop() {
  int i;
  unsigned char read_buffer[100];

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  // The FileSystem card is mounted at the following "/mnt/FileSystema1"
  File dataFile = FileSystem.open("/mnt/sd/datalog.txt", FILE_READ);

  // if the file is available, write to it:
  if (dataFile) {
    while(dataFile.available()){
      read_buffer[dataFile.position()] = dataFile.read();
      SerialUSB.println(atof(read_buffer); 
   
    }
   //SerialUSB.println(atoi(read_buffer)); 
    //dataFile.close();
    // print to the serial port too:
    
  }
  // if the file isn't open, pop up an error:
  else {
    SerialUSB.println("error opening datalog.txt");
  }
  dataFile.close();
  delay(15000);

}

content of the datalog.txt file:

0.000	1.233	2.455	3.566
0.020	3.566	4.677	5.899
0.040	6.899	7.900	8.122
0.050	9.233	1.566	2.666

The atof() function operates on an array of chars terminated by a zero, otherwise known as a C style string.

Your
  SerialUSB.println(atof(read_buffer[0]); has 2 problems. The first is that the parameter being passed to atof() is not a zero terminated array of chars and secondly there is a parenthesis missing.

SD_read:59: error: invalid conversion from 'unsigned char' to 'const char*' [-fpermissive]

SerialUSB.println(atof(read_buffer[0]);

What do you know. The compiler is right. The atof() function takes an array, not a character. Why is the [ 0 ] in there?

   while(dataFile.available()){
      read_buffer[dataFile.position()] = dataFile.read();
      SerialUSB.println(atof(read_buffer);
   
    }

I hope that there are less than 100 characters in the file. Why are you calling atof() after adding each character? Why are you calling a function that expects a string with a char array?

You need to learn the difference between a string and a char array. Hint: A string is a NULL-terminated something.

content of the datalog.txt file:

So what should atof() convert all that text to?

Another choice is file.parseFloat() which should return the next value in the file.

  if (dataFile) {
    int i = 0;
    while(dataFile.available()) {
        array1[i] = dataFile.parseFloat();
        array2[i][0] = dataFile.parseFloat();
        array2[i][1] = dataFile.parseFloat();
        array2[i][2] = dataFile.parseFloat();
        i++;
        }
    }

I tried the version with parseFolat but it doesnt work, the error message is:

SD_read:68: error: invalid types 'float[int]' for array subscript

array2*[0] = dataFile.parseFloat();*
why can't i index a float array by writing an integer into the brackets?

why can't i index a float array by writing an integer into the brackets?

Who can tell from a mangled snippet?

http://snippets-r-us.com

#include <FileIO.h>

void setup() {
  // Initialize the Bridge and the Serial
  Bridge.begin();
  Serial.begin(9600);
  FileSystem.begin();

  while (!SerialUSB); // wait for Serial port to connect.
  SerialUSB.println("Filesystem datalogger\n");
}


void loop() {
  int i,j;
  int inChar;
  String inString = "";
  float array1[50];
  float array2[10];
  //float array3[10]



  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  // The FileSystem card is mounted at the following "/mnt/FileSystema1"
  File dataFile = FileSystem.open("/mnt/sd/datalog.txt", FILE_READ);

  //str_buffer = '0';
  // if the file is available, write to it:
  if (dataFile) {
      i=0;
    while(dataFile.available()){

        array1[i] = dataFile.parseFloat();
        array2[i][0] = dataFile.parseFloat();
        array2[i][1] = dataFile.parseFloat();
        array2[i][2] = dataFile.parseFloat();
        SerialUSB.println(array1[i]);
        i++;
  
    /*
     if ((inChar>45)&&(inChar<58)) { 
      inString += (char)inChar;
      i++;
     }
     else if (inChar <11){
      input[i] = inString.toFloat();
      inString = "";
     }
  */
  }

    }
  // if the file isn't open, pop up an error:
  else {
    SerialUSB.println("error opening datalog.txt");
  }
  
  dataFile.close();
  //for (j=0;j<3;j++)
  //{
  /*j=0;
    for(i=0;i<4;i++){
      SerialUSB.println("erste:");
      SerialUSB.println(array2[0][0]);
    } */
  //}
  delay(30000);

}

You said 'three dimensional' but I assumed you meant 'two-dimensional'. Try:

 float array2[10][3];

WARNING: array1 shouldn't have to be sized for 50 lines in the file if array2 is only sized for 10 lines.

If the file contains plain text, what happens with this code:

  char temp;
  int count;
  static int valsRead = 0;
  

// other loop() code...
  count = 0;
  while(dataFile.available()){
      read_buffer[count] = dataFile.read();
      if (read_buffer[count] == '\t') {              // It's a tab character...
         read_buffer[count] = '\0';                  // replace it with null
         array1[valsRead++] = atof(read_buffer);     // Convert to fp number  
         count = 0;
      } else {
         count++;
      }
   }

I haven't tested this, so it's just an idea that might work.

EDIT: I forgot the else clause for count.