Go Down

Topic: [RESOLVED]Due with W5100 Ethernet and SD Card Web Server SPI Issue (Read 747 times) previous topic - next topic

jonis_99

I have a Due with a W5100 & SD Card shield and am attempting to get a web server working.

When using the SD card only I can read/write fully and everything functions normally.

When using the Ethernet only (and hard coded HTML) the W5100 functions normally. (Pings/serves page)

When I attempt to use both at the same time, to serve a webpage from the SD card, the "client" portion of the below code seems to hold the SPI CS line and doesn't allow reading of the "index.htm" file from the sd card.

Using:

IDE 1.8.9
SD 1.2.3
Ethernet 2.0.0

Any hints/help would be appreciated...

Code: [Select]
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>


// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 111); // IP address, may need to change depending on network
EthernetServer server(80);  // create a server at port 80
#define Serial SerialUSB

File webFile;

void setup()
{
    //pinMode(4, OUTPUT);
    //pinMode(10, OUTPUT);
    //pinMode(52, OUTPUT);
    digitalWrite(4, HIGH);
    digitalWrite(10, HIGH);
    digitalWrite(52, HIGH);
  
    Serial.begin(115200);       // for debugging
    while (!Serial) {
      ; // wait for serial port to connect. Needed for Leonardo onlyffa
    }    
    // initialize SD card
    Serial.println("Initializing SD card...");
    if (!SD.begin(4)) {
        Serial.println("ERROR - SD card initialization failed!");
        return;    // init failed
    }
    Serial.println("SUCCESS - SD card initialized.");
    // check for index.htm file
    if (!SD.exists("index.htm")) {
        Serial.println("ERROR - Can't find index.htm file!");
        return;  // can't find index file
    }
    Serial.println("SUCCESS - Found index.htm file.");
              // start to listen for clients
    
    Ethernet.init(10);
    Ethernet.begin(mac, ip);  // initialize Ethernet device
    server.begin();
}

void loop()
{
    EthernetClient client = server.available();  // try to get client

    if (client) {  // got client?
      Serial.println("client request...");
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {   // client data available to read
                char c = client.read(); // read 1 byte (character) from client
                // last line of client request is blank and ends with \n
                // respond to client only after last line received
                if (c == '\n' && currentLineIsBlank) {
                    // send a standard http response header
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-Type: text/html");
                    client.println("Connection: close");
                    client.println();
                    // send web page
                    webFile = SD.open("index.htm");        // open web page file
                    if (webFile) {
                      Serial.println("webfile...");
                        while(webFile.available()) {
                            client.write(webFile.read()); // send web page to client
                        }
                        webFile.close();
                    }
                    break;
                }
                // every line of text received from the client ends with \r\n
                if (c == '\n') {
                    // last character on line of received text
                    // starting new line with next character read
                    currentLineIsBlank = true;
                }
                else if (c != '\r') {
                    // a text character was received from client
                    currentLineIsBlank = false;
                }
            } // end if (client.available())
        } // end while (client.connected())
        delay(1);      // give the web browser time to receive the data
        client.stop(); // close the connection
    } // end if (client)

}



Serial output when running this code gives me:

Code: [Select]
Initializing SD card...
SUCCESS - SD card initialized.
SUCCESS - Found index.htm file.


And after requesting the page at 192.168.0.111 the serial output gives me:

Code: [Select]
Initializing SD card...
SUCCESS - SD card initialized.
SUCCESS - Found index.htm file.
client request...
client request...


Which is the index page request (and the un-handled favicon request) from the browser.

The problem appears to be in this section when the SPI bus is required to change its chip select line back and forth between the sd card and the w5100 chip while reading index.htm a byte at a time...

Code: [Select]

// send web page
webFile = SD.open("index.htm");        // open web page file
if (webFile) {
   Serial.println("webfile...");
   while(webFile.available()) {
      client.write(webFile.read()); // send web page to client
   }
webFile.close();
}



ard_newbie

What are you expecting with these lines ?

Code: [Select]

 //pinMode(4, OUTPUT);
    //pinMode(10, OUTPUT);
    //pinMode(52, OUTPUT);
    digitalWrite(4, HIGH);
    digitalWrite(10, HIGH);
    digitalWrite(52, HIGH);

jonis_99

pin 52 is CS line for an ADC that is currently not being used but connected on SPI bus.
pin 4 is sd card CS line
pin 10 is W5100 line


In troubleshooting the issue, I read on the forums that those lines may need to be pulled High (CS disable) when using multiple items on the SPI bus.

EDIT: Disabled before initializing.... i forgot to add.
they may not be required but at this point I am in "Try anything" mode.

jonis_99

If I add a "client.stop();" right before the "webFile = SD.open("index.htm");" then the file is found on the sd card, obviously this means I can no longer push the page out to the browser but... it seems to mean that the EthernetClient is either holding SS OR  MISO for some reason?

or is there a flaw in my logic?

I welcome anyone's thoughts on this.... its driving me crazy and I need to solve this.


ard_newbie


jonis_99

This blog may help you:

https://hackaday.com/2014/11/25/better-spi-bus-design/

and this thread:

https://forum.arduino.cc/index.php?topic=465101.0
Thanks ard, I was hoping someone would find something obviously wrong with the code or had some insight into a library bug... instead of it being a hardware issue I had to sort out.

jonis_99

Here is the resolution to this issue.

The hardware design had the W5100 SEN pin pulled HIGH through a R10K

When the SEN pin is HIGH the chips SPI is active, which holds (drives/floats) MISO, which doesn't allow any other devices to use the bus.

I ran an additional wire from the R10k to a digital output and set it HIGH/LOW any time the W5100 need to use the SPI bus.


Additional Reading:
https://www.pjrc.com/better-spi-bus-design-in-3-steps/
https://arduinodiy.wordpress.com/2017/04/12/the-w5100-bug/
https://forum.arduino.cc/index.php?topic=195287.0

Go Up