Ethernet shield stops working after day

Hello,
I’ve got a project which checks whether the internal and external networks are working, and if they are gets a colour from a local web page. It then either flashes an error code or lights RGB LEDs to the relevant colour.

This works fine, but after a day or so it error codes indicating that it doesn’t have an internal or external network connection. There’s no gap between each error signal, so it’s not behaving in the same way as it does when there’s a real network problem as that takes a few seconds to check. It seems that the ethernet shield just stops responding.

It’s an old one - duemilanove era (circa 2011), in case that makes a difference.

Any suggestions, please?

Here’s the code (I’ve stripped the colour change bits in order to get it to post):

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

boolean anode = false;
byte mac = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //MAC address
IPAddress server1(74,125,232,128); // IP for Google for external network check
IPAddress server2(192,168,0,1); // router for internal network check
char server3 = “192.168.0.9”; // cownas for colour.
// RGB LED control
int redPin = 3; // Red LED, connected to digital pin 3
int greenPin = 5; // Green LED, connected to digital pin 5
int bluePin = 6; // Blue LED, connected to digital pin 6

byte redV = 0;
byte greenV = 0;
byte blueV = 0;
byte oldRedV = 0;
byte oldGreenV = 0;
byte oldBlueV = 0;
String temp = “”;
int RGB = 0;

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,0,250);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);

// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Ethernet.begin(mac, ip);
}
}

void outLight(byte rValue, byte gValue, byte bValue) {
(sets the RGB LED)
}

void fader(byte oldrValue, byte oldgValue, byte oldbValue, byte rValue, byte gValue, byte bValue, byte pause) {
//Fades to an RGB colour over a number of steps
}

boolean checkNetwork() {
//checks the status of the internal and extrarnal networks
//flashes if broken.
boolean internal = false;
boolean external = false;

if (client.connect(server1, 80)) { //can’t connect to google
external = true;
}
client.stop();
if (client.connect(server2, 80)) { //can’t connect to router
internal = true;
}
client.stop();

if ((internal == false) || (external == false)) { //one or both failed
return false;
} else {
return true;
}
}

void loop()
{
RGB=0;
if (checkNetwork()) {
if (client.connect(server3, 80)) {
Serial.println(“Connected…”);
client.println(“GET /arduino/getcolour.php”);
client.println(“Connection: close”);
}
delay(100);
while (client.available()) {
char c = client.read();
if (c != 44) {
temp += c;
} else {
if (RGB == 0) {
redV = temp.toInt();
temp = “”;
} else if (RGB == 1) {
greenV = temp.toInt();
temp = “”;
} else if (RGB == 2) {
blueV = temp.toInt();
temp = “”;
}
RGB++;
}
}
fader(oldRedV,oldGreenV,oldBlueV,redV,greenV,blueV,70);
client.stop();
oldRedV = redV;
oldGreenV = greenV;
oldBlueV = blueV;
delay(10000);
}
}

It may be you are running out of sockets. You should put some more Serial.println() calls to debug that code. Find out where in the code it is failing.

Does it stop after displaying "Connected..."? Or does it keep displaying "Connected..." over and over?

I thought client.stop would end the use of that socket? Is there a way to finish with a socket?

I haven't actually debugged it (that serial print is legacy from when I was debugging during its creation), I presumed it'd be a known problem and someone would be able to tell me the answer :~

Running out of sockets is a known problem. Add this function to your sketch, then call it at the start of loop().

#include <utility/w5100.h>

byte socketStat[MAX_SOCK_NUM];

void ShowSockStatus()
{
  for (int i = 0; i < MAX_SOCK_NUM; i++) {
    Serial.print(F("Socket#"));
    Serial.print(i);
    uint8_t s = W5100.readSnSR(i);
    socketStat[i] = s;
    Serial.print(F(":0x"));
    Serial.print(s,16);
    Serial.print(F(" "));
    Serial.print(W5100.readSnPORT(i));
    Serial.print(F(" D:"));
    uint8_t dip[4];
    W5100.readSnDIPR(i, dip);
    for (int j=0; j<4; j++) {
      Serial.print(dip[j],10);
      if (j<3) Serial.print(".");
    }
    Serial.print(F("("));
    Serial.print(W5100.readSnDPORT(i));
    Serial.println(F(")"));
  }
}

A socket status list:
0X0 = available.
0x14 = socket waiting for a connection
0x17 = socket connected to a server.

Will do, thanks surfertim.

Is there a way round if it is lack of sockets? Can I reset the ethernet shield in my sketch?

CowJam:
Is there a way round if it is lack of sockets? Can I reset the ethernet shield in my sketch?

Yes. Avoid using code that leaves them connected. Normally if you are running out of sockets, you will end up showing all 4 sockets with the status of 0X17, and none with 0X0. At that point, you will not be able to connect to a server. The connection will fail.

If you're setting a static IP address the Arduino will never even try DHCP. If you knew that, change the comment.

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,0,250);

It's interesting, that this code:

    if (client.connect(server3, 80)) {
      Serial.println("Connected...");
      client.println("GET /arduino/getcolour.php");
      client.println("Connection: close");
    }

ever worked because by the HTTP standard the request header is finished when an empty line is received. Your server never gets that and answers anyway? What server are you running that behaves that odd?

I thought client.stop would end the use of that socket?

That's correct, at least it tries to do that. It disconnects by sending a FIN packet to the server. If the server doesn't respond within 1 second with the same kind of packet, it closes the socket forcefully. If that doesn't work, that hardware is in fail (my opinion).

@pylon: My past experiments have shown that if the socket has characters in the rx buffer, it will not close properly when client.stop() is called.

SurferTim: @pylon: My past experiments have shown that if the socket has characters in the rx buffer, it will not close properly when client.stop() is called.

That should be straight forward to code in for, I'll try it. Ta.

@pylon - it's a QNAP NAS box.

I checked the behavior with telnet before implementing it.

Here is my client code. It has all the “antifreeze” stuff added to it, including a timeout if the connection fails.
http://playground.arduino.cc/Code/WebClient

SurferTim: Here is my client code. It has all the "antifreeze" stuff added to it, including a timeout if the connection fails. http://playground.arduino.cc/Code/WebClient

Thank you!