0

Arduino Ethernet shield with SD card - File hosting?
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Arduino Ethernet shield with SD card - File hosting?

by Nate Strech on Wed Aug 11, 2010 7:21 pm

I’m a bit confused by this new shield – the updated documentation states:

“The latest revision of the shield adds a micro-SD card slot, which can be used to store files for serving over the network.”

Then it also states:

“Note that because the W5100 and SD card share the SPI bus, only one can be active at a time.”

Is it really possible to pull files from the SD card over the Ethernet? If so could a client/broswer pull a file using the following format: http://10.10.10.1/file-to-snag.txt?

Thanks!
Nate
Last edited by Nate Strech on Tue Aug 24, 2010 12:39 pm, edited 1 time in total.
Nate Strech
 
Posts: 10
Joined: Wed Aug 11, 2010 7:19 pm
Location: Chicago

Re: Arduino Ethernet shield with SD card - File hosting?

by adafruit on Wed Aug 11, 2010 7:41 pm

the description is technically confusing but basically what it means is - you have to interleave SD card access and ethernet access. it just means its not super fast, not that you can't essentially do both at the same time

note that there is no precise example code to do what you want (yet)

adafruit
 
Posts: 12149
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: Arduino Ethernet shield with SD card - File hosting?

by jonbaer on Sun Aug 22, 2010 5:53 pm

Hi,

I just got this card and trying to figure out what the preferred lib is to use for SD IO, I came across this one ...

http://code.google.com/p/sdfatlib/

But after running a few tests they seem to bail out ...

Free RAM: 1261
error: card.init failed!
SD error: 1,0

Is this something more specific to be using?

Thanks.
jonbaer
 
Posts: 2
Joined: Fri May 07, 2010 9:45 pm

Re: Arduino Ethernet shield with SD card - File hosting?

by Nate Strech on Tue Aug 24, 2010 3:39 pm

Hi jonbaer,

I had the same issue but I just figured it out…

BACKGROUND:

SPI is a protocol designed for communicating between two devices. You can read more about it on Wikipedia; but for our purposes it's important to know that there are four signals used in SPI: MOSI, MISO, SCK and CS (or SS). These signals are defined in a FAT library and associated with a specific pin. On Arduino, the default pins are D10 (CS), D11, (MOSI), D12 (MISO) and D13 (SCK).

(source: http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=172)

So a basic Ethernet Shield will use the SS pin 10 to select the Wiznet W5100 Ethernet chip. It also looks like most Data Logging shields also use the same SS pin 10 to access the SC card.

RESOLUTION:

Seeing that this new shield has both - pin 10 is for the W5100 and pin 4 is for the SD card. You’ll have to make a small code change in the SDFATLIB.

I’m currently using this version: sdfatlib20100818

Open the file called ‘Sd2PinMap.h’ and drop down to line 279. Change the SS_PIN value to 4.

Code: Select all | TOGGLE FULL SIZE
#else  // defined(__AVR_ATmega1280__)
// 168 and 328 Arduinos

// Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 18;
uint8_t const SCL_PIN = 19;

// SPI port
// uint8_t const SS_PIN = 10;
uint8_t const SS_PIN = 4 ;  //THIS LINE
uint8_t const MOSI_PIN = 11;
uint8_t const MISO_PIN = 12;
uint8_t const SCK_PIN = 13;


Now that my SD card is working I’ll still have to see if will play nicely with the Ethernet chip.

This looks promising… http://www.webweavertech.com/ovidiu/weblog/archives/000476.html

Cheers,
Nate
Nate Strech
 
Posts: 10
Joined: Wed Aug 11, 2010 7:19 pm
Location: Chicago

Re: Arduino Ethernet shield with SD card - File hosting?

by fat16lib on Wed Aug 25, 2010 7:03 pm

To change the chip select pin for the SD please do not edit Sd2PinMap.h. This may cause problems since it changes both the value of SS and SD chip select. These are different pins on the Ethernet Shield.

The SparkFun documentation is not correct for the current version of SdFat. SS, pin 10, will be set as an output independent of the pin used for SD chip select.

Either use init with two arguments
Code: Select all | TOGGLE FULL SIZE
uint8_t Sd2Card:init(uint8_t sckRateID, uint8_t chipSelectPin);


For the ethernet SD the call would be something like
Code: Select all | TOGGLE FULL SIZE
 card.init(SPI_FULL_SPEED, 4)



You can also edit Sd2Card.h at line 60 and change the default SD chip select.

Original:
Code: Select all | TOGGLE FULL SIZE
uint8_t const  SD_CHIP_SELECT_PIN = SS_PIN;

New default pin 4:
Code: Select all | TOGGLE FULL SIZE
uint8_t const  SD_CHIP_SELECT_PIN = 4;
fat16lib
 
Posts: 593
Joined: Wed Dec 24, 2008 1:54 pm

Re: Arduino Ethernet shield with SD card - File hosting?

by adafruit on Thu Aug 26, 2010 1:22 am

We have a full tutorial here
http://www.ladyada.net/learn/arduino/ethfiles.html

make sure to delete your old version of SDfatlib completely before reinstalling!!

adafruit
 
Posts: 12149
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: Arduino Ethernet shield with SD card - File hosting?

by Nate Strech on Thu Aug 26, 2010 9:05 am

Fat16lib & Adafruit – Excellent information!

I could have really used this new tutorial three days ago :)

You’ve answered my original question about hosting files in the format of: http://10.10.10.1/file-to-snag.txt

I went about it a slightly different way and managed to complete my Cisco IP Phone project: http://www.youtube.com/watch?v=LnTGZVIdx38

Thanks for staying on top of this forum – I wouldn’t get very far without it!
Nate Strech
 
Posts: 10
Joined: Wed Aug 11, 2010 7:19 pm
Location: Chicago

Re: Arduino Ethernet shield with SD card - File hosting?

by adafruit on Thu Aug 26, 2010 10:32 am

ahhh...we only wrote it 12 hours ago - in response to your posts :)

adafruit
 
Posts: 12149
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: Arduino Ethernet shield with SD card - File hosting?

by Andyx on Mon Aug 30, 2010 5:05 pm

Good job on the tutorial.

Here is a version of the web server sketch turning it into a little more or less of a server.

It adds support for a root file name and jpeg and gif image content types to the server.

It also corrects a minor problem in the SD byte reading loop that affected image content types.

Code: Select all | TOGGLE FULL SIZE
/*
 * Web Server
 *
 * A simple web server that shows the value of the analog input pins.
 */

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 177 };
char rootFileName[] = "index.htm";
Server server(80);

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

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

void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

void setup() {
  Serial.begin(9600);
 
  PgmPrint("Free RAM: ");
  Serial.println(FreeRam()); 
 
  // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  // breadboards.  use SPI_FULL_SPEED for better performance.
  pinMode(10, OUTPUT);                       // set the SS pin as an output (necessary!)
  digitalWrite(10, HIGH);                    // but turn off the W5100 chip!

  if (!card.init(SPI_HALF_SPEED, 4)) error("card.init failed!");
 
  // initialize a FAT volume
  if (!volume.init(&card)) error("vol.init failed!");

  PgmPrint("Volume is FAT");
  Serial.println(volume.fatType(),DEC);
  Serial.println();
 
  if (!root.openRoot(&volume)) error("openRoot failed");

  // list file in root with date and size
  PgmPrintln("Files found in root:");
  root.ls(LS_DATE | LS_SIZE);
  Serial.println();
 
  // Recursive list of all directories
  PgmPrintln("Files found in all dirs:");
  root.ls(LS_R);
 
  Serial.println();
  PgmPrintln("Done");
 
  // Debugging complete, we start the server!
  Ethernet.begin(mac, ip);
  server.begin();
}

// How big our line buffer should be. 100 is plenty!
#define BUFSIZ 100

void loop()
{
  char clientline[BUFSIZ];
  char *filename;
  int index = 0;
  int image = 0;
 
  Client client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean current_line_is_blank = true;
   
    // reset the input buffer
    index = 0;
   
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
       
        // If it isn't a new line, add the character to the buffer
        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          // are we too big for the buffer? start tossing out data
          if (index >= BUFSIZ)
            index = BUFSIZ -1;
         
          // continue to read more data!
          continue;
        }
       
        // got a \n or \r new line, which means the string is done
        clientline[index] = 0;
        filename = 0;
       
        // Print it out for debugging
        Serial.println(clientline);
       
        // Look for substring such as a request to get the root file
        if (strstr(clientline, "GET / ") != 0) {
          filename = rootFileName;
        }
        if (strstr(clientline, "GET /") != 0) {
          // this time no space after the /, so a sub-file
         
          if (!filename) filename = clientline + 5; // look after the "GET /" (5 chars)
          // a little trick, look for the " HTTP/1.1" string and
          // turn the first character of the substring into a 0 to clear it out.
          (strstr(clientline, " HTTP"))[0] = 0;
         
          // print the file we want
          Serial.println(filename);

          if (! file.open(&root, filename, O_READ)) {
            client.println("HTTP/1.1 404 Not Found");
            client.println("Content-Type: text/html");
            client.println();
            client.println("<h2>File Not Found!</h2>");
            break;
          }
         
          Serial.println("Opened!");
         
          client.println("HTTP/1.1 200 OK");
          if (strstr(filename, ".htm") != 0)
             client.println("Content-Type: text/html");
          else if (strstr(filename, ".jpg") != 0)
             client.println("Content-Type: image/jpeg");
         else if (strstr(filename, ".gif") != 0)
             client.println("Content-Type: image/gif");
         else
             client.println("Content-Type: text");

          client.println();
               
          int16_t c;
          while ((c = file.read()) >= 0) {
              // uncomment the serial to debug (slow!)
              //Serial.print((char)c);
              client.print((char)c);
          }
          file.close();
        } else {
          // everything else is a 404
          client.println("HTTP/1.1 404 Not Found");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<h2>File Not Found!</h2>");
        }
        break;
      }
    }
    // give the web browser time to receive the data
    delay(1);
    client.stop();
  }
}
What is better than an Arduino? An Arduino with a laser!

Andyx
 
Posts: 40
Joined: Tue Aug 03, 2010 5:55 pm
Location: Dania Beach, Florida

Re: Arduino Ethernet shield with SD card - File hosting?

by adafruit on Mon Aug 30, 2010 5:22 pm

nice! are you by chance on github?

adafruit
 
Posts: 12149
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: Arduino Ethernet shield with SD card - File hosting?

by Andyx on Tue Aug 31, 2010 3:44 pm

Added github link to my profile. :idea:
What is better than an Arduino? An Arduino with a laser!

Andyx
 
Posts: 40
Joined: Tue Aug 03, 2010 5:55 pm
Location: Dania Beach, Florida

Re: Arduino Ethernet shield with SD card - File hosting?

by adafruit on Tue Aug 31, 2010 4:09 pm

if youd like, you can fork our code and mod it
we'll post it on our tutorial :)

adafruit
 
Posts: 12149
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

Re: Arduino Ethernet shield with SD card - File hosting?

by Andyx on Tue Aug 31, 2010 5:51 pm

Done. :idea:
What is better than an Arduino? An Arduino with a laser!

Andyx
 
Posts: 40
Joined: Tue Aug 03, 2010 5:55 pm
Location: Dania Beach, Florida

Please be positive and constructive with your questions and comments.