Arduino Uno R3 + Ethernet hangs after a few day's

Hi everyone,

My first post here hope someone can tell me what i do wrong ... :slight_smile:

The project is for a central heating system. The purpose is to operate it over ethernet.

First of all thank you for reading my post ;).

Arduino uno R3, software v1.0.2 on Mac os x

The problem:
The ethnetnet shield is unreachable after a few day's. I did look for some solutions, i found that my SRAM memory was overflowing so i made a new program. The SRAM usage is printed in web browser and reports over 1300byte of free memory so i guess there is no more problem with the SRAM.
Also when the shield is unreachable the program is still running, so i still have hot water but can not access the web interface anymore.

Comments, suggestions on the code are appreciated :slight_smile:

My program:

byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0x57, 0x49, 0x5A };

IPAddress ip(192,168,2, 38);

static char baseurl[]="http://192.168.2.38/";

byte gateway[] = { 
  192, 168, 2, 1 };
byte subnet[] = { 
  255, 255, 255, 0 };

String readString = "";

EthernetServer server(80);

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

  SetupAnalogInput();

  sensors.begin();
  sensors.setResolution(outsideThermometer, 10);
  
  //test
  pinMode(4, OUTPUT);                  // SD select pin
  digitalWrite(4, HIGH);               // Explicitly disable SD
  pinMode(10, OUTPUT);                  // Ethernet select pin
  digitalWrite(10, LOW);               // Explicitly enable Network

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

  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

  wdt_enable(WDTO_2S);

}
void loop() {

  wdt_reset();

  listenForEthernetClients(Tbuiten,Tketel,Tboiler,Twens); 

  // Every 5 Sec update temperature
  if((long)millis()-eventTimeout>=0) {
    eventTimeout=(long)millis() + 5000;
    sensors.requestTemperatures();
    Tbuiten = GetTemperature(outsideThermometer);
  }


  // Every 3 Sec update verwarming
  if((long)millis()-eventTimeout2>=0) {
    eventTimeout2=(long)millis() + 3000;

    // boiler temperatuur  23°c = 852 90°C= 676ohm => 67°C/155,79
    Tboiler = (23 + ((GetTemperatureVerwarming(A1, 5)-852)  * 430 / 1000));
    // ketel temperatuur omzetting
    //831 -> 1K4 + 540 (23°C) => 3,3V * 540 /(540+1405) / 1,1V/1023 (10bit) = 831
    Tketel = (23 + ((GetTemperatureVerwarming(A0, 5)-852)  * 475 / 1000));


    //Serial.print(Tketel);


    if(mode == 2){
      // Verwarming Dag
      if(Tbuiten <= -10){
        Twens = 70;
      }
      else if(Tbuiten > 27){ 
        Twens = 0;
      }
      else {

        Twens = ( 70 - ((Tbuiten + 10) / k));
      }
    }
    else if(mode == 3){
      // Verwarming Nacht
      if(Tbuiten <= -10){
        Twens = 45;
      }
      else if(Tbuiten > 20){ 
        Twens = 0;
      }
      else {

        Twens = ( 45 - ((Tbuiten + 10) / (2*k)));
      }
    }
    //Do(byte mode, int Tketel, int Tboiler, int Tout, float Twens)
    Viessmann.Do(mode, Tketel, Tboiler, Tbuiten, Twens);

  }


}

//--------------------------------------------------------------------------
void listenForEthernetClients(float fTbuiten, float fTketel, float fTboiler, float fTwens) {


  boolean SBrander = 1;
  boolean SPverw = 1;
  boolean SPboil = 1;
  boolean data_found=0;

  char Tketel[7] = "100.0";
  char Tboil[7] = "100.0";
  char Tbuiten[7] = "100.0";
  char Tomloop[7] = "0.0";

  byte lengte = 0;

  //Serial.print(Tbuit);
  // Convert float to string
  dtostrf(fTbuiten,3,2,Tbuiten);
  dtostrf(fTketel,4,1,Tketel);
  dtostrf(fTboiler,4,1,Tboil);
  dtostrf(fTwens,4,1,Tomloop);


  //clearing string for next read
  readString="";

  //test
  server.begin();



  // listen for incoming clients
  EthernetClient client = server.available();


  if (client) {

    // an http request ends with a blank line
    boolean currentLineIsBlank = true;


    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        if( c == '?')
          data_found = true;

        //read first 100 chars
        //read char by char HTTP request
        if ((lengte < 25) && (data_found)) {

          lengte ++;
          //store characters to string 
          readString += c; 
          //Serial.print(c);

          if (readString.length() > 30) {
            readString = "";
          }


        }
        else if((lengte >= 25) && (data_found)) {


          if(readString.indexOf("cmd=0") >0)//checks for on
          {
            mode = 0; 
          }

          if(readString.indexOf("cmd=1") >0)//checks for on
          {
            mode = 1; 
          }

          if(readString.indexOf("cmd=2") >0)//checks for on
          {
            mode = 2; 
          }

          if(readString.indexOf("cmd=3") >0)//checks for on
          {
            mode = 3; 
          }
          data_found = false; 

        }  

        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {

          // send a standard http response header

          client.println(F("HTTP/1.1 200 OK Content-Type: text/html Connnection: close"));
          client.println();
          client.println(F("<!DOCTYPE HTML><html><meta http-equiv=\"refresh\" content=\"5;URL='"));
          // add a meta refresh tag, so the browser pulls again every 5 seconds:

          client.print(baseurl);

          client.println(F("'\"><center><p><h1>Welcome to Viessmann Atola Ethernet Shield V1.0  </h1></p><hr>
 <h2><font color=\"blue\">-- Status online -- 
 Temperatuur Ketel: "));
          client.print(Tketel);
          client.println(F(" &degC
 Temperatuur Boiler: "));
          client.print(Tboil);
          client.println(F(" &degC
 Temperatuur Buiten: "));
          client.print(Tbuiten);
          client.println(F(" &degC
 Gewenste omloop temperatuur: "));
          client.print(Tomloop);
          client.println(F(" &degC
 
 Status Brander: "));

          if (Viessmann.BranderStatus())
            client.println(F("Aan"));
          else
            client.println(F("Uit")); 

          client.println(F("
 Status Pomp verwarming: "));

          if (Viessmann.PompVerwarmingStatus())
            client.println(F("Aan"));
          else
            client.println(F("Uit"));

          client.println(F("
 Status pomp Boiler: "));

          if (Viessmann.PompBoilerStatus())
            client.println(F("Aan"));
          else
            client.println(F("Uit"));

          client.println(F("
</font></h2></center><hr><center><form METHOD=get>"));


          // knoppen


          if(mode==0)
            client.println(F("<button type=submit name=\"cmd\" value=\"0\"><B STYLE=\"color: red;\">Verwarming Uit</B></button>"));
          else
            client.println(F("<button type=submit name=\"cmd\" value=\"0\">Verwarming Uit</button>"));

          if(mode==1)
            client.println(F("<button type=submit name=\"cmd\" value=\"1\"><B STYLE=\"color: red;\">Enkel Warmwater</B></button>"));
          else
            client.println(F("<button type=submit name=\"cmd\" value=\"1\">Enkel Warmwater</button>"));

          if(mode==3)  
            client.println(F("<button type=submit name=\"cmd\" value=\"3\"><B STYLE=\"color: red;\">Verwarming Nacht</B></button>"));
          else
            client.println(F("<button type=submit name=\"cmd\" value=\"3\">Verwarming Nacht</button>"));

          if(mode==2)  
            client.println(F("<button type=submit name=\"cmd\" value=\"2\"><B STYLE=\"color: red;\">Verwarming Dag</B></button></form></center><hr>"));
          else
            client.println(F("<button type=submit name=\"cmd\" value=\"2\">Verwarming Dag</button></form></center><hr>"));

          client.println(F("FreeMemory: "));
          client.print(freeMemory());
          client.println(F(" KB</html>"));
          client.println();


          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(5);
    // close the connection:
    //client.stop();


    client.stop();


    byte g=0;
    while((client.status() != 0) && g < 100) { // ADDED Aug 2 (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235991468)
      delay(5);
      g++;
      //Serial.println(F("Wait!"));
    }
    client.flush();
    client.stop();


}

Kind regards,

digi128pci:

String readString = "";

Stability problems in a sketch that uses the String class immediately raises the possibility that you have hit the known problem with the String class.

I haven't checked what use you're making of String and it may be blameless in this case, but even if it isn't causing the current problem it is a loaded gun pointed at your foot. I suggest you remove all use of the String class from your sketch and see whether that makes any difference.

If the ethernet shield is connected to a router, have you checked it to see if there any clues there. also, have you counted the number of connections to the arduino before the connection is lost?

Allright! I will remove the strings i used the string for checking if there was an variable added in the URL :).

Anyway, I think its going out of sockets, I cannot connect but program keeps running.
I red about problems with closing the sockets but they were old, don't know if they are still bugs.
I also tried to disable the SD card but still no success.

Can anyone confirm an error / bug with the sockets in wiznet?

Although this is an old post, there were problems with the ethernet lib before arduino 1.0.5.

I saw a memory leak (using a periodic dump of free mem) with older libs after I realized that my arduino also stopped sending ethernet packets after some days. These probs were gone after using arduino 1.0.5 and the arduino runs since several weeks and months now.

Bad news for using enc28j60 ethernet shields, I am using a pollin netio with arduino compatible boot loader etc called netino. This guy still needs a watchdog to prevent it from hanging around.

~josef