Ethernet shield web server stops responding

I have tried searching the forums and cannot find a similar post to my problem, I am sure its just an issue with my query style. Anyway, I have an Arduino Uno and an Ethernet Shield. I am serving a page using the ethernet library with simple html on it to display a variable in my code. My problem is that seemingly randomly the web page stops responding, sometimes it loads then after a short time if I refresh the browser it will not load. The nic does still respond to ping. I am sure there is something wrong with my code as I am a beginner to the Arduino programming world. Any help or guidance would be greatly appreciated.

#include <Ethernet.h>
#include <Server.h>
#include <Udp.h>
#include <SPI.h>
#include <Time.h>
#include <TimeAlarms.h>

// Setup NIC
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x30, 0x92 };
byte ip[] = { 192,168,100,90  };
Server server(80);

// NTP Time stuff
unsigned int localPort = 8888;      // local port to listen for UDP packets
byte timeServer[] = {192, 43, 244, 18}; // time.nist.gov NTP server
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 

// this constant won't change:
const int buttonPin = 7;    // the pin that the pushbutton is attached to
const int ledPin = 9;       // the pin that the LED is attached to
const double demandConstant = .72 * 4; //constant from utility to multiply count
const int demandChargeTime = 15; //number of minutes utility bases demand
const int demandLimit = 100;

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
double currentDemand = 0; // kW 
int demandLoopCount = 0;
int countArray[demandChargeTime];

void setup() {
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  Udp.begin(localPort);
  server.begin();
  
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
  
  //Set the demand loop every 60 seconds, 5 for testing
  Alarm.timerRepeat(60, Demand);  
  
  //sync time to NTP
  getNTP();
  
  Serial.println("--Demand Meter Ready--");
}

void loop() {
   
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      // Serial.println("on");
      digitalWrite(ledPin, HIGH); //light LED when contact is closed
      Serial.print("Pulse Count: ");
      Serial.print(buttonPushCounter, DEC);
      Serial.println();
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      // Serial.println("off"); 
      digitalWrite(ledPin, LOW); //Shut LED when contact is open
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;

  //need this for repeated loop to work
  Alarm.delay(100);
  
  webServer();
}

void Demand()
{
  if(demandLoopCount <= (demandChargeTime-2))
  {  
    countArray[demandLoopCount] = buttonPushCounter;
    demandLoopCount++;
  }
  else {
    for(int i=0; i <= (demandChargeTime-2); i++)
    {
      countArray[i] = countArray[i+1];
      // Serial.println(countArray[i]);
    }
    
    //demandLoopCount should be 15 here
    countArray[(demandChargeTime-1)] = buttonPushCounter;
    // Serial.println(countArray[(demandChargeTime-1)]);
    currentDemand = demandConstant * (countArray[(demandChargeTime-1)]-countArray[0]);
    Serial.print("Current Demand: ");
    Serial.print(currentDemand);
    Serial.println();
  }
}

void webServer()
{
  // listen for incoming clients
  Client 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 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("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<center><b>Demand Meter</b></center>");
          client.print("
");
          client.print("Demand ");
          client.print(currentDemand);
          client.print(" kW");
          client.print("

");
          client.print(month());
          client.print("/");
          client.print(day());
          client.print("/");
          client.print(year());
          client.print("
");
          client.print(hour());
          client.print(":");
          client.print(minute());
          client.print(":");
          client.print(second());
          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(1);
    // close the connection:
    client.stop();
  }

}

void getNTP()
{
sendNTPpacket(timeServer); // send an NTP packet to a time server

    // wait to see if a reply is available
  delay(1000);  
  if ( Udp.available() ) {  
    Udp.readPacket(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer

    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:

    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;  
            
    // now convert NTP time into everyday time:
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;     
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;  
      
    setTime(epoch);
  }
  // wait ten seconds before asking for the time again
  delay(10000); 
}

// send an NTP request to the time server at the given address 
unsigned long sendNTPpacket(byte *address)
{
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE); 
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49; 
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp: 		   
  Udp.sendPacket( packetBuffer,NTP_PACKET_SIZE,  address, 123); //NTP requests are to port 123
}

My experience is that the ethernet shield needs to be reset between connections. I don’t know why, but I’ve had the same problem where the sketch runs for a while and then hangs. Try calling ethernet.begin(), udp.begin() and server.begin() before each connection.

Going to give that a try today, thanks!

I have a similar application where I'm reading pulses from an gas meter and sending the data to pachube.com. You seem to be reading pulses from an electricity meter and displaying them an a simple web page. I have a problem where my connection to pachube.com hangs. If I cycle power to the Arduino, everything is fine again. I don't know much about internet connections, but maybe I need to do something similar. Where in your code is DCContrarian suggesting you reset the connections? Would it be right before:

Client client = server.available();

What does void Demand() do?

I like how you get time from time.nist.gov. I was grabbing the time from the HTTP response from pachube.

Is the code you posted the complete sketch? I'd like to give your application a try with my gas pulse meter

I have the exact same problem with the Ethernet shield based on a very similar application. i.e. responds to web server requests and posts data to Pachube.

Because the Server must remain connected I don't see how it is possible to call ethernet.begin() on each Pachube update.

Did you solve your problem pubman?

ScottG, Demand() is called every 60 seconds on the Alarm.timerRepeat() callback. For the first 14 minutes it just collects the pushButton occurances. After that it sets the variable currentDemand to the number of pushButton occurences over the last 15 minutes. (I think!)

While I am still playing and testing it seems like DCContrarian's solution has worked for me. Once I have finished the code I will post it all so fellow meter readers can play. Thanks guys.

I found my problem. I am running a server on port 80 and also a Pachube client update on port 80. The server claims all 4 sockets for listening. A new instance of Client doesn't see these sockets are taken and uses one of them for Pachube update. Seems all is well most of the time but eventually a Client return is picked up by the server listen and this causes the program to stop. My solution is to add a new constructor method to the Ethernet Server class to only claim three sockets. Then a new constructor methods to the Client class to use the remaining socket. It has now been working 8 days without a problem.