Arduino Ethernet Freezes

I have a couple Arduino Ethernet Boards with POE connected to a couple of buttons and LEDs

Depending on which board (I have 5 of them) they lock up most of the time around once a day, if I unplug them and plug them back in everything is fine again.

I’ve tried putting in Serial Prints to find where it locks but it seems to do it in different spots, I’ve looked at free memory and that doesn’t seem to be it any help would be great

I’ve tried using 1.0.1, 1.0.4, and 1.5.2 all of them seem to do the same thing

#include <Dhcp.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <EthernetUdp.h>
#include <util.h>
#include <SPI.h>


// Buttons
int openButton = 3;
int tempOpenButton = 8;
int closeButton = 6;

// LEDs
int tempOpenLED = 9;
int closeLED = 5;
int openLED = 7;

//Variable
int state = 0;
const int timeOut = 100;
const int ServerCommsTimeOut = 1000000;
char data[300];
int datapos = 0;
long previousMillis = 0;  
long interval = 1000;   
long askInterval = 1000; 
int failIDEA = 0;


int SDCard = 4;


byte mac[] = {  
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xC2 };  
//byte ip[] = { 10, 100, 110, 10 }; 
byte ip[] = {
  10,100,110,10};
byte server[] = { 
  10,100,2,158 };  // Internal Server
int port = 22490;

EthernetClient client;

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

  Serial.println("Starting Ethernet");
  Ethernet.begin(mac);  
  Serial.print("My IP address: ");
  //  for (byte thisByte = 0; thisByte < 4; thisByte++) {
  //    // print the value of each byte of the IP address:
  //    Serial.print(Ethernet.localIP()[thisByte], DEC);
  //    Serial.print("."); 
  //  }
  //  Serial.println();


  Serial.println("Ethernet Complete");  

  pinMode(tempOpenLED, OUTPUT);  
  pinMode(closeLED, OUTPUT);
  pinMode(openLED, OUTPUT);

  pinMode(tempOpenButton, INPUT);  
  digitalWrite(tempOpenButton, HIGH);
  pinMode(closeButton, INPUT);  
  digitalWrite(closeButton, HIGH);
  pinMode(openButton, INPUT);  
  digitalWrite(openButton, HIGH);


  digitalWrite(tempOpenLED, HIGH);   
  delay(100);             
  digitalWrite(tempOpenLED, LOW);    
  delay(100); 
  digitalWrite(openLED, HIGH);   
  delay(100);             
  digitalWrite(openLED, LOW);    
  delay(100); 
  digitalWrite(closeLED, HIGH);   
  delay(100);             
  digitalWrite(closeLED, LOW);    
  delay(100); 

  pinMode(SDCard,OUTPUT);
  digitalWrite(SDCard,HIGH);


  Serial.println("Connecting To Server");
  if (client.connect(server, port)) {
    Serial.println("Connected To Server");
    digitalWrite(tempOpenLED, HIGH);
    digitalWrite(openLED, HIGH);
    digitalWrite(closeLED, HIGH); 
    delay(100);
    digitalWrite(tempOpenLED, LOW);
    digitalWrite(openLED, LOW);
    digitalWrite(closeLED, LOW);     
  } 
  else {
    connectToServer();
  }
}

void loop() {
  unsigned long currentMillis = millis();
  if (!client.connected()){
    connectToServer();
  }

  client.println("GetStatus=1");
 
  int availableBytes = 0;
  availableBytes = client.available();

  if (availableBytes > 0) {
    int gState = client.read();
    Serial.print("Gate State: ");
    Serial.println(gState);
    switch (gState) {
    case 0: // Unknown
      if(currentMillis - previousMillis > interval - 900) {
        previousMillis = currentMillis;  
        if (failIDEA == 0)
        {
          failIDEA = 1;
        } 
        else {
          failIDEA = 0;
        }
        digitalWrite(tempOpenLED, failIDEA);  
        digitalWrite(closeLED, failIDEA);  
        digitalWrite(openLED, failIDEA);
      }
      break;
    case 1: // Held Open
      digitalWrite(openLED, HIGH);
      digitalWrite(tempOpenLED, LOW);
      digitalWrite(closeLED, LOW);
      break;
    case 2: // Held Open Moving To Closed
      digitalWrite(openLED, HIGH);
      digitalWrite(tempOpenLED, LOW);
      if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;  
        digitalWrite(closeLED, !digitalRead(closeLED));
      }
      break;
    case 3: // Held Open Moving to Temp Open
      digitalWrite(openLED, HIGH);
      digitalWrite(closeLED, LOW);
      if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;  
        digitalWrite(tempOpenLED, !digitalRead(tempOpenLED));
      }
      break;
    case 4: // Temp Open 
      digitalWrite(openLED, LOW);
      digitalWrite(tempOpenLED, HIGH);
      digitalWrite(closeLED, LOW);
      break;
    case 5: // Temp Open Moving to Closed
      digitalWrite(tempOpenLED, HIGH);
      digitalWrite(openLED, LOW);
      if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;  
        digitalWrite(closeLED, !digitalRead(closeLED));
      }
      break;
    case 6: // Temp Open Moving To Open
      digitalWrite(tempOpenLED, HIGH);
      digitalWrite(closeLED, LOW);
      if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;  
        digitalWrite(openLED, !digitalRead(openLED));
      }
      break;
    case 7: // Closed
      digitalWrite(openLED, LOW);
      digitalWrite(tempOpenLED, LOW);
      digitalWrite(closeLED, HIGH);
      break;
    case 8: // Closed Moving to Open
      digitalWrite(closeLED, HIGH);
      digitalWrite(tempOpenLED, LOW);
      if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;  
        digitalWrite(openLED, !digitalRead(openLED));
      }  
      break;
    case 9: // Closed Moving to Temp Open
      digitalWrite(closeLED, HIGH);
      digitalWrite(openLED, LOW);
      if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;  
        digitalWrite(tempOpenLED, !digitalRead(tempOpenLED));
      }  
      break;
    }
  }
   checkButtons();

}


void checkButtons(){
 // Serial.println("checkButtons");


  if (digitalRead(tempOpenButton) == LOW)
  {
    sendTempOpen();
  }    
  if (digitalRead(closeButton) == LOW)
  {
    sendClose();
  }
  if (digitalRead(openButton) == LOW)
  {
    sendOpen(); 
  }  

}

void sendTempOpen() {
  client.println("RequestStatus=4&Gate=1"); // Temp Open Gate
  Serial.println("Set Gate State To Temp Open");
}

void sendClose() {
  client.println("RequestStatus=7&Gate=1"); // Close Gate
  Serial.println("Set Gate State To Close");
}

void sendOpen() {
  client.println("RequestStatus=1&Gate=1"); // Open Gate
  Serial.println("Set Gate State To Open");
}


void connectToServer(){
  Serial.println("In connectToServer");
  client.stop();
  digitalWrite(tempOpenLED, HIGH);  
  digitalWrite(closeLED, HIGH);  
  digitalWrite(openLED, HIGH);
  failIDEA = 0;
  if (!client.connect(server, port)){
    Serial.println("Not Connected To Server");
    if (failIDEA == 0)
    {
      failIDEA = 1;
    } 
    else {
      failIDEA = 0;
    }
    digitalWrite(tempOpenLED, failIDEA);  
    digitalWrite(closeLED, failIDEA);  
    digitalWrite(openLED, failIDEA);
    delay(250);         
  } 
  else {
    Serial.println("Connected To Server");
    digitalWrite(tempOpenLED, LOW);  
    digitalWrite(closeLED, LOW);  
    digitalWrite(openLED, LOW);
  }
}

You may be running out of sockets. Just a quick scan, and I saw no "client.stop()" anywhere, except here:

void connectToServer(){
  Serial.println("In connectToServer");
  client.stop();

So the first thing you want to do when connecting to a server is close the connection?

This web client code has been well tested. http://playground.arduino.cc/Code/WebClient

You don't read the whole answer from the server just one byte and then you send many bytes to it which may lead to new bytes being received. Have you checked the network traffic between the Arduino and the server with a tool like WireShark?

@SurferTim As far as I can tell everything should be talking over a single socket ever, the first thing I do is connect to the server in the setup then during the loop the first thing I do is check if I'm connected if I'm not I go to the connectToServer function. In there it should disconnect any sockets (just to make sure) then try and connect to the server until its actually connected and go on with life.

@Pylon I wrote the server side software as well, It only sends one bit back. I figured that would be easier on the arduino side.

If anyone thinks it will help I can post the server code

I wrote the server side software as well, It only sends one bit back. I figured that would be easier on the arduino side.

Even though you wrote the server yourself, I would check if it really does what you expect it to do by controlling the traffic between the two. Sometimes there is some little fact forgotten in the programming or you use a library that inserts another character which you didn't realize yet.

If the server code is of acceptable size, post it, it may give us hints to the problem.

The server code is a little large (its simply but a little longer then I should probably post on here)

But I did more testing and it looks like every time the Arduino locks up it locks up on the

client.println("GetStatus=1");

It still takes somewhere between a day or two for it to lock up. I'm not sure if there is a network issue or if there isn't a timeout on the println function ?

Do you ever see this message on the serial monitor?

In connectToServer

@SurferTim

Yeah, It connects and I see it passing data for 12 ~ 36 then it stops on the

Client.Println("GetStatus=1")

I've updated the code a little bit with a couple more Serial.prints basicly I now have this

void loop {
  if (!client.connected){
    connectToServer();
  } else {
    Serial.println("Here1");
    Client.Println("GetStatus=1");
    Serial.println("Here2");
    if (client.dataavaiable()){
      Serial.println("Here3");
      data = Client.read();
      Serial.println("Here4");
   }
   Client.flush();
}

The above code is not exact I will post exact tonight but it always stops after "Here1" and before "Here2"

since I check right before that if I'm connected and only get to those lines if I am connected I know that the commuication is working. Plus I can see it on the server side

Thanks

You don't do lots of error handling. Try replacing your line:

client.println("GetStatus=1");

by

client.clearWriteError();
client.println("GetStatus=1");
if (client.getWriteError()) {
  client.stop();
  Serial.println("Client write failed, stopping.");
}

Does that change anything?

Thanks … I’m running this code now, we will see if it locks up

#include <Dhcp.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <EthernetUdp.h>
#include <util.h>
#include <SPI.h>

byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xC2 }; 
byte server[] = { 
  10,100,2,158 };
int port = 22490;

int tempOpenLED = 9;
int closeLED = 5;
int openLED = 7;

int SDCard = 4;

EthernetClient client;

void setup() {

  pinMode(SDCard,OUTPUT);
  digitalWrite(SDCard,HIGH);
  pinMode(tempOpenLED, OUTPUT);  
  pinMode(closeLED, OUTPUT);
  pinMode(openLED, OUTPUT);


  digitalWrite(tempOpenLED, HIGH);   
  digitalWrite(openLED, HIGH);  
  digitalWrite(closeLED, HIGH); 

  Serial.begin(9600);
  Ethernet.begin(mac);  

  digitalWrite(tempOpenLED, LOW); 
  digitalWrite(openLED, LOW);
  digitalWrite(closeLED, LOW);


  digitalWrite(tempOpenLED, HIGH);   
  delay(100);             
  digitalWrite(tempOpenLED, LOW);    
  delay(100); 
  digitalWrite(openLED, HIGH);   
  delay(100);             
  digitalWrite(openLED, LOW);    
  delay(100); 
  digitalWrite(closeLED, HIGH);   
  delay(100);             
  digitalWrite(closeLED, LOW);    
  delay(100); 

  connectToServer();
}

long previousMillis = 0;
long previousMillis2 = 0;
long interval = 100; 
long interval2 = 500;

void loop() {
  unsigned long currentMillis = millis();
  if (!client.connected()){
    connectToServer();
  } 
  else {
    Serial.println("Here1");  //Stopped Here
    if(currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;   
      digitalWrite(tempOpenLED, !digitalRead(tempOpenLED)); 
    }
    Serial.println("Here2");
    client.clearWriteError();
    client.println("GetStatus=1");
    if (client.getWriteError()) {
      client.stop();
      Serial.println("Client write failed, stopping.");
    }
    Serial.println("Here3");
    int availableBytes = 0;
    availableBytes = client.available();

    if (availableBytes > 0) {
      int gState = client.read();
      Serial.println("Here4");
      if(currentMillis - previousMillis2 > interval2) {
        previousMillis2 = currentMillis;   
        digitalWrite(closeLED, !digitalRead(closeLED)); 
      }
    }
    client.flush();
    Serial.println("Here5");
  }
}

void connectToServer(){
  Serial.println("In connectToServer");
  client.stop();

  for (int count = 0; count < 4; count++)  {
    digitalWrite(tempOpenLED, !digitalRead(tempOpenLED));  
    digitalWrite(closeLED, !digitalRead(closeLED));  
    digitalWrite(openLED, !digitalRead(openLED));
    delay(200);   
  }
  digitalWrite(tempOpenLED, LOW);  
  digitalWrite(closeLED, LOW);  
  digitalWrite(openLED, LOW);

  client.connect(server, port);
  Serial.println("Leaving connectToServer");
}

The last thing I would see on the serial monitor was “Here2” that’s how I knew it would stop at the client.println

Same thing …

Where do I find the code for client.println? Doesn’t that have a timeout function in it ?

Where do I find the code for client.println? Doesn't that have a timeout function in it ?

In hardware/arduino/cores/arduino/Print.cpp and no, it doesn't have a timeout function in it.

Same thing ...

And what do you get in the serial monitor?

Are you certain it is the client.println()? I have not used client.clearWriteError().

    Serial.println("Here2");
    client.clearWriteError();
    Serial.println("Here2a");
    client.println("GetStatus=1");

I have not used client.clearWriteError().

client.clearWriteError() resets an class-internal variable. Would be very strange if it freezes there.

I'm sure that it happens on the client.println();

Doesn't it seem like that function should have a timeout, anyone have any idea if client.write will timeout ?

Doesn't it seem like that function should have a timeout, anyone have any idea if client.write will timeout ?

client.write() doesn't have a timeout functionality. If the hardware hangs (for whatever reason) it'll never return. You can add a timeout yourself. BTW: most socket libraries of todays operating system also don't have a timeout. In the OS world you can use and alarm signal to catch a hanging send() call while in the Arduino world the watchdog is probably what you're looking for.

I thought thatt I had it ... I changed all the client.println("stuff") to client.write("stuff\n") and it worked great about two weeks, now its doing the same things

locking up on the send