Ethernet stops sending data ..

So the code below seems to stop working after about 24hours give or take a few hours… otherwise it works, most of it was just copied from various library examples. When it does fail it still says its connecting(shown on serial monitor) to the web server it just doesn’t print out a response… no 404 or 500 just blank. and the webserver never receives any data… hit reset button and it resumes sending data(so its not web server blocking it)

if any other errors or suggestions or even how to make the program smaller… all criticism is welcome
In a 24hour period it sends about 20,000 results… reason for so many is testing to the extreme… it will always need to poll this often(as its primary purpose is to notify of high wind gusts) but will only send highs and every 5min in the final version

#include "TimerOne.h" // Timer Interrupt set to 2 second for read sensors 
#include <math.h>
#include <SPI.h>
#include <UIPEthernet.h>
#include "DHT.h"

#define DHTPIN 9     // what digital pin we're connected torm
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);

#define WindSensorPin 2 // The pin location of the anemometer sensor 
#define WindVanePin A3 // The pin the wind vane sensor is connected to 
#define VaneOffset -90 // define the anemometer offset from magnetic north

#define server "myweatherserver.com" // url of my webserver(changed for posting)
#define page "/weather/log.php" //php file that takes GET data and posts it to mysql database

#define Location "TheRanch"
#define WeatherSize 4

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

EthernetClient client;

float temperature;
float humidity;

int VaneValue; // raw analog value from wind vane
int Direction; // translated 0 - 360 direction
int CalDirection; // converted value with offset applied
int LastValue; // last direction value

char Weather[WeatherSize][10];

volatile bool IsSampleRequired; // this is set true every 2.5s. Get wind speed
volatile unsigned int TimerCount; // used to determine 2.5sec timer count
volatile unsigned long Rotations; // cup rotation counter used in interrupt routine
volatile unsigned long ContactBounceTime; // Timer to avoid contact bounce in isr
unsigned long Failed = 0;
unsigned long Passed = 0;

float WindSpeed; // speed miles per hour

void setup() {
  Serial.begin(9600);
  dht.begin();
  pinMode(8,OUTPUT);
  digitalWrite(8,LOW);
  if(Ethernet.begin(mac)) digitalWrite(8,HIGH);
  delay(1000);
  LastValue = 0;

  IsSampleRequired = false;

  TimerCount = 0;
  Rotations = 0; // Set Rotations to 0 ready for calculations

  pinMode(WindSensorPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(WindSensorPin), rotation, FALLING);
  
  // Setup the timer interupt
  Timer1.initialize(500000);// Timer interrupt every 2.5 seconds
  Timer1.attachInterrupt(isr_timer);
}

void loop() {
  getWindDirection();

  // Only update the display if change greater than 5 degrees.
  if (abs(CalDirection - LastValue) > 5) {
    LastValue = CalDirection;
  }

  if (IsSampleRequired) {
    // convert to mp/h using the formula V=P(2.25/T)
    // V = P(2.25/2.5) = P * 0.9
    WindSpeed = (Rotations * 0.9) * 0.44704;
    Rotations = 0; // Reset count for next sample

    IsSampleRequired = false;
    Timer1.stop();
    detachInterrupt(digitalPinToInterrupt(WindSensorPin));
    Ethernet.maintain();
    getWeather();
    sendWeather();
    attachInterrupt(digitalPinToInterrupt(WindSensorPin), rotation, FALLING);
    Timer1.start();
  }
}

// isr handler for timer interrupt
void isr_timer() {

  TimerCount++;

  if (TimerCount == 5)
  {
    IsSampleRequired = true;
    TimerCount = 0;
  }
}

// This is the function that the interrupt calls to increment the rotation count
void rotation() {

  if ((millis() - ContactBounceTime) > 15 ) { // debounce the switch contact.
    Rotations++;
    ContactBounceTime = millis();
  }
}

// Get Wind Direction
void getWindDirection() {

  VaneValue = analogRead(WindVanePin);
  Direction = map(VaneValue, 0, 1023, 0, 360);
  CalDirection = Direction + VaneOffset;

  if (CalDirection > 360)
    CalDirection = CalDirection - 360;

  if (CalDirection < 0)
    CalDirection = CalDirection + 360;

}
void getWeather(){
  for(int x = 0; x < WeatherSize; x++) {
    Weather[x][0] = NULL;
  }

  //Read DHT Sensor
  humidity = dht.readHumidity();
  temperature = dht.readTemperature();
  dtostrf(WindSpeed,2,4,Weather[0]);
  dtostrf(CalDirection,2,0,Weather[1]);
  dtostrf(temperature,2,2,Weather[2]);
  dtostrf(humidity,2,0,Weather[3]);
}
byte sendWeather(){
  int inChar;
  char outBuf[128];
  
  if (client.connect(server,80)) {
    Passed++;
    sprintf(outBuf,"GET %s?location=%s&speed=%s&direction=%s&temperature=%s&humidity=%s HTTP/1.1",page,Location,Weather[0],Weather[1],Weather[2],Weather[3]);
    //sprintf(outBuf,"GET %s?location=%s HTTP/1.1",page,Location);
    Serial.print("Sending... ");
    Serial.println(outBuf);
    client.println(outBuf);
    sprintf(outBuf,"Host: %s",server);
    client.println(outBuf);
    client.println(F("Connection: close\r\n"));
  }
  else {
    Failed++;
    Serial.println(F("failed"));
    return 0;
  }
    // connectLoop controls the hardware fail timeout
  int connectLoop = 0;
  Serial.print("Failed: ");
  Serial.println(Failed);
  Serial.print("Passed: ");
  Serial.println(Passed);
  Serial.println();
  while(client.connected())
  {
    while(client.available())
    {
      inChar = client.read();
      Serial.write(inChar);
      // 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();
}

wow page 4 after a few hours.... think im going to start helping out around here:p

  dtostrf(WindSpeed,2,4,Weather[0]);

Do you really think you are measuring wind speed to 4 decimal places?

  dtostrf(temperature,2,2,Weather[2]);

Do you really believe that you are measuring temperature to the nearest 0.01 degrees?

  if (IsSampleRequired) {
    // convert to mp/h using the formula V=P(2.25/T)
    // V = P(2.25/2.5) = P * 0.9
    WindSpeed = (Rotations * 0.9) * 0.44704;
    Rotations = 0; // Reset count for next sample

What is there to stop an interrupt from happening while you are computing wind speed? While you are resetting Rotations?

    Ethernet.maintain();

What is it you think you are maintaining?

We can not see what is actually happening on your system. You need to show your serial output around where you see a failure.

PaulS:

  dtostrf(WindSpeed,2,4,Weather[0]);

Do you really think you are measuring wind speed to 4 decimal places?

  dtostrf(temperature,2,2,Weather[2]);

Do you really believe that you are measuring temperature to the nearest 0.01 degrees?

no and the 2 decimal points is to make averaging more accurate when averaged by the mysql database

  if (IsSampleRequired) {

// convert to mp/h using the formula V=P(2.25/T)
   // V = P(2.25/2.5) = P * 0.9
   WindSpeed = (Rotations * 0.9) * 0.44704;
   Rotations = 0; // Reset count for next sample



What is there to stop an interrupt from happening while you are computing wind speed? While you are resetting Rotations?

that’s a good point, it wouldn’t actually matter as the computation would never take longer than a fraction of a rotation but for best practice I will definitely move the interrupt disconnects up a few lines.

    Ethernet.maintain();

What is it you think you are maintaining?

Ethernet.maintain renews the DHCP lease when needed best practice is to call it at least every second.

We can not see what is actually happening on your system. You need to show your serial output around where you see a failure.

serial output on failure seems to wait a bit to receive data and reads:

Sending... GET /weather/log.php?location=WeatherSolve&speed=1.2090&direction=193&temperature=23.30&humidity=33 HTTP/1.1
Failed: 0
Passed: 15189
disconnecting.

serial output on an actual send happens very quickly and reads:

Sending... GET /weather/log.php?location=WeatherSolve&speed=1.2090&direction=193&temperature=23.30&humidity=33 HTTP/1.1
Failed: 0
Passed: 15189

HTTP/1.1 200 OK
Server: nginx
Date: Fri, 24 Feb 2017 23:42:40 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: close
X-Powered-By: PHP/5.6.26RC1

74
Added The Following...
Location: WeatherStation
Wind Speed: 1.2090
Wind Direction: 193
Temperature: 23.30
Humidity: 33
0


disconnecting.

Ethernet.maintain renews the DHCP lease when needed best practice is to call it at least every second.

From your Ethernet.begin() call, it does not appear that you are using DHCP. Even if you are, is it necessary to retain the lease when acting as a client?

PaulS:
From your Ethernet.begin() call, it does not appear that you are using DHCP. Even if you are, is it necessary to retain the lease when acting as a client?

I am using DHCP and a DHCP lease has to be renewed on timeout(most routers default to 1800seconds) or else the address could be assigned to another client thats why I am not so worried about doing it every 1.5secs but you are supposed to do it sub 1sec