Arduino Uno with Ethernet freezes when reading data

Hello everyone!
I have the problem I mentioned in the title.. So I have connected Arudino with Ethernet shield to my website to read data between "<" and ">" using a couple of tutorials I found all over the internet. So when it reads 1 it turns on an LED, when there is 0 it turns off an LED nad this works just fine. The problem is that after a while, sometimes few seconds, sometimes a few minutes the Arduino just freezes and won't do anything. When I start (or restart) Serial monitor Arduino starts working again just fine until it freezes again. Does anyone know what could be the problem?
The code is below.
Thank you in advance!

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

////////////////////////////////////////////////////////////////////////
//CONFIGURE
////////////////////////////////////////////////////////////////////////
//byte server[] = { 174,123,231,247 }; //ip Address of the server you will connect to
char server[] = "peho1.byethost24.com";
//The location to go to on the server
//make sure to keep HTTP/1.0 at the end, this is telling it what type of file it is
String location = "/elementi/ HTTP/1.0";
String prosli="0";
IPAddress ip(192,168,0,177);

// if need to change the MAC address (Very Rare)
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
////////////////////////////////////////////////////////////////////////

EthernetClient client;

char inString[32]; // string for incoming serial data
int stringPos = 0; // string index counter
boolean startRead = false; // is reading?

void setup(){
  pinMode(6, OUTPUT);
  Serial.begin(9600);
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
}

void loop(){
  String pageValue = connectAndRead(); //connect to the server and read the output

  Serial.println(pageValue); //print out the findings.
  if (pageValue == "1" && prosli=="0"){
    digitalWrite(6, HIGH);
    prosli="1";
    Serial.println("Led On");
  }
  else if (pageValue == "0" && prosli=="1"){
    digitalWrite(6, LOW);
    prosli="0";
    Serial.println("Led Off");
  }
  else{
    Serial.println("Ne radim nista!");
  }
  delay(3000); //wait 5 seconds before connecting again
}

String connectAndRead(){
  //connect to the server

  Serial.println("connecting...");

  //port 80 is typical of a www page
  if (client.connect(server, 80)) {
    Serial.println("connected");
    client.print("GET ");
    client.println(location);
    client.println("Host: peho1.byethost24.com");
    client.println("Connection: close");
    client.println();
    //Connected - Read the page
    return readPage(); //go and read the output
  }
  else{
    return "connection failed";
  }
}

String readPage(){
  //read the page, and capture & return everything between '<' and '>'

  stringPos = 0;
  memset( &inString, 0, 32 ); //clear inString memory

  while(true){

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

      if (c == '<' ) { //'<' is our begining character
        startRead = true; //Ready to start reading the part 
      }
      else if(startRead){

        if(c != '>'){ //'>' is our ending character
          inString[stringPos] = c;
          stringPos ++;
        }
        else{
          //got what we need here! We can disconnect now
          startRead = false;
          client.stop();
          client.flush();
          Serial.println("disconnecting.");
          return inString;
        }
      }
    }
  }
}

Add the serial output below. Does the code lock up after "Reading page" but doesn't display "disconnecting"?

String connectAndRead(){
  //connect to the server

  Serial.println("connecting...");

  //port 80 is typical of a www page
  if (client.connect(server, 80)) {
    Serial.println("connected");
    client.print("GET ");
    client.println(location);
    client.println("Host: peho1.byethost24.com");
    client.println("Connection: close");
    client.println();
    //Connected - Read the page

   // add this serial print
   Serial.println(F("Reading page"));

    return readPage(); //go and read the output
  }
  else{
    return "connection failed";
  }
}

edit: If not, can you be more specific about where in the code you think it is failing. What is the last thing displayed on the serial monitor when it does fail?

It stops at "Connecting" or (more often) at "Connected"..
I'll now add what you've posted and test it...

Let me know what the result is. I expect you will find it will print "Reading page" but will not print "disconnecting".

Yes, that's just right, it stopped after "Reading page", as you said...

As a test, replace your readPage function with this. You can modify it later to retrieve the data you want. Run it for a while to see if this corrects the freezing. If you ever see a "Timeout" message on the serial monitor, your old code would have stopped there.

String readPage() {
  // connectLoop controls the hardware fail timeout
  int connectLoop = 0;

  while(client.connected())
  {
    while(client.available())
    {
      char ch = client.read();
      Serial.write(ch);
      // 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();
  String rtnVal = "Done";

  return rtnVal;
}

I have done it and it's now been running for couple of hours with no problems. I haven't yet seen the "Timeout" message..

Have you seen the output you expect each download? If you do not receive that ">" character, it wouldn't disconnect either, and would freeze.

I haven't checked the out every time, as it's a php script which only reads from database and echos <1> or <0>.
But even if there's nothing written, wouldn't it just disconnect and reconnect, the same as after reading the string?

   else{
          //got what we need here! We can disconnect now

          startRead = false;
          client.stop();
          client.flush();
          Serial.println("disconnecting.");
          return inString;

Note that section of code is an "else". If you do not find the '>' character, that section of code is never executed.

        if(c != '>'){ //'>' is our ending character
          inString[stringPos] = c;
          stringPos ++;
        }
        else{
          //got what we need here! We can disconnect now
          startRead = false;
          client.stop();
          client.flush();
          Serial.println("disconnecting.");
          return inString;
        }

Oh yes, that's true.. I haven't noticed that other "if" after "else if".. Do you think it would work if I added another else, like this:

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

      if (c == '<' ) { //'<' is our begining character
        startRead = true; //Ready to start reading the part 
      }
      else if(startRead){

        if(c != '>'){ //'>' is our ending character
          inString[stringPos] = c;
          stringPos ++;
        }
        else{
          //got what we need here! We can disconnect now

          startRead = false;
          client.stop();
          client.flush();
          Serial.println("disconnecting.");
          return inString;
        }
      }
      else{
        client.stop();
        client.flush();
        Serial.println("disconnecting.");
        return inString;

      }
    }

Do you think it would work if I added another else, like this:

No.

edit: This should work. I haven't checked it for errors tho. I changed the return type to char. If it returns 0 (not '0'), then it did not find the '<' character. Otherwise, it should return '0' or '1' (ascii 48 or 49).

char readPage() {
  char rtnVal = 0;
  char startRead = 0;

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

  while(client.connected())
  {
    while(client.available())
    {
      char ch = client.read();
      Serial.write(ch);
       if(ch == '<') startRead = 1;
       else if(ch == '>') startRead = 0;
       else if(startRead == 1) rtnVal = ch;

      // 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 rtnVal;
}

I would have posted this earlier, but the arduino websites are choking. Something is going wrong with the servers. It is becoming almost impossible to login or post anything. I can't access the reference pages at all now. :frowning:

Thank you a lot! This seems to work, at least for now. I'll leave it running until the morning to see what happens..
There have been a couple of errors, but replacing strings with chars solved them..
Thanks a lot again!

It works like a charm!
Thank you a lot, again! :slight_smile:
May I buy you a beer? :smiley:

You are welcome. Have a beer for me. I'll drink one here. :slight_smile: