Arduino Ethernet shield with SD card - File hosting?

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
nate strech
 
Posts: 11
Joined: Wed Aug 11, 2010 7:19 pm

Arduino Ethernet shield with SD card - File hosting?

Post by nate strech »

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.

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

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

Post by adafruit »

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)

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

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

Post by jonbaer »

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.

User avatar
nate strech
 
Posts: 11
Joined: Wed Aug 11, 2010 7:19 pm

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

Post by nate strech »

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/tutori ... als_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

#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/web ... 00476.html

Cheers,
Nate

User avatar
fat16lib
 
Posts: 595
Joined: Wed Dec 24, 2008 1:54 pm

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

Post by fat16lib »

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

uint8_t Sd2Card:init(uint8_t sckRateID, uint8_t chipSelectPin);
For the ethernet SD the call would be something like

Code: Select all

 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

uint8_t const  SD_CHIP_SELECT_PIN = SS_PIN;
New default pin 4:

Code: Select all

uint8_t const  SD_CHIP_SELECT_PIN = 4;

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

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

Post by adafruit »

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!!

User avatar
nate strech
 
Posts: 11
Joined: Wed Aug 11, 2010 7:19 pm

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

Post by nate strech »

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!

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

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

Post by adafruit »

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

User avatar
Andyx
 
Posts: 40
Joined: Tue Aug 03, 2010 5:55 pm

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

Post by Andyx »

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

/*
 * 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();
  }
}

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

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

Post by adafruit »

nice! are you by chance on github?

User avatar
Andyx
 
Posts: 40
Joined: Tue Aug 03, 2010 5:55 pm

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

Post by Andyx »

Added github link to my profile. :idea:

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

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

Post by adafruit »

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

User avatar
Andyx
 
Posts: 40
Joined: Tue Aug 03, 2010 5:55 pm

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

Post by Andyx »

Done. :idea:

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”