Ethernet. No connection freezing sketch.

I am using the following code to upload some log data (of events that have happened) to a web server based php script, which in turn records the received data into a log file.

All works 99.999999 %, except on a few rare occasions, my dsl connection to my ISP fails ( due to external reasons ), and then the code freezes for a very long time ( I think in the range of a few minutes ). Absolutely nothing on the board responds, which leads me to think that the ethernet board is locking-up the main loop while it tries, continually without success, to connect to the web server IP address. This extended delay / freeze is a problem for my application of the Arduino board. I need to reduce the freeze time and get back to the main loop.

Any idea as to what, in the code, is causing the freezing, and then how can I modify it to abort the upload if the connection does not exist ?

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <SD.h>
#include <EEPROM.h>
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xAD, 0xAD, 0xBE, 0xBE, 0xFE, 0xFE}; //physical mac address
IPAddress ip(192,168,1,101);         // ip in lan
IPAddress gateway(192,168,1,1);  // internet access via router
IPAddress subnet(255,255,255,0); //subnet mask
IPAddress myserver(41,21,1,1);    // web server IP address
EthernetServer server(82);          //server port
EthernetClient client;
String readString; 

// in the main loop if there has been no other activity for 4 seconds :
  UploadLogData();


// and after the main loop

void UploadLogData(){

  // check if data exists in the array
  if (LogNext >= 1){
    if (client.connect(myserver, 80)) {
      client.print("GET http://www.xxx.co.za/xxx.php?data=");
  
      // make a string of all the codes to upload  
      for(int i = 0;i < 30;i++){
        if(LogData[i] != 0){
            client.print(LogData[i]);
            client.print("-");
        }
      }
      client.println(" HTTP/1.1");
      client.println("Host: www.xxx.co.za");
      client.println();
      delay(250);
      client.stop();
    } 
    ClearLogArray();   // separate code to clear the uploaded log data array
  }
}

You are not reading the response from the server. This will have two adverse effects.

  1. If the rx buffer has anything in it, the connection may not close. You will eventually run out of sockets, and it will fail from there on out.
  2. The server may not process what you sent. You must read the response to get a clean close on the connection and determine what the server did with your request.

You are also sending a lot of packets. Every call to client.print, client.println, or client.write generates a packet.

This code has all required to handle repeating requests, even a timeout if the connection fails.
http://playground.arduino.cc/Code/WebClient

@SurferTim

Many Thanks for the reply, link, and guidance.

I will work on modifying my code as the sample in the link.

However, in the line :

if(client.connect(ipBuf,80))

wouldn't a significant delay still be experienced if the dsl to ISP link is down ?

From looking at the sample code, it looks like the timeout management in the code is for the receiving of the response from the server. I don't see anything there that would restrict the amount of time that the client.connect action would keep trying ( and freezing the system ).

I experienced this first hand a few days ago. Got in the car, lightning hit the dsl line, link to ISP died, board froze ( i think due to continually trying to 'client.connect' ) and I sat there in the parking area, surrounded by a shiny new 10ft high electric fence, no keys for gates, and the Arduino not responding to my repeated and frustrated presses of the remote control buttons to open the electric lock on the gates. I won't go into the details of how I had to break back into my own house in the pouring rain.

This is tcp. It has fault tolerance built-in if you have a mind to use it. But the fault tolerant nature has delays at times. You cannot force a connection to happen faster than it can. If you try, you are "cruising for a bruising".

If the connection breaks due to hardware failure enroute, that is the longest delay. It is 10 seconds. But it will continue after the connection is re-established. That is better than a fail and lockup!

lightning hit the dsl line, link to ISP died

OK, a couple million volts one way or the other could affect the performance.

Thanks again SurferTim

From your explanation, I go back to my original code :

if (client.connect(myserver, 80)) {

Although you have already shown that my original code is not ideal, the 'IF client.connected' check should have timed out after a maximum of 10 seconds, and none of the rest of the code should have any relevance, due to the failure of the IF check.

So why did it freeze for a few minutes ?

My only thought of a possibility here, is that each 'event' handled by the Arduino adds an 'event number' to the LogData array, and that is attempted to be written to the web server php script ( which receives the event numbers in the 'get' and converts them to a text explanation of the event ) with the following :

if (currentMillis - LogLastMil >= 4000){  //upload the data to the online file if no activity for 4 seconds
  UploadLogData();
}

and each time the client.connect takes 10 seconds to timeout, and at the end of the 10 seconds the 4000ms has already passed, and the main loop again calls 'UploadLogData' and sits for another 10 seconds, and this could happen a number of times, adding up to a few minutes 'freeze' ?

Does this sound logical ? I am wanting to try to understand exactly why the freeze occurred.