Arduino reading SD file line by line C++
Asked Answered
S

1

7

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.

Sweettempered answered 18/2, 2016 at 15:47 Comment(9)
Why don't you just perform the action using the content of Buffer before this line Buffer[bufferposition] = 0?Intratelluric
@ArtonDorneles What do you think are good points of this change? I don't think do some actions to the Buffer before terminating the string is a good idea.Nyasaland
I don't think opening a file and not closing it is good.Nyasaland
Sorry, I wanted to say after Buffer[bufferposition] = 0. At this point you have a valid string in your buffer that you can use to trigger any action. However, note that you is including a \n character as last character. This can be an issue when processing the line. In order to remove it, just replace Buffer[bufferposition] = 0; by Buffer[bufferposition-1] = 0;. There is nothing wrong in keeping the file open while processing the commands. You can close it after reading the whole data.Intratelluric
@ArtonDorneles Thank you for your help regarding the '\n' character. However my issue is not carrying out the action on the line, it is the method to read the next line of the text file for further action. So for example: line 1: G1 X19.500 Y9.000 line 2: G1 X-19.500 Y-9.000 line 3: etc.... how to read the next line and then successive lines till the EOF. Any ideas? thank you in advance.Sweettempered
So, do want to read all the lines before carrying out some action?Intratelluric
@ArtonDorneles Well each line is data for motors to use so I want to read a line from the SD, then carry out the action (move motors etc) and then read the next line etc. Hope that makes senseSweettempered
The code I presented in my answer does exactly this. You just need to replace insert the code to move the motors below the line indicated by //do some action here. The while loop will read one line each time and the content of the line will be stored in the variable buffer.Intratelluric
Thank you so much for your help! Think it's working nowSweettempered
I
15

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
}
Intratelluric answered 19/2, 2016 at 15:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.