Go Down

Topic: read int/long from sd card (Read 2 times) previous topic - next topic

oran_outan

hi

I used an ethernet shield  for read an SDcard, on it I have a file.txt
Card initialization and open file is ok.
but, next I'm in fog for read what it contain.

my .txt file contain int
ex:

1000
2000
3000
4000

one integer (as "long" type) by line.(min 0, max 999940)
the length of the file is more 200000 line.

my way is to read the file, line after line, one line each 10ms, in a loop process.
value, after is convert to control DCmotor, but it's an other step...

if anyone can clear me for how do this !

here the code, where I am...
but the process to how get each line he's not clear for me... it's a part of shadow...



Code: [Select]
#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
*/

const int chipSelect = 4;

void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
 
  pinMode(53, OUTPUT); // cs pin is an output
 
  // see if card ready----------------------------
  if (!SD.begin(chipSelect))
  {
    Serial.println("Card failed");
    return;
  }
 
  Serial.println("card Ready");
 
  // Read the file -------------------------------
  File logFile = SD.open("testfile.txt");

  // if the file is available
  if (logFile)
  {
    Serial.println ("reading file");
    while (logFile.available());
  }
 
  // if the file not open
  else {
    Serial.println("error read file");
    return;
  }
}

void loop()
{
 
  File dataFile = SD.open ("testfile.txt", FILE_READ);
  if (dataFile)
  {
    long dataString = dataFile.read() ;
    }
 
    Serial.println(dataString);
  }
 
  else
  {
    Serial.println ("couldn't read file");
  }

  delay (10);
}




PaulS

You read data from the SD card just like from the serial port - one character at a time. Read and store that data in an array, until you encounter the carriage return. Keep the array NULL terminated, or append a NULL at the end. Then, call atoi() or atol(). Then, reset the array index and read the next set of characters.

oran_outan

thanks to have clear me about the process...
my skills are limited and need some help. have few questions...


if i have understand the process,  the code seems to this :
void loop()
{
  File dataFile = SD.open ("testfile.txt", FILE_READ);
  if (dataFile)
 
  {
        int c[20] ; // define an array, value are between 0/999940
        int i;
        for (i = 0 ; i< 20; i++); // write with index on array
        c = dataFile.read();
        if ( c == '\0' )
        {
           //serial_data = atol(c);
          serial_data = "";
         
          Serial.println (serial_data);
          Serial.println (c[20]);
          break;
        }

but i have error  on serial_data : invalid conversion from 'const char' to 'long int'
I have try some stuff but no result.
how i can do for convert in right format ?

and the return function is there good and on good place ? I have ad it for stop 'i' increment and restart it at the next frame


else, is it normal if I have nothing write on serial monitor if I print c[20] ?
on my monitor wind i have this :

InitInitializing SD card...card Ready
reading file

but nothing more...



thanks a lot for your help
o_o

oran_outan

copy paste code have do failure...
is like this

Code: [Select]

void loop()
{
  File dataFile = SD.open ("testfile.txt", FILE_READ);
  if (dataFile)
 
  {
        int c[20] ;
        int i;
        for (i = 0 ; i< 20; i++); // write with index on array
        c[i] = dataFile.read();
        if ( c == '\0' )
        {
           //serial_data = atol(c);
          //serial_data = "";
         
          Serial.println (c[20]);
          return;
        }

PaulS

Code: [Select]
        c[i] = dataFile.read();
Reads ONE character, and stores it in the ith element of the c array. It is NOT reading the whole record. You need two arrays - a char array and a long (not int) array.

Read the characters from the file, storing them in the char array, until you encounter a carriage return or line feed.

When you encounter one, call atol() to convert the char array to a long, and store that in the long array.

Reset the char array and index and continue reading.

oran_outan

hi

thanks, it's most clear and now run good. i get the file data...
i have do this code : i don't know if it's good, but run... the file is just read one time... i search now for read in loop...

best

Code: [Select]

void loop()
{
  File dataFile = SD.open ("testfile.txt", FILE_READ);
  if (dataFile)
 
  {
        char c[2];
        long data[1];
        c[0] = dataFile.read();
        if ( c == '\0' )
        {
          data[0] = atol(c); // atol()  convert string to long
         
          Serial.println (data[0]);
        }
  }





PaulS

Code: [Select]
        long data[1];
A one element array. How useful.

Quote
if ( c == '\0' )

The address of a static array (c) will never be '\0'.

Code: [Select]
          data[0] = atol(c); // atol()  convert string to long
But, c is NOT a string. A string is a NULL terminated array of chars. While c is an array of chars, it is not NULL terminated, so it can not be passed as input to a function that expects a string.

That code no longer loops to read every record. It reads exactly one character from the file. I fail to see how that is useful.

guix

#7
Oct 15, 2012, 04:39 pm Last Edit: Oct 15, 2012, 04:44 pm by guix Reason: 1
Here is basic example, hope it helps :)

Code: [Select]

char fileStr[] = "987654"; // example of what is in the file

char result[7]; // value are between 0/999940? so lenght is 6 characters + 1 ('\0')
uint8_t i = 0; // a counter

while (fileStr[i] != '\0') // while character isn't the string terminator
{
 result[i] = fileStr[i]; // store character in result
 i++; // increase counter
}

unsigned long number = atol(result); // convert result string to numeric value
Serial.print(number); // print the number

oran_outan

Quote
hope it helps

oui, beaucoup °°°°  :smiley-red:

merci

PaulS

Quote
Here is basic example, hope it helps

No. It suffers some of the same problems as OP's code. The result variable is NOT a string, since it is not NULL terminated. Therefore, is can not be passed to a function that expects a string.

There is no checking that there is room in results for the new character, so it is quite possible that you will write beyond the end of the array.

That code is not reading data from the file.




guix

PaulS, like this is better?
Code: [Select]

char fileStr[] = "987654"; // example of what is in the file

char result[7]; // value are between 0/999940? so lenght is 6 characters + 1 ('\0')
uint8_t i = 0; // a counter

while (fileStr[i] != '\0' && i < sizeof(result) - 1) // while character isn't the string terminator
{
 result[i] = fileStr[i]; // store character in result
 i++; // increase counter
}
result[i] = '\0';

unsigned long number = atol(result); // convert result string to numeric value
Serial.print(number); // print the number


But both are working I have tested :)

PaulS

Quote
PaulS, like this is better?

Yes.

guix

oran outan tu devrais essayer avec cette librairie ca sera peut être plus facile :) http://www.henningkarlsen.com/electronics/library.php?id=37

oran_outan

;) thanks, je regarde ça... merci pour ton aide...

Go Up