Arduino Ethernet Shield

An advanced Arduino-compatible board with ATmega1284P and ATmega32u2 MCUs for experienced users. More RAM than a Mega, but in a convenient Uno-style form factor. [Product page]
richard47
Posts: 6
Joined: Thu Jan 23, 2014 7:45 am

Arduino Ethernet Shield

Post by richard47 » Thu Jan 23, 2014 8:09 am

Is the Arduino Ethernet Shield compatible with Goldilocks? I have tried a number of test sketches in addition to my own without success. The same shield works with my Uno.

It appears that the shield when attached to Goldilocks fails to connect to my local network.

Edit: I will post a short sketch later
Edit 2: On the Uno web access works but it does not on Goldilocks

Code: Select all

/*
 * This sketch uses the microSD card slot on the Arduino Ethernet shield
 * to serve up files over a very minimal browsing interface
 *
 * Some code is from Bill Greiman's SdFatLib examples, some is from the
 * Arduino Ethernet WebServer example and the rest is from Limor Fried
 * (Adafruit) so its probably under GPL
 *
 * Tutorial is at http://www.ladyada.net/learn/arduino/ethfiles.html
 * Pull requests should go to http://github.com/adafruit/SDWebBrowse
 */

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

/************ ETHERNET STUFF ************/
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x9C, 0x24 };
byte ip[] = { 192, 168, 1, 178 };
EthernetServer 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();
}

void ListFiles(EthernetClient client, uint8_t flags) {
  // This code is just copied from SdFile.cpp in the SDFat library
  // and tweaked to print to the client output in html!
  dir_t p;
  
  root.rewind();
  client.println("<ul>");
  while (root.readDir(&p) > 0) {
    // done if past last used entry
    if (p.name[0] == DIR_NAME_FREE) break;

    // skip deleted entry and entries for . and  ..
    if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.') continue;

    // only list subdirectories and files
    if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;

    // print any indent spaces
    client.print("<li><a href=\"");
    for (uint8_t i = 0; i < 11; i++) {
      if (p.name[i] == ' ') continue;
      if (i == 8) {
        client.print('.');
      }
      client.print((char)p.name[i]);
    }
    client.print("\">");
    
    // print file name with possible blank fill
    for (uint8_t i = 0; i < 11; i++) {
      if (p.name[i] == ' ') continue;
      if (i == 8) {
        client.print('.');
      }
      client.print((char)p.name[i]);
    }
    
    client.print("</a>");
    
    if (DIR_IS_SUBDIR(&p)) {
      client.print('/');
    }

    // print modify date/time if requested
    if (flags & LS_DATE) {
       root.printFatDate(p.lastWriteDate);
       client.print(' ');
       root.printFatTime(p.lastWriteTime);
    }
    // print size if requested
    if (!DIR_IS_SUBDIR(&p) && (flags & LS_SIZE)) {
      client.print(' ');
      client.print(p.fileSize);
    }
    client.println("</li>");
  }
  client.println("</ul>");
}

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

void loop()
{
  char clientline[BUFSIZ];
  int index = 0;
  
  EthernetClient 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;
        
        // 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) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          
          // print all the files, use a helper to keep it clean
          client.println("<h2>Files:</h2>");
          ListFiles(client, LS_SIZE);
        } else if (strstr(clientline, "GET /") != 0) {
          // this time no space after the /, so a sub-file!
          char *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");
          client.println("Content-Type: text/plain");
          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();
  }
}

andrew
Freetronics Staff
Freetronics Staff
Posts: 978
Joined: Sun Jul 14, 2013 7:06 am
Location: Melbourne, Australia
Contact:

Re: Arduino Ethernet Shield

Post by andrew » Mon Jan 27, 2014 3:59 am

There isn't any reason why it shouldn't, the project instigator has been running W5100 and W5200-based Ethernet shields with success.
http://feilipu.me/2013/08/03/wiznet-w52 ... no-shield/

If you haven't already done so, can you power your hardware from DC power (not just USB) and try again with the basic webserver sketch that comes with the Arduino IDE Ethernet library?

richard47
Posts: 6
Joined: Thu Jan 23, 2014 7:45 am

Re: Arduino Ethernet Shield

Post by richard47 » Mon Jan 27, 2014 5:07 pm

Thank you for responding to my question.

I have now tried several of the sketches from the Arduino Ethernet library with DC power and still my Ethernet shield fails to respond.

andrew
Freetronics Staff
Freetronics Staff
Posts: 978
Joined: Sun Jul 14, 2013 7:06 am
Location: Melbourne, Australia
Contact:

Re: Arduino Ethernet Shield

Post by andrew » Mon Jan 27, 2014 9:39 pm

richard47 wrote:Thank you for responding to my question.

I have now tried several of the sketches from the Arduino Ethernet library with DC power and still my Ethernet shield fails to respond.
Try using D10~D13 as simple digital outputs, see if they work.

richard47
Posts: 6
Joined: Thu Jan 23, 2014 7:45 am

Re: Arduino Ethernet Shield

Post by richard47 » Wed Jan 29, 2014 4:18 pm

When used as digital outputs D10 ~ D13 on Goldilocks operated correctly.

As both the Goldilocks and the Arduino Ethernet shield have SD sockets I added a datalogging shield to the Uno/Ethernet shield combination. Once again the Goldilocks/Ethernet combination failed to connect to my network whilst the Uno/Ethernet/Datalogger combination was OK.

andrew
Freetronics Staff
Freetronics Staff
Posts: 978
Joined: Sun Jul 14, 2013 7:06 am
Location: Melbourne, Australia
Contact:

Re: Arduino Ethernet Shield

Post by andrew » Wed Jan 29, 2014 9:03 pm

richard47 wrote:When used as digital outputs D10 ~ D13 on Goldilocks operated correctly.

As both the Goldilocks and the Arduino Ethernet shield have SD sockets I added a datalogging shield to the Uno/Ethernet shield combination. Once again the Goldilocks/Ethernet combination failed to connect to my network whilst the Uno/Ethernet/Datalogger combination was OK.
Is your board the 22.1184MHz version from the Pozible campaign?

feilipu
Posts: 52
Joined: Fri Jul 19, 2013 6:17 am

Re: Arduino Ethernet Shield

Post by feilipu » Thu Jan 30, 2014 10:30 pm

There is an issue with some Ethernet Shields not effectively removing themselves from the SPI bus when they are deselected. If you have an old Ethernet shield, then the W5100 chip will not "exit" the SPI bus which will prevent the SD card from working at all.

I have seen that problem with an old Ethernet Shield. However, I think the Freetronics Ethernet Shield addresses the problem.

What is your environment for not being successful with the Goldilocks and the Ethernet Shield?

richard47
Posts: 6
Joined: Thu Jan 23, 2014 7:45 am

Re: Arduino Ethernet Shield

Post by richard47 » Fri Jan 31, 2014 5:17 pm

Is your board the 22.1184MHz version from the Pozible campaign?
My Goldilocks is from the Pozible campaign. In the Arduino IDE I have set it up as a 20MHz board.
What is your environment for not being successful with the Goldilocks and the Ethernet Shield?
Goldilocks set up as a 20MHz board with an Arduindo Ethernet Shield R3 (the one with SCL/SDA adjacent to the Ethernet connect.

Thanks for your interest in my problem.

feilipu
Posts: 52
Joined: Fri Jul 19, 2013 6:17 am

Re: Arduino Ethernet Shield

Post by feilipu » Sat Feb 01, 2014 8:49 am

I don't have that Shield, but I've checked the schematic of Ethernet Shield 06 - Rev 03. I think it is the same one that you have.

This Ethernet Shield has a IC11, a Schmitt Trigger inverter on the SEN line, which ensures that the W5100 stays off the SPI bus, when the SS line is high. This fixes the issue that older Ethernet Shields exhibited.

The uSD SS is on PD4, which is shared with the Goldilocks uSD SS. This means that you should have only one uSD card at a time. And, best while you're testing to have NO uSD card inserted, to minimise the chance of influencing the W5100 result.

From the schematic, I don't see any specific issues that you're facing.
Assuming you have a 20MHz Goldilocks (with no large green sticker on the uSD cage)?

There is a problem with interfacing with the W5100. The W5100 SPI interface is only specified to run at 4MHz. The limitation in SPI rate to 4MHz means that the standard 16MHz Arduino Uno board SPI bus cannot be driven at any speed greater than SCK/4, if it is to remain within specification for driving the W5100. 20MHz boards, such as the Goldilocks must drop to SCK/8 if they are to remain within the W5100 specification. This could also be an issue if you have a "bad" (not bad, but just within specification and no more) W5100 chip. This, and the fact that the W5100 can't do multi-byte transfers, are the reasons I've given up on W5100 Ethernet Shields.

I also have a suspicion that the SDI interworking is not being handled correctly between the SD card library and the Ethernet library in your sketch. If the SS lines are not correctly managed the SD card will hold the SPI bus, and that will cause the W5100 to fail. For example if a file is open for reading the library might not have deselected the uSD card.

If you have a logic analyser you can check this out. Alternatively, try a test program that doesn't enable the SD card, and see if the Ethernet Shield still doesn't work. Also try the test program at SCK/8 to see if that changes things.

richard47
Posts: 6
Joined: Thu Jan 23, 2014 7:45 am

Re: Arduino Ethernet Shield

Post by richard47 » Sat Feb 01, 2014 4:58 pm

Alternatively, try a test program that doesn't enable the SD card, and see if the Ethernet Shield still doesn't work.
At the moment I cannot load any sketches as Goldilocks keeps giving me this error

avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer

In the past I got this message occasionally but now I get it 99% of the time!

Post Reply