Arduino reading SD file line by line C++

Julian Das picture Julian Das · Feb 18, 2016 · Viewed 18.6k times · Source

I am trying to read a text file "Print1.txt", line by line, from an SD card attached to my Arduino MEGA. So far I have the following code:

#include <SD.h>
#include <SPI.h>
int linenumber = 0;
const int buffer_size = 54;
int bufferposition;
File printFile;
char character;
char Buffer[buffer_size];
boolean SDfound;


void setup()
{
  Serial.begin(9600);
  bufferposition = 0;
}

void loop() 
{
  if (SDfound == 0)
  {
    if (!SD.begin(53)) 
    {
      Serial.print("The SD card cannot be found");
      while(1);
    }
  }
  SDfound = 1;
  printFile = SD.open("Part1.txt");


  if (!printFile)
  {
    Serial.print("The text file cannot be opened");
    while(1);
  }

  while (printFile.available() > 0)
  {
    character = printFile.read();
    if (bufferposition < buffer_size - 1)
    {
      Buffer[bufferposition++] = character;
      if ((character == '\n'))
      {
        //new line function recognises a new line and moves on 
        Buffer[bufferposition] = 0;
        //do some action here
        bufferposition = 0;
      }
    }

  }
  Serial.println(Buffer);
  delay(1000);
}

The function returns only the first line of the text file repeatedly.

My Question

How do I change the function to read a line of text, (with the hope to perform an action on such line, shown by "//do some action") and then move onto the next line in the subsequent loop, repeating this until the end of file has been reached?

Hopefully this makes sense.

Answer

Arton Dorneles picture Arton Dorneles · Feb 19, 2016

Actually, your code returns only the last line of the text file because it is printing the buffer only after reading the whole data. The code is printing repeatedly because the file is being opened inside the loop function. Usually, reading a file should be done in the setup function that is executed only one time.

Instead of reading the data char by char into the buffer, you could read until find the delimiter and assign that to a String buffer. This approach keep your code simple. My suggestion to fix your code is right below:

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

File printFile;
String buffer;
boolean SDfound;


void setup() {
  Serial.begin(9600);

  if (SDfound == 0) {
    if (!SD.begin(53)) {
      Serial.print("The SD card cannot be found");
      while(1);
    }
  }
  SDfound = 1;
  printFile = SD.open("Part1.txt");

  if (!printFile) {
    Serial.print("The text file cannot be opened");
    while(1);
  }

  while (printFile.available()) {
    buffer = printFile.readStringUntil('\n');
    Serial.println(buffer); //Printing for debugging purpose         
    //do some action here
  }

  printFile.close();
}

void loop() {
   //empty
}