SDConfigFile library for reading sketch settings from an SD card

I recently finished an open source library to read sketch settings from an SD configuration file. I use the library instead of re-downloding the sketch every time some simple setting changes.

I can put a file on my SD card containing lines like

ssid=wickedOz
password=flyingMonkeys

then my sketch can read those settings using the library. The library lets me write sketches that can be reconfigured without reprogramming. For example, to switch to a new Wifi hotspot, I just use my PC to edit the configuration file, put the SD card back in my project, and off it goes.

I'm using the library in my Robotic Glockenspiel project, to give the URL of the glockenspiel playlist:

playlist=file://playlist.m3u

or eventually:

playlist=http://www.needhamia.com/glockenspiel/carols.m3u

See the SDConfigFile git project at GitHub - bneedhamia/sdconfigfile: Arduino Library to read an SD Configuration File The project includes a simple example.

Enjoy,
Brad

hello
i have seen your library
the things are that i cannot understand properly the way it works
is there any way that you can sample an mac and ip in the config.txt in order to connect it a w5100 shield?
thank you

I use the SD to store network settings. Here is a link to the post that explains how.
http://forum.arduino.cc/index.php?topic=128763.msg976118#msg976118

hi,
is not working with ide 1.6
i have tried to fix it but i have got mac address 0:0:0:0:0
ip address 0.0.0.0

is not working with ide 1.6

You could not possibly be more vague. Where does it not work (fail)? What are the messages on the serial monitor?

network_sdcard.ino: In function 'void setup()':
network_sdcard.ino:123:1: error: unable to find a register to spill in class 'NO_REGS'
network_sdcard.ino:123:1: error: this is the insn:
(insn 160 157 163 7 (set (mem:QI (post_dec:HI (reg/f:HI 32 SP_L)) [0 S1 A8])
(subreg:QI (reg/f:HI 183) 1)) network_sdcard.ino:79 1 {pushqi1}
(expr_list:REG_ARGS_SIZE (const_int 1 [0x1])
(nil)))
network_sdcard.ino:123: confused by earlier errors, bailing out
Error compiling.
This is the error i have got

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

If i modifying it like:
Serial.print("mac ");
sscanf(netBuffer,"%2x:%2x:%2x:%2x:%2x:%2x",myMac[0],myMac[1],myMac[2],myMac[3],myMac[4],myMac[5]);
break;
So removing the & will compile it but the output will be 0:0:0:0:0:0
Regards

On IDE v1.6.0 (and all 1.5.x versions), I get an internal compiler error segmentation fault. With IDE v1.0.6, it compiles fine. It is caused by the sscanf calls.

Is there any fix for it?

Compile it with IDE v1.0.6.

I'll wait to see Brad's library in action

In the event you didn't see Brad's library in action, I modified my sketch to compile on IDE v1.6.x.

This is the contents of network.txt. It is the mac, ip, netmask, gateway, and dns in that order, each on its own line.

DE:AD:BE:EF:FE:ED
192.168.2.2
255.255.255.0
192.168.2.1
1.2.3.4

Here is the sketch.

#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(115200);  

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

  delay(2000);
  
  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 == '\n') {
      chPos = 0;

      switch(lineNo) {
        case 0:
          if(getMAC(netBuffer,myMac)) Serial.println(F("mac ok"));
          break;

        case 1:
          if(getIP(netBuffer,myIP)) Serial.println(F("ip ok"));
          break;

        case 2:
          if(getIP(netBuffer,myNM)) Serial.println(F("netmask ok"));
          break;

        case 3:
          if(getIP(netBuffer,myGW)) Serial.println(F("gateway ok"));
          break;

        case 4:
          if(getIP(netBuffer,myDNS)) Serial.println(F("dns ok"));
          break;
      }

      lineNo++;
    }
    else if(ch == '\r') {
      // 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);
  
  Serial.println(Ethernet.localIP());
}

void loop() {
}

byte getMAC(char* macBuf, byte* thisMAC) {
  byte thisLen = strlen(macBuf);
  byte thisOctet = 1;

  thisMAC[0] = strtol(&macBuf[0],NULL,16);
  
  for(int x = 0; x<thisLen; x++) {
      if(macBuf[x] == ':') {
        thisMAC[thisOctet] = strtol(&macBuf[x+1],NULL,16);
        thisOctet++;
      }
  }

  if(thisOctet == 6) return(1);
  else return(0);
  
}

byte getIP(char* ipBuf, byte* thisIP) {
  byte thisLen = strlen(ipBuf);
  byte thisOctet = 1;

  thisIP[0] = atoi(&ipBuf[0]);
  
  for(int x = 0; x<thisLen; x++) {
      if(ipBuf[x] == '.') {
        thisIP[thisOctet] = atoi(&ipBuf[x+1]);
        thisOctet++;
      }
  }

  if(thisOctet == 4) return(1);
  else return(0);
}

Do you need a separate library? Basic SD card file reads together with a simple string parsing procedure (assuming that you are reading line input) can solve this problem. I use a procedure named ENDF (ExtractNextDelimitedField) to parse text lines that I read from files.

I note that you still have to remove the SD card and edit your config files on a PC. I guess that means you have to have physical contact with your Arduino system. You might as well made a code change and download an updates sketch.

I have built file upload and download functionality into my Arduino system. So I can and do upload my system's configuration files from remote locations while the application is running. For some files my system will pick up file changed content automatically. For others I would still have to restart the system because the files are only processed in the setup() procedure in the current code.

All of my application's source code is published on its website at http://www.2wg.co.nz within the public folder on the SD card. Note that you would need an Arduino processor with 8KB of RAM to implement SD card file uploads through a web page upload.

Cheers

Catweazle NZ

its done now
i use eeprom for that :slight_smile:
thank you