Why Arduino Ethernet runs so unstablely?

Hello! I'm using Arduino Uno with Ethernet shield. Recently, I found that Ethernet may suddenly be broken. For example, I upload one Ethernet testing code to Arduino which is given in Arduino's website at here. Then I run it for some times. It run well in the first several times, but in the fifth time, for example, it runs badly and hints me that either DHCP can't be used(most of the time) or Connection Failed or so on. Then no matter what I try, it remains unusable. The only solution is putting it away for half a day and then it may run well again. However, recently I find that no matter how long I wait, the board can not run forever... I find that two Ethernet boards I bought have the same problem. Any suggestions? Many appreciations! P.s. my problem is not that let Ethernet continuously runs a long TIME then it suddenly don't run, but that let it run several TIMES then when run it again it suddenly don't run.

Do you want to use DHCP to get the network settings or use a static IP?

Do you want to use a domain name or an IP for the server?

P.S. If you can't answer these two questions, you shouldn't be working with the ethernet shield yet. It isn't the ethernet shield that is the problem. It is the sketch. If you answer the questions, I can provide the correct sketch for you to try.

SurferTim: Do you want to use DHCP to get the network settings or use a static IP?

Do you want to use a domain name or an IP for the server?

P.S. If you can't answer these two questions, you shouldn't be working with the ethernet shield yet. It isn't the ethernet shield that is the problem. It is the sketch. If you answer the questions, I can provide the correct sketch for you to try.

Dhcp and domain name. Thanks for answering my question! However, it is the SAME sketch I use that sometimes runs well and sometimes can't run. So in my opinion,it is not the sketch's fault.

This works for me every time, all the time. Change the server to your server’s domain name. I have www.google.com in there now. It will load the page every 30 seconds, and takes the 30 seconds before it starts loading the page. I use 115200 for the serial baud rate.

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

// this must be unique
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEC };

// change to your server domain name
char server[] = "www.google.com";

// change to your server's port
int serverPort = 80;

EthernetClient client;
int totalCount = 0;
int loopCount = 0;
char pageAdd[32];

void setup() {
  Serial.begin(115200);

  // disable SD while starting w5100
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  // Start ethernet
  Serial.print(F("Starting ethernet..."));

 if(!Ethernet.begin(mac)) Serial.println(F("failed"));
 else Serial.println(F("ok"));

  Serial.println(Ethernet.localIP());

  delay(2000);
  Serial.println(F("Ready"));
}

void loop()
{
  Ethernet.maintain();
  
  if(loopCount < 30)
  {
    // if loopCount is less than 30, just delay a second
    delay(1000);
  }
  else
  {
    // every thirty seconds this runs
    loopCount = 0;

    // Modify next line to load different page
    // or pass values to server
    strcpy(pageAdd,"/");

    // sprintf(pageAdd,"/arduino.php?test=%u",totalCount);

    if(!getPage(server,serverPort,pageAdd)) Serial.print(F("Fail "));
    else Serial.print(F("Pass "));
    totalCount++;
    Serial.println(totalCount,DEC);
  }    

  loopCount++;
}

byte getPage(char* ipBuf,int thisPort, char *page)
{
  int inChar;
  char outBuf[128];

  Serial.print(F("connecting..."));

  if(client.connect(ipBuf,thisPort) == 1)
  {
    Serial.println(F("connected"));

    sprintf(outBuf,"GET %s HTTP/1.1",page);
    client.println(outBuf);
    sprintf(outBuf,"Host: %s",server);
    client.println(outBuf);
    client.println(F("Connection: close\r\n"));
  } 
  else
  {
    Serial.println(F("failed"));
    return 0;
  }

  // connectLoop controls the hardware fail timeout
  int connectLoop = 0;

  while(client.connected())
  {
    while(client.available())
    {
      inChar = client.read();
      Serial.write(inChar);
      // set connectLoop to zero if a packet arrives
      connectLoop = 0;
    }

    connectLoop++;

    // if more than 10000 milliseconds since the last packet
    if(connectLoop > 10000)
    {
      // then close the connection from this end.
      Serial.println();
      Serial.println(F("Timeout"));
      client.stop();
    }
    // this is a delay for the connectLoop timing
    delay(1);
  }

  Serial.println();

  Serial.println(F("disconnecting."));
  // close client end
  client.stop();

  return 1;
}

edit: Yes, it can be the sketch, and probably is. If it doesn’t work for you, let me know where it failed. If it is the DHCP that fails, I can help fix that.

SurferTim:
This works for me every time, all the time. Change the server to your server’s domain name. I have www.google.com in there now. It will load the page every 30 seconds, and takes the 30 seconds before it starts loading the page. I use 115200 for the serial baud rate.

#include <SPI.h>

#include <Ethernet.h>

// this must be unique
byte mac = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEC };

// change to your server domain name
char server = “www.google.com”;

// change to your server’s port
int serverPort = 80;

EthernetClient client;
int totalCount = 0;
int loopCount = 0;
char pageAdd[32];

void setup() {
  Serial.begin(115200);

// disable w5100 SPI while starting SD
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

// Start ethernet
  Serial.print(F(“Starting ethernet…”));

if(!Ethernet.begin(mac)) Serial.println(F(“failed”));
else Serial.println(F(“ok”));

Serial.println(Ethernet.localIP());

delay(2000);
  Serial.println(F(“Ready”));
}

void loop()
{
  Ethernet.maintain();
 
  if(loopCount < 30)
  {
    // if loopCount is less than 30, just delay a second
    delay(1000);
  }
  else
  {
    // every thirty seconds this runs
    loopCount = 0;

// Modify next line to load different page
    // or pass values to server
    strcpy(pageAdd,"/");

// sprintf(pageAdd,"/arduino.php?test=%u",totalCount);

if(!getPage(server,serverPort,pageAdd)) Serial.print(F("Fail "));
    else Serial.print(F("Pass "));
    totalCount++;
    Serial.println(totalCount,DEC);
  }

loopCount++;
}

byte getPage(char* ipBuf,int thisPort, char *page)
{
  int inChar;
  char outBuf[128];

Serial.print(F(“connecting…”));

if(client.connect(ipBuf,thisPort) == 1)
  {
    Serial.println(F(“connected”));

sprintf(outBuf,“GET %s HTTP/1.1”,page);
    client.println(outBuf);
    sprintf(outBuf,“Host: %s”,server);
    client.println(outBuf);
    client.println(F(“Connection: close\r\n”));
  }
  else
  {
    Serial.println(F(“failed”));
    return 0;
  }

// connectLoop controls the hardware fail timeout
  int connectLoop = 0;

while(client.connected())
  {
    while(client.available())
    {
      inChar = client.read();
      Serial.write(inChar);
      // set connectLoop to zero if a packet arrives
      connectLoop = 0;
    }

connectLoop++;

// if more than 10000 milliseconds since the last packet
    if(connectLoop > 10000)
    {
      // then close the connection from this end.
      Serial.println();
      Serial.println(F(“Timeout”));
      client.stop();
    }
    // this is a delay for the connectLoop timing
    delay(1);
  }

Serial.println();

Serial.println(F(“disconnecting.”));
  // close client end
  client.stop();

return 1;
}




edit: Yes, it can be the sketch, and probably is. If it doesn't work for you, let me know where it failed. If it is the DHCP that fails, I can help fix that.

Sorry but it doesn’t work… it prints:

Starting ethernet…failed.
0.0.0.0
ready

Then it is the dhcp that is failing. Does it fail every time, or just occasionally?

Try this mod.

// replace this
  if(!Ethernet.begin(mac)) Serial.println(F("failed"));
  else Serial.println(F("ok"));

// with this  
  while(!Ethernet.begin(mac)) {
    Serial.println(F("failed. Trying again in 5 seconds."));
    delay(5000);
  }

SurferTim:
Then it is the dhcp that is failing. Does it fail every time, or just occasionally?

Try this mod.

// replace this

if(!Ethernet.begin(mac)) Serial.println(F(“failed”));
 else Serial.println(F(“ok”));

// with this  
 while(!Ethernet.begin(mac)) {
   Serial.println(F(“failed. Trying again in 5 seconds.”));
   delay(5000);
 }

Thanks for your kind help and your time! But now I find the real problem that the NETWORK CABLE has a poor contact, which is solved by changing a new one…
Maybe there is another hidden problem, if I find it I will contract you. Many appreciated!

I should have suggested the cable first. I assumed you had checked it, since you suspected a hardware problem. My bad.

If you use my code, there should not be any hidden problems. I have tested it thoroughly. It might not connect every time (I disconnect the CAT5 cable to test it), but it won't lock up like other code.

The way to test client code is to use Google's home page as the download, and disconnect the CAT5 cable just after the download starts. The home page is quite large, so it is easy to break the connection during the download. Most example sketches will lock up if this happens (server stalls or connection breaks). Mine won't. You will get a "Timeout" message and it will continue to work.