Go Down

Topic: Understanding of SD Cards (Read 232 times) previous topic - next topic

Hokahonay

hi all
I have come across something I don't understand and am hoping someone can shed some light on the problem
I have been developing a project to read / write to sd cards, I can write string to an sd card writing a testfile say:
00,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,
10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,
20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f,
30,31,32,33,34,35,36,37,38,39,3a,3b,3c,3d,3e,3f,
40,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f,
50,51,52,53,54,55,56,57,58,59,5a,5b,5c,5d,5e,5f,
60,61,62,63,64,65,66,67,68,69,6a,6b,6c,6d,6e,6f,
70,71,72,73,74,75,76,77,78,79,7a,7b,7c,7d,7e,7f,
80,81,82,83,84,85,86,87,88,89,8a,8b,8c,8d,8e,8f,
90,91,92,93,94,95,96,97,98,99,9a,9b,9c,9d,9e,9f,
a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,
the problem comes reading the file back.
the reference says I can only read back on char at the time.... BUT ..... if I use the dumpfile utility from the refrence it reads
Serial.println(dataFile.read());
if I use dumpFile to read my file above it prints out the data exactly as above, one line at the time, not one char at the time. Obviously there is something I am not fully understanding or does the
Serial.println(dataFile.read()); keep reading from the sd until it reads /n
I hope I have been clear enough for someone to explain how it does it
thanks in advance
Dave

CatweazleNZ

#1
May 24, 2015, 06:03 am Last Edit: May 24, 2015, 06:48 am by CatweazleNZ
Hi

This code from the dump file example is reading the file char by char and writing the result to the serial monitor. It will read CR/LF characters and write them to the serial monitor which is why you see the line breaks in the output when only the write() function is being used.

Code: [Select]
 
// if the file is available, write to it: (SHOULD BE READ FROM IT)
  if (dataFile) {
    while (dataFile.available()) {
      Serial.write(dataFile.read());
    }
    dataFile.close();
  }


You can read text data files line by line using the readStringUntil() procedure. For example this code from my application is reading a text file line by line and writing it to a web page:
Code: [Select]

while (l_file.available()) {
  String l_line = l_file.readStringUntil('\n');
  SPIDeviceSelect(DC_EthernetSSPin); //Enable Ethernet on SPI (Disable others)
  G_EthernetClient.println(l_line);
  SPIDeviceSelect(DC_SDCardSSPin);
}


If you want to read the example file you provided and parse each data line to extract the data separated by the commas you could use my ENDF2 procedure. (Extract Next Delimited Field)

Code: [Select]

String ENDF2(const String &p_line, int &p_start, char p_delimiter) {
//Extract fields from a line one at a time based on a delimiter.
//Because the line remains intact we dont fragment heap memory
//p_start would normally start as 0
//p_start increments as we move along the line
//We return p_start = -1 with the last field

  //If we have already parsed the whole line then return null
  if (p_start == -1) {
return "";
  }

  int l_start = p_start;
  int l_index = p_line.indexOf(p_delimiter,l_start);
  if (l_index == -1) { //last field of the data line
p_start = l_index;
return p_line.substring(l_start);
  }
  else { //take the next field off the data line
p_start = l_index + 1;
return p_line.substring(l_start,l_index); //Include, Exclude
  }
} //ENDF2


Cheers

Catweazle NZ

CatweazleNZ

#2
May 24, 2015, 06:28 am Last Edit: May 25, 2015, 03:09 am by CatweazleNZ
Hi

For example:
Code: [Select]

#include <SPI.h>
#include <SD.h>

void setup() {
}

void loop() {
  //This code reloads arrays from command separate file input
  //We assume sixteen comma separated fields
  //This example is reloading the same String array for each input file.
  File l_file = SD.open("TESTFILE.TXT", FILE_READ);
  String l_line;
  String l_fieldlist[16];
  while (l_file.available()) {
    String l_line = l_file.readStringUntil('\n');
    l_line.trim();
    if (l_line != "") {
      int l_start = 0;
      int l_index = 0;
      while ((l_start != -1) && (l_index < 16)) {
        l_fieldlist[l_index] = ENDF2(l_line,l_start,',');
      }
    }
  }
  l_file.close();
}

String ENDF2(const String &p_line, int &p_start, char p_delimiter) {
//Extract fields from a line one at a time based on a delimiter.
//Because the line remains intact we dont fragment heap memory
//p_start would normally start as 0
//p_start increments as we move along the line
//We return p_start = -1 with the last field

  //If we have already parsed the whole line then return null
  if (p_start == -1) {
    return "";
  }

  int l_start = p_start;
  int l_index = p_line.indexOf(p_delimiter,l_start);
  if (l_index == -1) { //last field of the data line
    p_start = l_index;
    return p_line.substring(l_start);
  }
  else { //take the next field off the data line
    p_start = l_index + 1;
    return p_line.substring(l_start,l_index); //Include, Exclude
  }
} //ENDF2


This should load a file into an array of string variables. You can convert the string variables to numeric values if required. The example reloads one sixteen element array for every input line. You can use your own memory variables.

The full source code and some documentation for my application is available at http://2wg.co.nz/ if you want to look for other file handling code etc.

Cheers

Catweazle NZ

Hokahonay

hi CatweazleNZ
thanks for coming back to me, the mist has cleared so that's a BIG THANK YOU!!!!

Go Up