Go Down

Topic: How to read variables stored on an SDCard? (Read 2 times) previous topic - next topic

Onenate

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.

http://arduino.cc/forum/index.php?topic=68373.0

I have been able to get the INIFile. library working the way I need it to from Steve Marple  https://github.com/stevemarple/IniFile 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 .


PaulS

Quote
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.

Quote
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.

Onenate

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. 

Code: [Select]
 
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] );

PaulS

Code: [Select]
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?

Code: [Select]
  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.

Code: [Select]
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.

Onenate

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.

Code: [Select]
#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
}
 

Onenate

I have updated the code a little bit I hope it makes more sense
Code: [Select]
#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
}


 


wildbill

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.

PaulS

Code: [Select]
  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:
Code: [Select]
  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).

Onenate

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
Code: [Select]
#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
}





wildbill

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.

PaulS

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?

Onenate

Almost their I can see the light  :)

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?

Code: [Select]
#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
}


 


PaulS

Quote
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().

Onenate

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 :)

... 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 :) and I think I may I have one hair still left on my head. :)

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

Onenate

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
 
Code: [Select]

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]);
   
Code: [Select]
#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
}


 

Go Up