Arduino Ethernet - Inconsistent connection

I’ve got a Arduino Ethernet board with code that runs on start-up to read settings from the on-board SD-Card, setup the network accordingly and then try and connect to a page specified. The result of the page determines if a digital output switches on / off. It checks for connection issues and after a reasonable number it resets the board.

Now with testing in a controlled environment this seems to be stable and works fine for a considerable period of time. Running this in various locations within the company the inconsistencies arise.

It’s fine running on the test server but on the various live servers the page is not returning a result.

Any idea on what it could be?

  • Latency to the page
  • Client timeout
  • Memory issue (not enough / leak / handling)

Code follows:

#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
#include <string.h>
#include <avr/wdt.h>

// The select pin used for the SD card
#define SD_SELECT 4
#define ETHERNET_SELECT 10

int ledPin =  7; // LED pin
boolean LEDON = false; //LED status flag
EthernetClient client; // connect to result page

byte mac[6] = {0};
byte ip[4] = {0};
byte st_dns[4] = {0};
byte gateway[4] = {0};
byte subnet[4] = {0};

long timePause;
long timeWait;
char server[20];
char page[20];
int err = 0;

//#define soft_reset()        
void softReset(){
asm volatile ("  jmp 0");
}

void Configure()
{ 
    //Start Serial Port
    Serial.begin(9600);
      
    //Enable SD.
    pinMode(SD_SELECT, OUTPUT);
    digitalWrite (SD_SELECT, LOW);
    
    pinMode(ledPin, OUTPUT);  
    
    //Init SD Card  
    Serial.print("Initializing SD card...");
    
    if (!SD.begin(SD_SELECT)) {
        Serial.println("Card failed, or not present");
        // don't do anything more:
        return;
    }
    Serial.println("card initialized.");
      
    File statusFile = SD.open("net.ini");

    // if the file is available, read from it
    if (statusFile) {
      String SD_read = String(); // configuration settings  
      while (statusFile.available()) {
         char ltr = statusFile.read();
         SD_read += ltr;
       }
       statusFile.close();
      
       char settings[SD_read.length()+1];
       SD_read.toCharArray(settings, SD_read.length()+1);
       Serial.print(settings);
       Serial.println("-------------------");
       
       sscanf(settings, "mac = %x:%x:%x:%x:%x:%x ip = %u.%u.%u.%u dns = %u.%u.%u.%u gateway = %u.%u.%u.%u subnet = %u.%u.%u.%u pause = %d wait = %d server = %s page = %s", 
           &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5],
           &ip[0], &ip[1], &ip[2], &ip[3],
           &st_dns[0], &st_dns[1], &st_dns[2], &st_dns[3],
           &gateway[0], &gateway[1], &gateway[2], &gateway[3],
           &subnet[0], &subnet[1], &subnet[2], &subnet[3],
           &timePause, &timeWait, server, page);
    } else {
       // if the file isn't open, pop up an error:
      Serial.println("error opening net.ini");
    }
}

void connectNetwork()
{
  Serial.println("Connecting to network");
    Serial.print("Mac: "); 
    Serial.print( mac[0], HEX); 
    Serial.print(":");    
    Serial.print( mac[1], HEX);
    Serial.print(":");    
    Serial.print( mac[2], HEX);
    Serial.print(":");    
    Serial.print( mac[3], HEX);
    Serial.print(":");    
    Serial.print( mac[4], HEX);
    Serial.print(":");    
    Serial.println( mac[5], HEX);
    
    Serial.print("IP: ");
    Serial.print( ip[0]);
    Serial.print(".");    
    Serial.print( ip[1]);
    Serial.print(".");    
    Serial.print( ip[2]);
    Serial.print(".");    
    Serial.println( ip[3]);
    
    Serial.print("DNS: ");
    Serial.print( st_dns[0]);
    Serial.print(".");    
    Serial.print( st_dns[1]);
    Serial.print(".");    
    Serial.print( st_dns[2]);
    Serial.print(".");    
    Serial.println( st_dns[3]);
    
    Serial.print("Gateway: ");
    Serial.print( gateway[0]);
    Serial.print(".");    
    Serial.print( gateway[1]);
    Serial.print(".");    
    Serial.print( gateway[2]);
    Serial.print(".");    
    Serial.println( gateway[3]);
    
    Serial.print("SubNet: ");
    Serial.print( subnet[0]);
    Serial.print(".");    
    Serial.print( subnet[1]);
    Serial.print(".");    
    Serial.print( subnet[2]);
    Serial.print(".");    
    Serial.println( subnet[3]);
    
    Serial.print("Server: |");
    Serial.print(server);
    Serial.println("|");
    Serial.print("Page: |");
    Serial.print(page);
    Serial.println("|");
   
    Serial.print("Pause: ");
    Serial.println( timePause);
    Serial.print("Wait: ");
    Serial.println( timeWait);

    Serial.println("-------------------");
    
    //while (true) {}
    //Ethernet.begin(mac, ip, dns, gateway, subnet); 
    Ethernet.begin(mac, ip, st_dns, gateway, subnet);
    Serial.println(Ethernet.localIP());
    delay(1000); 
}  

bool connectAndRead(){
  //connect to the server
    Serial.print("connected to "); Serial.print(server); Serial.print(page); Serial.print(" : ");
    if (client.connect(server, 80)) {
      // Make a HTTP request:
      client.print("GET http://"); client.print(server); client.print(page);
      client.println(" HTTP/1.1");
      client.print("Host: "); client.println(server);
      client.println();
      
      return readPage(); //go and read the output
    }  else {
      
      err ++;
      
      // you didn't get a connection to the server:
      Serial.print("Connection Failed (");
      Serial.print(err);
      Serial.println(")");
      
      return false; // turn of light
    }
}

bool readPage(){
  //read the page, and capture & return everything between '[' and ']'
  int stringPos = 0;
  String inString = "{on:0}";
  bool startRead = false;
  
  while(true){
    if (client.available()) {
      char c = client.read();

      if (c == '[' ) { //'[' is our begining character
        startRead = true; //Ready to start reading the part 
        
        //Serial.println("");
      }else if(startRead){

        if(c != ']'){ //']' is our ending character
          inString.setCharAt(stringPos,c);
          
          //Serial.print(c);
          stringPos ++;
        } else {
           
          //got what we need here! We can disconnect now
          startRead = false;
          client.stop();
          client.flush();
          Serial.print("\"");
          Serial.print(inString);
          Serial.print("\"");
          
          if (inString.indexOf("on:1") > 0) {
            Serial.println(" 1 done.");
            return true; 
          } else {
            Serial.println("0 done.");  
            return false;
          }
        } // if ended
      }
    }
  }

  Serial.println("false");  
  return false;
}

void setup(void)
{   
    Configure();
    connectNetwork(); 
}

void loop()
{
   if (err >= 20)
   {
      err = 0;
      softReset();
   }
    
  //lets check if LED should be lighted
  if (connectAndRead())
  {
      //led has to be turned ON
      digitalWrite(ledPin, HIGH); // set the LED on
      Serial.print("pausing: ");
      Serial.print(timePause);
      Serial.println();
      delay(timePause); // keep light on for 10 seconds
  }
  
  digitalWrite(ledPin, LOW); // set the LED off
  Serial.print("waiting: ");
  Serial.print(timeWait);
  Serial.println();
  delay(timeWait); //wait 1 min / 60 seconds before connecting again
}