Arduino Uno - Ethernet Shield - Hangs

I am using the heavily plagiarized code below. It works, but is not dependable. After a period of usage the web server will just hang and not respond. On some occasions the web browser will fill with garbage characters. I can still ping the Arduino when the hang occurs, but the only way to get the web server to respond again is to reboot. Do I need some judiciously placed delay statements? Any advice would be appreciated. Am I expecting too much for this to work dependably? Thanks.

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

int ch00 = 4;
int ch01 = 5;
int ch02 = 6;
int ch03 = 7;
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0xA5, 0x9C };
byte ip[] = { 192, 168, 0, 200 };
byte gateway[] = { 192, 168, 0, 1 };
byte subnet[] = { 255, 255, 255, 0 };
EthernetServer server(80);
String readString;

void setup()
{
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();
pinMode(ch00, OUTPUT);
pinMode(ch01, OUTPUT);
pinMode(ch02, OUTPUT);
pinMode(ch03, OUTPUT);
digitalWrite(ch00, LOW);
digitalWrite(ch01, LOW);
digitalWrite(ch02, LOW);
digitalWrite(ch03, LOW);
}

void loop()
{
EthernetClient client = server.available();
if (client)
{
while (client.connected())
{
if (client.available())
{
char c = client.read();
if (readString.length() < 24)
{
readString += c;
}
if (c == '\n')
{
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("");
client.println("");
client.println("");
client.println("");
client.println("");
client.println("");
client.println("Relay Control");
client.println("");
client.println("");
client.println("

Relay Control

");
client.println("

Arduino

");
client.println("
");
client.println("<a href="/?ch00on"">Turn CH00 On");
client.println("<a href="/?ch00off"">Turn CH00 Off
");
client.println("
");
client.println("
");
client.println("<a href="/?ch01on"">Turn CH01 On");
client.println("<a href="/?ch01off"">Turn CH01 Off
");
client.println("
");
client.println("
");
client.println("<a href="/?ch02on"">Turn CH02 On");
client.println("<a href="/?ch02off"">Turn CH02 Off
");
client.println("
");
client.println("
");
client.println("<a href="/?ch03on"">Turn CH03 On");
client.println("<a href="/?ch03off"">Turn CH03 Off
");
client.println("
");
client.println("");
client.println("");
client.stop();
if (readString.indexOf("?ch00on") >0)
{
digitalWrite(ch00, HIGH);
}
if (readString.indexOf("?ch00off") >0)
{
digitalWrite(ch00, LOW);
}
if (readString.indexOf("?ch01on") >0)
{
digitalWrite(ch01, HIGH);
}
if (readString.indexOf("?ch01off") >0)
{
digitalWrite(ch01, LOW);
}
if (readString.indexOf("?ch02on") >0)
{
digitalWrite(ch02, HIGH);
}
if (readString.indexOf("?ch02off") >0)
{
digitalWrite(ch02, LOW);
}
if (readString.indexOf("?ch03on") >0)
{
digitalWrite(ch03, HIGH);
}
if (readString.indexOf("?ch03off") >0)
{
digitalWrite(ch03, LOW);
}
readString = "";
}
}
}
}
}

You may be getting a GET request that is longer than 24 characters, so it never gets to end of the string, namely the condition where c=='\n'.

Change this

if (readString.length() < 24)

to

if (readString.length() < 255)

and see whether it stops hanging.

He's reading them all, just not storing any past 24 characters. That is ok.

Do you have a SD card in the shield's slot?

And this is not correct. It may not affect localnet connections, but it will certainly affect any internet communication.

// change this...
Ethernet.begin(mac, ip, gateway, subnet);
// ...to this:
Ethernet.begin(mac, ip, gateway, gateway, subnet);

You could be running out of memory. Try using the F() function on the static strings.

Here is my server code. It works well.
http://playground.arduino.cc/Code/WebServerST

SurferTim,
Thanks for the advice. I do have an SD card in the Ethernet Shield's slot, but it is not being used for this project. Should I remove it? I also made the change on the Ethernet.begin statement. I will learn more about F() and also make that change.

SurferTim:
He's reading them all, just not storing any past 24 characters. That is ok.

Sorry, you are right. 24 chars should be enough for this application since the server IP address is typically removed from the GET request, making it shorter.
Cheers!

Trying to use F() as shown in the code below. Getting "avrdude: stk500_getsync(): not in sync: resp=0x00" when uploading.
I guess F() works on an UNO?

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

int ch00 = 4;
int ch01 = 5;
int ch02 = 6;
int ch03 = 7;
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0xA5, 0x9C };  
byte ip[] = { 192, 168, 0, 200 };                      
byte gateway[] = { 192, 168, 0, 1 };                   
byte subnet[] = { 255, 255, 255, 0 };                  
EthernetServer server(80);                                  
String readString;

void setup() 
  {
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  pinMode(ch00, OUTPUT);
  pinMode(ch01, OUTPUT);
  pinMode(ch02, OUTPUT);
  pinMode(ch03, OUTPUT);
  digitalWrite(ch00, LOW);  
  digitalWrite(ch01, LOW);  
  digitalWrite(ch02, LOW);  
  digitalWrite(ch03, LOW);  
  }

void loop() 
  {
  EthernetClient client = server.available();
  if (client) 
    {
    while (client.connected()) 
      {
      if (client.available()) 
        {
        char c = client.read();
        if (readString.length() < 24) 
          {
            readString += c;
          }
          if (c == '\n') 
            {          
            client.println(F("HTTP/1.1 200 OK")); 
            client.println(F("Content-Type: text/html"));
            client.println();     
            client.println(F("<HTML>"));
            client.println(F("<HEAD>"));
            client.println(F("<meta name='apple-mobile-web-app-capable' content='yes' />"));
            client.println(F("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />"));
            client.println(F("<meta name='viewport' content='width=320, initial-scale=0.90' />"));
            client.println(F("<link rel='stylesheet' type='text/css' href='http://randomnerdtutorials.com/ethernetcss.css' />"));
            client.println(F("<TITLE>Relay Control</TITLE>"));
            client.println(F("</HEAD>"));
            client.println(F("<BODY>"));
            client.println(F("<H1>Relay Control</H1>"));
            client.println(F("<H2>Arduino</H2>"));
            client.println(F("
"));  
            client.println(F("<a href=\"/?ch00on\"\">Turn CH00 On</a>"));
            client.println(F("<a href=\"/?ch00off\"\">Turn CH00 Off</a>
"));   
            client.println(F("
"));     
            client.println(F("
")); 
            client.println(F("<a href=\"/?ch01on\"\">Turn CH01 On</a>"));
            client.println(F("<a href=\"/?ch01off\"\">Turn CH01 Off</a>
"));   
            client.println(F("
"));     
            client.println(F("
")); 
            client.println(F("<a href=\"/?ch02on\"\">Turn CH02 On</a>"));
            client.println(F("<a href=\"/?ch02off\"\">Turn CH02 Off</a>
"));   
            client.println(F("
"));     
            client.println(F("
")); 
            client.println(F("<a href=\"/?ch03on\"\">Turn CH03 On</a>"));
            client.println(F("<a href=\"/?ch03off\"\">Turn CH03 Off</a>
")); 
            client.println(F("
")); 
            client.println(F("</BODY>"));
            client.println(F("</HTML>"));
            client.stop();
            if (readString.indexOf("?ch00on") >0)
              {
              digitalWrite(ch00, HIGH);
              }
            if (readString.indexOf("?ch00off") >0)
              {
              digitalWrite(ch00, LOW);
              }
            if (readString.indexOf("?ch01on") >0)
              {
              digitalWrite(ch01, HIGH);
              }
            if (readString.indexOf("?ch01off") >0)
              {
              digitalWrite(ch01, LOW);
              }
            if (readString.indexOf("?ch02on") >0)
              {
              digitalWrite(ch02, HIGH);
              }
            if (readString.indexOf("?ch02off") >0)
              {
              digitalWrite(ch02, LOW);
              }
            if (readString.indexOf("?ch03on") >0)
              {
              digitalWrite(ch03, HIGH);
              }
            if (readString.indexOf("?ch03off") >0)
              {
              digitalWrite(ch03, LOW);
              }
            readString = "";  
            } 
        }
      }
    }
  }

The F() function works with the Uno.

If you have a SD card in the shield's slot, you must disable it before calling any other SPI device begin functions. Like this:

void setup() 
  {
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  Ethernet.begin(mac, ip, gateway, gateway, subnet);

Thanks for the help, I made all the suggested changes and it is working like a charm so far. We will see what happens with the test of time. I think my biggest problem was not having this correct: Ethernet.begin(mac, ip, gateway, gateway, subnet);

Here's a picture of my rig. Triple stacked Arduino Uno, Ethernet Shield and Seeed Studio Relay Shield V1.0

The problem is resolved with the new begin or not?

stefben:
The problem is resolved with the new begin or not?

Yes.

pk_arduino:
Thanks for the help, I made all the suggested changes and it is working like a charm so far. We will see what happens with the test of time. I think my biggest problem was not having this correct: Ethernet.begin(mac, ip, gateway, gateway, subnet);

Hi

I'am having issues with W5100 too, I have 2 identical setups, with 2 different IP's
One of them runs for an hour, then it's not responding, the other one, runs several days.
I have use Ethernet.begin(mac, ip, gateway, subnet);
from the start (and experienced hangs on a weekly basis)

Could someone explain why this is wrong, this is the same format as in the reference

Where are those parameters explained?

/Shummi