[Solved] Generating variables from an SD Card File.

I have written some config data to an SD Card and the format is flexible i.e. I can write it any format.
The present format is : “1000.0001.B01.A”
I was thinking the “.” can be used as a separator.

I want to end up with 4 variables viz

a = “1000”;
b = “0001”;
c = “B01”;
d = “A”;

I am trying to read the data into a buffer and then manipulate it from there.
So far I can read the data, but I am not getting it into the buffer.

Can someone please tell me help me with code to read into the buffer.

This is the code :

/*  Read from SD Card and create variables. */


#include <SdFat.h> // SD Card library
#include <SPI.h>

/* The contents of conf.txt file can be written
in any format to facilate reading. */

//  contents  : 1000.0001.A01.A
//  bufmem    : 0123456789012345
//              0         1
//  var[]       aaaa bbbb ccc d

char a[5];
char b[5];
char c[4];
char d[2];
char buffer[20];

SdFat SD;
File datFile;
char fileName[] = "conf.txt";

void setup()
  {
    pinMode(10, OUTPUT);
    
    // Start Serial
    Serial.begin(9600);	
    while (!Serial) {;}              // wait till port connects
    Serial.println(F("Serial started.")); // test print
    
    // SD Card setup
    Serial.print(F("Initializing SD card..."));
    
    // SD Card setup result
    if (!SD.begin(4, SPI_HALF_SPEED)) {
      SD.initErrorHalt();
      }

    Serial.println(F(" done."));
    
    Serial.print(F("Reading config file... "));
    // Open config file:
    datFile = SD.open("conf.txt");
    
    if (datFile) {
    // Read file contents:
    while (datFile.available()) {
      Serial.write(datFile.read());
//      Serial.readBytes(buffer, 15);
//        for (int i=0; i<15; i++){
//        buffer[i] = datFile.read();
//        buffer[i] = Serial.write(datFile.read());
        }
      }
      
    // Close config file:
    datFile.close();
    } else {
      Serial.println(F("Error opening config file."));
    }
      
    for (int i = 0; i <15; i++) {
      Serial.print(i);
      Serial.print(" : ");
      Serial.println(buffer[i]);
    }
    
    char *a = buffer + 0;
    char *b = buffer +5;
    char *c = buffer +10;
    char *d = buffer +14;
    
    Serial.println(a);
    Serial.println(b);
    Serial.println(c);
    Serial.println(d);
  }

    

void loop()
  {
   }

This is the present output :

Serial started.
Initializing SD card… done.
Reading config file… 1000.0001.B01.A
1000.0001.B01.A

Can anyone tell me why is the data being printed twice?

Can anyone tell me why is the data being printed twice?

I believe that there is more than one line written in conf.txt and the while (datFile.available())is reading everything. That can happen if you open the serial monitor to confirm the creation of a file. You can read the card in the computer to confirm.

Your code is close. Here is a slight modification which only reads the first 15 bytes, regardless of what is in the file.

/*  Read from SD Card and create variables. */

#include <SdFat.h> // SD Card library
#include <SPI.h>

char a[5];
char b[5];
char c[4];
char d[2];
char buffer[20];

SdFat SD;
File datFile;
char fileName[] = "conf.txt";
// conf.txt  1000.0001.B01.A

void setup()
{
  pinMode(10, OUTPUT);

  // Start Serial
  Serial.begin(9600);
  while (!Serial) {
    ; // wait till port connects
  }
  Serial.println(F("Serial started.")); // test print

  // SD Card setup
  Serial.print(F("Initializing SD card..."));

  // SD Card setup result
  if (!SD.begin(4, SPI_HALF_SPEED)) {
    SD.initErrorHalt();
  }

  Serial.println(F(" done."));

  Serial.print(F("Reading config file... "));
  // Open config file:
  datFile = SD.open("conf.txt");

  if (datFile) 
  {
    // Read file contents:
    datFile.readBytes(buffer, 15);
    Serial.println(buffer); //confirm what was read
    // Close config file:
    datFile.close();
  }
  else 
  {
    Serial.println(F("Error opening config file."));
  }

  for (int i = 0; i < 15; i++) {
    Serial.print(i);
    Serial.print(" : ");
    Serial.println(buffer[i]);
  }

  char *a = buffer + 0;
  char *b = buffer + 5;
  char *c = buffer + 10;
  char *d = buffer + 14;

  Serial.println(a);
  Serial.println(b);
  Serial.println(c);
  Serial.println(d);
}

void loop()
{
}

Thanks cattledog. That helped me achieve my objective.

Coming back to this little problem…
Things have evolved and now I do actually want to read everything in the file into a buffer.

Could someone please help me tweak this bit of the code to create the buffer :

 if (datFile) {
    // Read file contents:
    while (datFile.available()) {
      Serial.write(datFile.read());
//      Serial.readBytes(buffer, 15);
//        for (int i=0; i<15; i++){
//        buffer[i] = datFile.read();
//        buffer[i] = Serial.write(datFile.read());
        }
      }

FWIW I will be turning the code into a function, so cannot have a hard limit of readBytes().

Things have evolved and now I do actually want to read everything in the file into a buffer.

Is that even reasonable? How big is the file?

so cannot have a hard limit of readBytes().

Tough. You MUST have a hard limit - the size of the array to store data in.

PaulS: Is that even reasonable? How big is the file? Tough. You MUST have a hard limit - the size of the array to store data in.

I mean I don't want a fixed number, some files are 8 char the biggest is about 30 char. Ok, so I guess I can use sizeof(array), but something "looks" wrong :(

 if (datFile) {
    // Read file contents:
    while (datFile.available()) {
        Serial.readBytes(buffer, sizeof(buffer));

    }
 }

From what I have read about "sizeof" command. It is only looked at when the sketch is compiled. That is a static number from that point on. I am working on something simular to this. I am reading from a serial port but the data from the bar codes I will be reading are different in length. Wanting to keep my sketch as small as possible. I have written the code with more loops than needed. I am now looking for a carriage return to "break" out of the "while" loop and continue on with the sketch when the buffer is empty and a CR is detected. If you create your file with say a NULL at the end, use that to break out of your loop.

Hope I was not barking up the wrong tree. And this was of help.

Paul

Paul1958:
From what I have read about “sizeof” command. It is only looked at when the sketch is compiled. That is a static number from that point on.
I am working on something simular to this. I am reading from a serial port but the data from the bar codes I will be reading are different in length. Wanting to keep my sketch as small as possible. I have written the code with more loops than needed. I am now looking for a carriage return to “break” out of the “while” loop and continue on with the sketch when the buffer is empty and a CR is detected. If you create your file with say a NULL at the end, use that to break out of your loop.

Hope I was not barking up the wrong tree. And this was of help.

Paul

sizeof(array) is set as soon as you declare the array, and yes sizeof() won’t change.
I will be declaring a separate array for each file, so I will use the relevant sizeof() to read from the file.
I know the theory for what I want to do, but sometimes it is like pulling teeth trying to get straightforward help here.
I guess I am back to wasting another few hours searching for the correct syntax myself - kinda defeats the purpose of having a forum for help.

but sometimes it is like pulling teeth trying to get straightforward help here.

Nonsense. What is difficult is finding someone to tell you how to do something that can’t be done.

I guess I am back to wasting another few hours searching for the correct syntax myself

Syntax for what?

PaulS: Nonsense. What is difficult is finding someone to tell you how to do something that can't be done. Syntax for what?

I believe that what I am trying to do can be done. It is probably just your interpretation of what I am trying to do that makes you believe it can't be done.

aisc: I believe that what I am trying to do can be done. It is probably just your interpretation of what I am trying to do that makes you believe it can't be done.

I would recommend looking at what Ladyada does in her GPS library for double-serial buffering and how she parses.... very simple to understand. Adafruit GPS.cpp

I hacked up to fit my need, but the INO shows how I utilized the concept in this project.

Ray

Thanks for the links Ray. I did have a look at the GPS sketch - it is way beyond the simple objective I was trying to achieve.

Anyway after some reading and a lot of mucking about I had already figured out a solution and now have a function that reads a file's entire contents from an SD card and spits it out as a variable.