How to read variables stored on an SDCard?

just looking from assistance with some code, I am trying to read variable from a sd card and I am getting stuck with getting the value from a requested matching variable.

say I have in a text file "config.txt"
mac=00:00:00:00:00,
ip=192.168.1.1,

how do I get I to search for ip and return the value to the buffer I was able to follow some of an old thread but got lost towards the end.

I have been able to get the INIFile. library working the way I need it to from Steve Marple GitHub - stevemarple/IniFile: Arduino library to parse ini files. the only issues is that I need it to work with sdfat as the rest of my sketch depends on it.

any help would be great .

I am trying to read variable from a sd card

Variables are not stored on the SD card. Data is. That data might represent a value that you want to store in a variable.

how do I get I to search for ip and return the value to the buffer

How do you get what to search? You need to write code to read each record in the file, and determine what to do with it. The key there is defining exactly what a record is, so you know when to suspend reading and storing, and deal with what you have read and stored.

What "buffer" do you expect the data to be returned to? How is that buffer defined? What are you going to do with the data in the buffer, after you get it there.

A string line 00:00:00:00:00:00 is useless to the Ethernet class which wants an array of bytes to define the mac address.

Paul

thanks for your reply you are correct it is the data I am after to populate a few different thing such as the IP and Mac address when the unit load.

this what I have started with I think it maybe completely wrong thou.

const char buffer_mac = 80;
char buffermac[buffer_mac] = "mac;";

  ifstream sdin("CONFIG.TXT");

  Serial.println("... inside the Loop");

  while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount()) 
  {
    if (strcmp(buffermac, buffer ) == 0)
   { Serial.println("Output in the if statement for line 1 is ");
   Serial.print("buffermac");
   Serial.println(buffer);
  
   }

sscanf(buffermac, "%x:%x:%x:%x:%x:%x ", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] );
const char buffer_mac = 80;
char buffermac[buffer_mac] = "mac;";

You need an 80 element array to store 5 characters? Why is 80 stored in a char?

  while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount())

What is in buffer when this function when sdin.getline() returns? This appears that it will read up to a carriage return. The example that you showed earlier implies that buffer will contain "mac=00:00:00:00:00," which will then not equal "mac;".

So, either your example data was wrong or this code is.

sscanf(buffermac, "%x:%x:%x:%x:%x:%x ", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] );

Given that you defined buffermac to contain "mac;" this will result in mac[0] through mac[5] containing zeros.

their is something wrong with my code as to be honest am have not been programing for too long so I would be something stupid I have done.

the mac address I am trying to use would look something like this

mac = 01:23:45:67:89:AB,
ip = 192.168.1.177,
unitid = 1000,

as I stated earlier I have taken the code from the pervious post and tried to adopt it to what I need it to do, the main reason I would prefer it to search for the name apposed to the line number is if for some reason the text file get messed up it will still be able to find the mac address and IP.

sorry I missed some of the code, I was trying to get the mac working first then move to the ip address.

#include <SdFat.h>
SdFat sd;
const uint8_t chipSelect = SS;
#define error(s) sd.errorHalt_P(PSTR(s))

void setup() {
  Serial.begin(9600);
  
  // Initialize SdFat or print a detailed error message and halt
  // Use half speed like the native library.
  // change to SPI_FULL_SPEED for more performance.
 if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  const int line_buffer_size = 50;
  char buffer[line_buffer_size];
  const char buffer_mac = 5;
  char buffermac[buffer_mac] = "mac";

  ifstream sdin("CONFIG.TXT");

  Serial.println("... inside the Loop");

  while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount()) 
  {
    if (strcmp(buffermac, buffer ) == 0)
      Serial.print("buffermac");
   Serial.println(buffer);
  
   }
   
  sscanf(buffermac, "%x:%x:%x:%x:%x:%x ", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ); 

sscanf(bufferi, "%u.%u.%u.%u" , &ip[0], &ip[1], &ip[2], &ip[3]);

  Serial.println("Connecting to network");
    Serial.print("Mac: "); 
    Serial.print( mac[0], HEX); 
    Serial.print(":");    
    Serial.print( mac[1], HEX);
    Serial.print(":");    
    Serial.print( mac[2], HEX);
    Serial.print(":");    
    Serial.print( mac[3], HEX);
    Serial.print(":");    
    Serial.print( mac[4], HEX);
    Serial.print(":");    
    Serial.println( mac[5], HEX);
        
    Serial.print("IP: ");
    Serial.print( ip[0]);
    Serial.print(".");    
    Serial.print( ip[1]);
    Serial.print(".");    
    Serial.print( ip[2]);
    Serial.print(".");    
    Serial.println( ip[3]);
  
Ethernet.begin(mac, ip);


void loop() {
  // nothing happens after setup
}

I have updated the code a little bit I hope it makes more sense

#include <SdFat.h>
#include <SdFatUtil.h>
#include <Ethernet.h>
#include <SPI.h>



#define SD_SELECT 4
/************ ETHERNET STUFF ************/
//byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//byte ip[] = { 192, 168, 3, 177 };
EthernetClient client; 
byte mac[6] = {0};
byte ip[4] = {0};
byte st_dns[4] = {0};
byte gateway[4] = {0};
byte subnet[4] = {0};
EthernetServer server(80);

/************ SDCARD STUFF ************/
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
SdFat sd;

// SD chip select pin
const uint8_t chipSelect = 4;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))



void setup() {
  Serial.begin(9600);
  
  // Initialize SdFat or print a detailed error message and halt
  // Use half speed like the native library.
  // change to SPI_FULL_SPEED for more performance.
 if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  const int line_buffer_size = 50;
  char buffer[line_buffer_size];
  const char buffer_mac = 5;
  char buffermac[buffer_mac] = "mac";
   const char buffer_ip = 5;
  char bufferip[buffer_ip] = "";

  ifstream sdin("CONFIG.TXT");

  Serial.println("... inside the Loop");

  while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount()) 
  {
    if (strcmp(buffermac, buffer ) == 0)
      Serial.print("buffermac");
   Serial.println(buffer);
  
   }
   
  sscanf(buffermac, "%x:%x:%x:%x:%x:%x ", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ); 

sscanf(bufferip, "%u.%u.%u.%u" , &ip[0], &ip[1], &ip[2], &ip[3]);

  Serial.println("Connecting to network");
    Serial.print("Mac: "); 
    Serial.print( mac[0], HEX); 
    Serial.print(":");    
    Serial.print( mac[1], HEX);
    Serial.print(":");    
    Serial.print( mac[2], HEX);
    Serial.print(":");    
    Serial.print( mac[3], HEX);
    Serial.print(":");    
    Serial.print( mac[4], HEX);
    Serial.print(":");    
    Serial.println( mac[5], HEX);
        
    Serial.print("IP: ");
    Serial.print( ip[0]);
    Serial.print(".");    
    Serial.print( ip[1]);
    Serial.print(".");    
    Serial.print( ip[2]);
    Serial.print(".");    
    Serial.println( ip[3]);
  
Ethernet.begin(mac, ip);
}

void loop() {
  // nothing happens after setup
}

I assume it isn't working at all - what output do you get? Take a look at strncmp instead of strcmp. That should get you a step closer.

  const char buffer_mac = 5;
  char buffermac[buffer_mac] = "mac";
   const char buffer_ip = 5;
  char bufferip[buffer_ip] = "";

Some consistency would be good. If buffermac holds "mac", then bufferip should hold "ip".

But, none of that is needed.

That code is now going to read every record in the file, and then process the last one (probably empty) as mac and ip data.

You want something more like this:

  char junk[10];
  while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount()) 
  {
     if(strncmp(buffer, "mac", 3) == 0)
     {
        // buffer contains mac values
        sscanf(buffer, "%s=%x:%x:%x:%x:%x:%x", &junk, &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
     }
     else if(strncmp(buffer, "ip", 2) == 0)
     {
        // buffer contains ipvalues
        sscanf(buffer, "%s=%u.%u.%u.%u", &junk, &ip[0], &ip[1], &ip[2], &ip[3]);
     }
     // More record checking/parsing
  }

Scanning the proper buffer is essential (you weren't) as is skipping the data you don't want (you weren't).

thanks for that but I am still at square one it now seems to be processing it but not getting the to mac or ip address all I am get is the standard

unless it is how I have the text in the text file it is currently

mac = 01:23:45:67:89:AB,
ip = 192.168.3.177,
unitid = 1000,

with the comma at the end does that matter ?

... inside the Loop
Connecting to network
Mac: 0:0:0:0:0:0
IP: 0.0.0.0

#include <SdFat.h>
#include <SdFatUtil.h>
#include <Ethernet.h>
#include <SPI.h>



#define SD_SELECT 4
/************ ETHERNET STUFF ************/
//byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//byte ip[] = { 192, 168, 3, 177 };
EthernetClient client; 
byte mac[6] = {0};
byte ip[4] = {0};
byte st_dns[4] = {0};
byte gateway[4] = {0};
byte subnet[4] = {0};
EthernetServer server(80);

/************ SDCARD STUFF ************/
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
SdFat sd;

// SD chip select pin
const uint8_t chipSelect = 4;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))



void setup() {
  Serial.begin(9600);
  
  // Initialize SdFat or print a detailed error message and halt
  // Use half speed like the native library.
  // change to SPI_FULL_SPEED for more performance.
 if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  const int line_buffer_size = 50;
  char buffer[line_buffer_size];
  

  ifstream sdin("CONFIG.TXT");
  
  
  Serial.println("... inside the Loop");

char junk[10];
  while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount()) 
  {
     if(strncmp(buffer, "mac", 3) == 0)
     {
        // buffer contains mac values
        sscanf(buffer, "%s=%x:%x:%x:%x:%x:%x", &junk, &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
     }
     else if(strncmp(buffer, "ip", 2) == 0)
     {
        // buffer contains ipvalues
        sscanf(buffer, "%s=%u.%u.%u.%u", &junk, &ip[0], &ip[1], &ip[2], &ip[3]);
     }
     // More record checking/parsing
  }

  Serial.println("Connecting to network");
    Serial.print("Mac: "); 
    Serial.print( mac[0], HEX); 
    Serial.print(":");    
    Serial.print( mac[1], HEX);
    Serial.print(":");    
    Serial.print( mac[2], HEX);
    Serial.print(":");    
    Serial.print( mac[3], HEX);
    Serial.print(":");    
    Serial.print( mac[4], HEX);
    Serial.print(":");    
    Serial.println( mac[5], HEX);
        
    Serial.print("IP: ");
    Serial.print( ip[0]);
    Serial.print(".");    
    Serial.print( ip[1]);
    Serial.print(".");    
    Serial.print( ip[2]);
    Serial.print(".");    
    Serial.println( ip[3]);
  
Ethernet.begin(mac, ip);
}

void loop() {
  // nothing happens after setup
}

I don't believe the commas matter, but they don't seem to serve any useful purpose either, so why not get rid of them? I suspect the real culprit is the whitespace around the = sign. Either tweak your sscanf format or drop those spaces from the file on the SD card.

Add some Serial.print() statements, to confirm what is read from the SD card. Confirm that the code indeed determines that the record is a mac line (or an IP line). What is in junk, after the sscanf?

Almost their I can see the light :slight_smile:

you where right it was a combination of a few things I have got it now returning the values

... inside the Loop
Mac Address Print Out = mac=D1:23:45:67:89:AB
IP Address Print Out = ip=192.168.3.177
Connecting to network
Mac: D1:23:45:67:89:AB
IP: 192.168.3.177
IP Address Set = 192.168.3.177

the only issues I have now is at the end when I use the command to start the

Ethernet.begin(mac, ip); for some reason the mac address does not work any idea?

#include <SdFat.h>
#include <SdFatUtil.h>
#include <Ethernet.h>
#include <SPI.h>

#define SD_SELECT 4
#define ETHERNET_SELECT 10

/************ ETHERNET STUFF ************/
//byte macz[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//byte ip[] = { 192, 168, 3, 177 };
EthernetClient client; 
byte mac[6] = {0};
byte ip[4] = {0};
byte st_dns[4] = {0};
byte gateway[4] = {0};
byte subnet[4] = {0};
EthernetServer server(80);

/************ SDCARD STUFF ************/
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
SdFat sd;

// SD chip select pin
const uint8_t chipSelect = 4;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))



void setup() {
  Serial.begin(9600);
  
    pinMode(SD_SELECT, OUTPUT);
  digitalWrite(SD_SELECT, HIGH); // disable SD card
  
  pinMode(ETHERNET_SELECT, OUTPUT);
  digitalWrite(ETHERNET_SELECT, HIGH); // disable Ethernet
  
  // Initialize SdFat or print a detailed error message and halt
  // Use half speed like the native library.
  // change to SPI_FULL_SPEED for more performance.
 if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  const int line_buffer_size = 50;
  char buffer[line_buffer_size];
  

  ifstream sdin("CONFIG.TXT");
  
  
  Serial.println("... inside the Loop");


  while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount()) 
  {
     if(strncmp(buffer, "mac", 3) == 0)
     { Serial.print("Mac Address Print Out = "); 
       Serial.println(buffer);
     // buffer contains mac values
        sscanf(buffer, "mac=%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
     }
     else if(strncmp(buffer, "ip", 2) == 0)
     { 
       Serial.print("IP Address Print Out = "); 
       Serial.println(buffer);
        // buffer contains ipvalues
        sscanf(buffer, "ip = %u.%u.%u.%u", &ip[0], &ip[1], &ip[2], &ip[3]);
     }
     // More record checking/parsing
  }

  Serial.println("Connecting to network");
    Serial.print("Mac: "); 
    Serial.print( mac[0], HEX); 
    Serial.print(":");    
    Serial.print( mac[1], HEX);
    Serial.print(":");    
    Serial.print( mac[2], HEX);
    Serial.print(":");    
    Serial.print( mac[3], HEX);
    Serial.print(":");    
    Serial.print( mac[4], HEX);
    Serial.print(":");    
    Serial.println( mac[5], HEX);
        
    Serial.print("IP: ");
    Serial.print( ip[0]);
    Serial.print(".");    
    Serial.print( ip[1]);
    Serial.print(".");    
    Serial.print( ip[2]);
    Serial.print(".");    
    Serial.println( ip[3]);
  
Ethernet.begin(mac, ip);
Serial.print("IP Address Set = "); 
Serial.println(Ethernet.localIP());

  delay(1000); 
}

void loop() {
  // nothing happens after setup
}

he only issues I have now is at the end when I use the command to start the

Ethernet.begin(mac, ip); for some reason the mac address does not work any idea?

Define "does not work". There is nothing after the Ethernet.begin() call except for the print statements and a useless delay().

Does not work meaning it would not respond to a ping.

but all ended up I figured it out it was the MAC address I was using in the text file I have changed it to DE:AD:BE:EF:FE:ED and we are in business :slight_smile:

... inside the Loop
Mac Address Print Out = mac=DE:AD:BE:EF:FE:ED
IP Address Print Out = ip=192.168.3.177
Connecting to network
Mac: DE:AD:BE:EF:FE:ED
IP: 192.168.3.177
IP Address Set = 192.168.3.177

Paul, I have to say thank you so much for you assistance you are an absolute life saver :slight_smile: and I think I may I have one hair still left on my head. :slight_smile:

on a separate note I have a completely separate issue that if you would be able to offer any assistance it would be great. thanks once again .
http://arduino.cc/forum/index.php/topic,148831.0.html

okay I though I was done but it looks like I have one more issue with the setting file it when I try and get the unitID it retrieves it in the buffer but does not display it correctly as a byte it is meant to be 1000 no idea how come it is 232

... inside the Loop
Mac Address Print Out = mac=DE:AD:BE:EF:FE:ED
IP Address Print Out = ip=192.168.3.177
Unitid Address Print Out = unitid=1000
Connecting to network
Mac: DE:AD:BE:EF:FE:ED
IP: 192.168.3.177
Unitid: 232
IP Address Set = 192.168.3.177

the only thing I have added was

byte unitid[1] = {0};

      else if(strncmp(buffer, "unitid", 6) == 0)
     { 
       Serial.print("Unitid Address Print Out = "); 
       Serial.println(buffer);
        // buffer contains ipvalues
        sscanf(buffer, "unitid = %u", &unitid[1]);
     }

    Serial.print("Unitid: "); 
    Serial.println( unitid[1]);
    Serial.print("Unitid: "); 
    Serial.println( unitid[1]);
#include <SdFat.h>
#include <SdFatUtil.h>
#include <Ethernet.h>
#include <SPI.h>

#define SD_SELECT 4
#define ETHERNET_SELECT 10

/************ ETHERNET STUFF ************/
//byte macz[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//byte ip[] = { 192, 168, 3, 177 };
EthernetClient client; 
byte mac[6] = {0};
byte ip[4] = {0};
byte st_dns[4] = {0};
byte gateway[4] = {0};
byte subnet[4] = {0};
byte unitid[1] = {0};
EthernetServer server(80);

/************ SDCARD STUFF ************/
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
SdFat sd;

// SD chip select pin
const uint8_t chipSelect = 4;

// store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))



void setup() {
  Serial.begin(9600);
  
    pinMode(SD_SELECT, OUTPUT);
  digitalWrite(SD_SELECT, HIGH); // disable SD card
  
  pinMode(ETHERNET_SELECT, OUTPUT);
  digitalWrite(ETHERNET_SELECT, HIGH); // disable Ethernet
  
  // Initialize SdFat or print a detailed error message and halt
  // Use half speed like the native library.
  // change to SPI_FULL_SPEED for more performance.
 if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  const int line_buffer_size = 50;
  char buffer[line_buffer_size];
  
// *******************************Configuration file setting************************************************************
//must be stored in root and like eg.
//mac=DE:AD:BE:EF:FE:ED  
//ip=192.168.3.177
//unitid=1000
//

  ifstream sdin("CONFIG.TXT");
  
  
  Serial.println("... inside the Loop");


  while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount()) 
  {
     if(strncmp(buffer, "mac", 3) == 0)
     { Serial.print("Mac Address Print Out = "); 
       Serial.println(buffer);
     // buffer contains mac values
        sscanf(buffer, "mac=%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
     }
     else if(strncmp(buffer, "ip", 2) == 0)
     { 
       Serial.print("IP Address Print Out = "); 
       Serial.println(buffer);
        // buffer contains ipvalues
        sscanf(buffer, "ip = %u.%u.%u.%u", &ip[0], &ip[1], &ip[2], &ip[3]);
     }
       else if(strncmp(buffer, "unitid", 6) == 0)
     { 
       Serial.print("Unitid Address Print Out = "); 
       Serial.println(buffer);
        // buffer contains ipvalues
        sscanf(buffer, "unitid = %u", &unitid[1]);
     }
     // More record checking/parsing
  }
// ******************************Pint out Setting************************************************************
  Serial.println("Connecting to network");
    Serial.print("Mac: "); 
    Serial.print( mac[0], HEX); 
    Serial.print(":");    
    Serial.print( mac[1], HEX);
    Serial.print(":");    
    Serial.print( mac[2], HEX);
    Serial.print(":");    
    Serial.print( mac[3], HEX);
    Serial.print(":");    
    Serial.print( mac[4], HEX);
    Serial.print(":");    
    Serial.println( mac[5], HEX);
        
    Serial.print("IP: ");
    Serial.print( ip[0]);
    Serial.print(".");    
    Serial.print( ip[1]);
    Serial.print(".");    
    Serial.print( ip[2]);
    Serial.print(".");    
    Serial.println( ip[3]);
    
    Serial.print("Unitid: "); 
    Serial.println( unitid[1]);
    
    
Ethernet.begin(mac, ip);
Serial.print("IP Address Set = "); 
Serial.println(Ethernet.localIP());

  delay(1000); 
}

void loop() {
  // nothing happens after setup
}

Unless the mac address you were using is that of another device on the same network, it shouldn't stop you from pinging it. Not that I care what mac address you use, but, it should have worked as long as it was unique.

that what I would have thought but I think it must have been conflicting with something else but hey it all good now :slight_smile:

with the unit id issue does it have anything to do with the %u I have tried to other thing such as %d and still the same result.

sscanf(buffer, "unitid=%u", &unitid[1]);

or is it more to do with the
byte unitid[1] = {0};
should this be something different not a byte?

The type is fine. The size of the array is 1. That means the valid indices are in the range 0 to 0. Notice that 1 is not in that range.

I get that now that 1 is not their so I have change it

but still this is still giving me the 232

... inside the Loop
Mac Address Print Out = mac=DE:AD:BE:EF:FE:ED
IP Address Print Out = ip=192.168.3.177
Unitid Address Print Out = unitid=1000
Connecting to network
Mac: DE:AD:BE:EF:FE:ED
IP: 192.168.3.177
Unitid: 232
IP Address Set = 192.168.3.177

byte unitid[1] = {0};

sscanf(buffer, "unitid=%u", &unitid[0]);

Serial.println( unitid[0]);

A value of 1000 will not fit in a byte. You need an int. I hadn't gone back to look at the size of the value you were trying to store in unitid.