Pages: 1 [2]   Go Down
Author Topic: Can SD Card be used to store ip address/MAC configs?  (Read 4064 times)
0 Members and 1 Guest are viewing this topic.
Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48556
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Anyway when you said
Somebody screwed up my post. I couldn't have mangled it that bad. Could I? I meant that you don't need the memset stuff.

In C, a string is a NULL terminated array of characters. Think of the NULL like a stop sign. Clearly, you don't need 14 stop signs, as memset puts in place, when 1 will do.

Code:
name[0] = '\0';
value[0] = '\0';
Does what memset does, in a way that C/C++ programmers would.

Quote
Most of the Serial print statements are just a means of debugging the sketch to see what's going wrong at certain steps.  As you can see from my Serial Monitor output I finally got the sketch to open and read the text file.
Certainly. But, in the Serial Monitor, which makes more sense?
Quote
ip[0] = [145]
or
Quote
145

It takes very little extra effort to produce the first output over what it takes to produce the second output, and the dividends are obvious. At least to me they are. I suspect that you will come around, in time.

In order to read the SD card correctly, you need to know what is on it. Perhaps you do, but you haven't shared that with us. So, it's hard to pick out where the code is not doing what you want. If you share the contents of the file with us, and do a little better job with the serial output, I think that we can quickly come up with a way that lets you read the file correctly.
Logged

Vancouver Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No worries about the typos.  That is'nt why I couldn't understand what you were saying. It was just my ignorance of C.  Besides my entries are full of typos and spelling miktahes so I can complain about that. (LoL  I wasn't faking that.  Thats how 'mistakes' actually came out).
  
Burried somewhere in this thread is the contents of "params.txt".  For the ease of everyone I should have restated it. Here's the contents of "params.txt":


ip0:192,ip1:168,ip2:1,ip3:200,


Thanks
Logged

Tasmania - Australia
Offline Offline
Sr. Member
****
Karma: 14
Posts: 307
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Paul for your input and help with assisting mfriesen.
Unfortunately I am unable at this moment able spend time due to my schedule, but will keep an eye on this thread in case of anything specific.
But it seems you are almost there.

Paul
Logged


Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48556
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Have you made the changes that I suggested, to better format what is being printed? I don't see much wrong with the code.

There is one call to file.available() and then any number of calls to file.read(), where the number of calls may exceed the number of characters actually in the file.

But, I don't see that as causing your particular issue. It is important, then, to know, when 192 is printed three times, for instance, which of the 4 Serial.print() calls is causing that to happen. Only one, as I see it, should. But, that's why there are debugging tools and techniques.
Logged

Vancouver Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I made the changes to clean up/make  more meaningful Debug printouts.  It really helped me trouble shoot the code.  I finally figured it out.  The "strcmp" function returns a "0" when the strings are the same.  Hence I needed a "!" in the code to make the load work.  Here's my final code. Unfortunately I saved the code after I cleaned up the sketch by stipping out most of the dedeug printlines.  It's too bad  because if anyone was following this, the debug lines might have been nice to see.  
Code:
#include <SD.h>
 #include <SPI.h>
 #include <Ethernet.h>
 int i = 0;
 int j = 0; // array pointer:
 char chtr;        // variable to hold value from file:
 char name[4];        // array for name data:
 char value[8];
  
  byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
  byte ip[]    = {10, 0, 0, 59};
 // set up variables using the SD utility library functions:
 Sd2Card card;
 int SD_CS = 4;  


 void setup() {
  
   Serial.begin(9600);
 

   // disable w5100 SPI while setting up SD
  
   digitalWrite(10,HIGH);  // Disabled

   Serial.print("Starting SD...");
   pinMode(10,OUTPUT);
   if(!SD.begin(4)) Serial.println("SD failed to start");
   else Serial.println("ok");
   // SD.begin() returns with its SPI disabled. Good SD library!
   if (!card.init(SPI_HALF_SPEED, SD_CS)) {
     Serial.println("Initialization Failed.");
  
   } else {
    Serial.println("Wiring is correct and a card is present.");
  }
  
 
   delay (2000);

   Serial.print("Starting w5100...");
   Serial.println();
  
   readFile();
      
   Ethernet.begin(mac, ip);
   Serial.println();
   Serial.print("Arduino set IP to ");
   Serial.println();
   Serial.println(Ethernet.localIP());

    
   // rest of your setup
}

void loop(){}


void readFile() {
                        
File file;
        
file=SD.open("params.txt");
if (file) {
// array for value data:

while (file.available()) { // read the settings file:
i = 0;
boolean paramEnd = false;
                        
while (!paramEnd) { // while not at the end of the parameter keep reading:
chtr = file.read();
if (chtr != ':') { // if the char from file is not a':' read it in:
name[i] = chtr;
i++;
                              
                              
                              
} else {
                              
 paramEnd = true;               // otherwise we have come to the end of our parmeter name:
                                  
                                                                
}
}
j = 0;
                         boolean valueEnd = false;
                         value[0] = '\0';                               // reset our array pointer:
while (!valueEnd) {
chtr = file.read();
if (chtr != ',') { // if the char from file is not a ',' read it in:
value[j] = chtr;
j++;
                              
} else {
      valueEnd = true; // otherwise we have come to the end of our value:
                              
                                                          
}
}

  
if (!strcmp(name, "ip0")) {
ip[0] = atoi(value); // assign value to ip0 first ip octet:
                        
}
if (!strcmp(name, "ip1")) {
ip[1] = atoi(value); // assign value to ip1 first ip octet:
                        
}
if (!strcmp(name, "ip2")) {
ip[2] = atoi(value); // assign value to ip2 first ip octet:
                        
}
if (!strcmp(name, "ip3")) {
ip[3] = atoi(value); // assign value to ip4 first ip octet:
                        


}
}
}
}

 

Thanks for all of your help.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48556
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The "strcmp" function returns a "0" when the strings are the same.  Hence I needed a "!" in the code to make the load work.
That's why I always use an explicit comparison.

Code:
     if (strcmp(name, "ip0") == 0) {

Great job of finding the problem. I completely missed that point.
Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 140
Posts: 5873
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Why don't you store all the network settings? I used this for the contents of a file named "network.txt". The mac must be the first line, followed by ip, netmask, gateway, and dns in that order. Each on their own line.
Code:
12:34:56:78:90:AB
192.168.2.2
255.255.255.0
192.168.2.1
192.168.2.1

Then I used this sketch:
Code:
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>

byte myMac[6];
byte myIP[4];
byte myNM[4];
byte myGW[4];
byte myDNS[4];

void setup() {
  Serial.begin(9600);  

  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);

  if(!SD.begin(4)) Serial.println("SD fail");
  else Serial.println("SD ok");

  File fh = SD.open("network.txt",FILE_READ);
  char netBuffer[32];
  
  if(!fh)
  {
    Serial.println("SD open fail");
    return;    
  }

  int chPos = 0;
  int lineNo = 0;
  
  while(fh.available())
  {
    char ch = fh.read();
    if(ch == '\r') {
      chPos = 0;

      switch(lineNo) {
        case 0:
//          Serial.print("mac ");        
  sscanf(netBuffer,"%2x:%2x:%2x:%2x:%2x:%2x",&myMac[0],&myMac[1],&myMac[2],&myMac[3],&myMac[4],&myMac[5]);  
        break;

        case 1:
//          Serial.print("ip ");        
  sscanf(netBuffer,"%u.%u.%u.%u",&myIP[0],&myIP[1],&myIP[2],&myIP[3]);  
        break;

        case 2:
//          Serial.print("netmask ");        
  sscanf(netBuffer,"%u.%u.%u.%u",&myNM[0],&myNM[1],&myNM[2],&myNM[3]);  
        break;

        case 3:
//          Serial.print("gateway ");        
  sscanf(netBuffer,"%u.%u.%u.%u",&myGW[0],&myGW[1],&myGW[2],&myGW[3]);  
        break;

        case 4:
//          Serial.print("dns ");        
  sscanf(netBuffer,"%u.%u.%u.%u",&myDNS[0],&myDNS[1],&myDNS[2],&myDNS[3]);  
        break;
      }

//      Serial.println(netBuffer);
      lineNo++;
    }
    else if(ch == '\n') {
      // do nothing
    }
    else if(chPos < 31) {
      netBuffer[chPos] = ch;
       chPos++;
      netBuffer[chPos] = 0;
    }
  }
  
  fh.close();

  int x;
  
  Serial.print("\r\nmac ");
  for(x=0;x<6;x++) {
    Serial.print(myMac[x],HEX);
    if(x<5) Serial.print(":");
  }

  Serial.print("\r\nip ");
  for(x=0;x<4;x++) {
    Serial.print(myIP[x],DEC);
    if(x<3) Serial.print(".");
  }

  Serial.print("\r\nnetmask ");
  for(x=0;x<4;x++) {
    Serial.print(myNM[x],DEC);
    if(x<3) Serial.print(".");
  }

  Serial.print("\r\ngateway ");
  for(x=0;x<4;x++) {
    Serial.print(myGW[x],DEC);
    if(x<3) Serial.print(".");
  }

  Serial.print("\r\ndns ");
  for(x=0;x<4;x++) {
    Serial.print(myDNS[x],DEC);
    if(x<3) Serial.print(".");
  }

  Serial.println("\r\nStarting ethernet");
  Ethernet.begin(myMac,myIP,myDNS,myGW,myNM);
  digitalWrite(10,HIGH);
  
  Serial.println(Ethernet.localIP());
}

void loop() {
}
I commented out some of the serial debugging stuff. You can use it to debug your text file.

edit: Removed the double post. My bad.
« Last Edit: October 29, 2012, 04:05:33 pm by SurferTim » Logged

Vancouver Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This looks good.  While both yours and mine work 'stand alone'  as soon as I try to merge either one with my sketch which calls up some Telnet configurations, the SD Card read fails.  I 'fooled' around with different sketchs, but I'm having little to no progress with any of them.  I'm not the type of guy that quits, but I think I'll investigate the suggestion earlier on in this thread to set the variables in EEPROM.  Eventually I'll make this work, but I have to move on.

Thanks
Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 140
Posts: 5873
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
While both yours and mine work 'stand alone'  as soon as I try to merge either one with my sketch which calls up some Telnet configurations, the SD Card read fails.
Are you using an Uno or a Mega? You may be running out of SRAM when you merge the sketches with that telnet code.

edit: According to fat16lib, you can open as many SD files as you want now, but at the cost of 500 bytes SRAM per open file.
« Last Edit: October 30, 2012, 09:01:38 am by SurferTim » Logged

Vancouver Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm using an Uno.  I'm only trying to open the one file, "params.txt" or as in the later method, "Network.txt".  Neither is more than 1k. 

How can I tell how much SRAM I am using.  Is it the 'file' size reported at the load to the Uno from IDE?

Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 140
Posts: 5873
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The reported size by the compiler is the program memory, not SRAM. The Uno has only 2K, and the Mega has 8K. The SD.open() function requires a 500 byte buffer, even if the file is only 20 bytes. That is a quarter of your SRAM to open that file.

There is a MemoryFree library function in the playground.
http://www.arduino.cc/playground/Code/AvailableMemory

edit:I think I used the one from github.
https://github.com/homecontrol/Arduino-MemoryFree

If you have questions about that, fat16lib hangs around the "Storage" section of the forum. He is the guy to ask.
« Last Edit: October 31, 2012, 07:31:00 am by SurferTim » Logged

Pages: 1 [2]   Go Up
Jump to: