Can't load entire contents of SD card

I’m trying to use an SD card to load configuration data for a robot I’m working on, but I can only read data from the SD card up to a certain point. In other words, while the data on my card may say “ABCDEFG”, what I actually get is “ABCDE”. I’m curious if it has to do with the Serial or SD buffer being full, or if there’s an error somewhere else.

Here is the actual content of my SD card file (config.txt):

A AXIS_DISTANCE_X 11494
B START_X 5715
C START_Y 3778
D PULLEY_R 100
E STEPS_PER_ROT 800
F servoPin 18
G ledPin 17
H stepPinM1 6
I dirPinM1 7
J stepPinM2 8
K dirPinM2 9
L pauseButtonPin 19

My sketch then consumes and processes each line, associating the numbers at the end of each line with the relevant variable in the Arduino sketch. For debugging, I have my sketch directly output any data that it does not understand, which results in:

L pause

The relevant code looks something like this:

 // Open the config file
  configFile = SD.open("config.txt");
  
  // Abort if file loading failed
  if(!configFile) {
    Serial.println("failed");
    return false;
  } else {
    currentFile = configFile;
    Serial.println();
  }
  
  // Read data from config file
  // Data format = {id} {variable name} {value}
  while(configFile.available()) {
     int id = configFile.read();
     
     switch(id) {
       // A = AXIS_DISTANCE_X
       case 'A':
         // Throw away variable name (17 bytes)
         for(int i=0; i<17; i++)
           configFile.read();
           
         AXIS_DISTANCE_X = readLong();
         configFile.read();
         
         Serial.print(" AXIS_DISTANCE_X = ");
         Serial.println(AXIS_DISTANCE_X);
         break;

       // more cases
         
       case 'K':
         for(int i=0; i<10; i++)
           configFile.read();
           
         dirPinM2 = readLong();
         configFile.read();
         
         Serial.print(" dirPinM2 = ");
         Serial.println(dirPinM2);
         break;
         
       case 'L':
        Serial.println("found L");
         for(int i=0; i<16; i++)
           configFile.read();
           
         pauseButtonPin = readLong();
         
         Serial.print(" pauseButtonPin = ");
         Serial.println(pauseButtonPin);
         break;
         
       default:
         Serial.write(id);
         break;
     }

It would be very funny if the word “pause” actually is triggering some sort of pausing behavior, but who knows? Any ideas?

Oh! Solved one problem to find another! I ran into this earlier, but it slipped my mind this time. When it encountered the "B" in "Button", it was running a different case, hence the apparent pausing behavior.

Accounting for that, I still can't read the number "19" from the end of the file. Since the number comes at the very end of the file, it is not followed by a line break, so the code I'm using to read in a value is crashing the sketch. What is a better way to read a 2 or 3 digit number (or better yet, a n-digit number) from a file, without crashing at the end of the file?

Here's the code I've been using to read in a long value:

void readToken(char *buf) {
    int c;
    while (true) {
      if (currentFile.available()) {
        c = currentFile.read();
        if ((c == ' ') || (c == 13) || (c == -1) || (c == ';')) {
          break;
        }
        *buf++ = c;
      }
    }
    *buf = '\0';   
}

parseInt()

Your end-of-file problem is the statement:

  if (currentFile.available()) {

It returns zero at end-of-file so you never hit the break when c is negative. Try this:

void readToken(char *buf) {
  int c;
  while (true) {
    c = currentFile.read();
    if ((c == ' ') || (c == 13) || (c == -1) || (c == ';')) {
      break;
    }
    *buf++ = c;
  }
  *buf = '\0';
}

Having while(true) { } that contains some conditional code to break out looks silly.

while(currentFile.available() > 0)
{
   // read and store the next character
}

makes, to me, a lot more sense.

It may seem silly but you still need the break for all the other cases.

Making readToken() elegant could be an interesting exercise in programming.