[Solved] Uno & W5100 ping but don't respond after random amount of time.

I have built two cistern sensors that both seem to have this ailment. They stop replying on port 80, but still ping. The amount of time that this happens in seems to be very random from an hour or so to almost a day.

They aren’t in cisterns or waterproof enclosures, as they are still in development.

The device is powered by PoE so they only have one wire. When they mess up, I can turn PoE off and back on, for that port from the switch and they come back to life.

It’s a super simple design of a Uno, W5100 ethernet module, an ultrasonic range finder on pins 2&3, and a DHT22 on pin 4

When they have problems, they still ping, so I know there are not network problems. Both devices are identical physically and in code. One is connected to a Cisco 3750G, the other is connected to a Cisco 3750.

They both have unique MAC addresses by REMark-ing out the line for the other device’s MAC address.

One of them performed flawlessly for 3 days before it had a problem. They are configured to reboot every 24 hours to prevent memory fragmentation etc…

#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include <SPI.h>
#include <Ethernet.h>
// Remember Ethernet uses pins 10-13, so they can not be used
#define TRIGGER_PIN 3  //  Pin to trigger rangefinder
#define PWM_OUTPUT_PIN 2  //  Pin to listen to Rangefinder
#define DHTPIN 4     // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

long duration;  //  Time for ping to reply (ms)
float distance;  //  Distance calculated by time to reply (inches)
float Volume_Current;  //  Current Volume of water
float Gallons_Per_Inch;  //  Calculated how many gallons per inch of water depth
float Temperature;  // Temperature at top of Cistern
float Volume_Total = 1800;  //  Total capacity when full (gallons)
float Distance_Bottom = 61;  // Distance to sensor when empty (inches)
float Distance_Top = 12;  //Distance to Sensor when full (inches)
//Remark out whichever this is not
//byte mac[] = { 0x00, 0x0C, 0xE2, 0xDE, 0xC0, 0x8D };  //  Byte Array of MAC address Irrigaiton
byte mac[] = { 0x00, 0x0C, 0xE2, 0xAB, 0x0F, 0x46 };  //  Byte Array of MAC address Fresh
unsigned long DHT22_Check_Time;  // When (Millis) did you check the DHT22 last?


EthernetServer server(80);
DHT dht(DHTPIN, DHTTYPE);


void setup()
{
  dht.begin();
  Ethernet.begin(mac);
  server.begin();
  Serial.begin(9600);

  Serial.println(Ethernet.localIP());
  pinMode(TRIGGER_PIN, OUTPUT);
  pinMode(PWM_OUTPUT_PIN, INPUT);

  Gallons_Per_Inch = Volume_Total / (Distance_Bottom - Distance_Top);
  delay(2000);  // Make sure the DHT is initialized before you start
  DHT22_Check_Time = 0;  //  Make sure we start at 0
}

void(* resetFunc) (void) = 0;  //declare reset function at address 0

void loop()
{
  EthernetClient client = server.available();
  if (client) { 
    while (client.connected()) {
      if (client.available()) { 
        client.print(millis()/1000);  // For Testing
        client.println(" Sec Uptime"); // For Testing
 // The sensor is triggered by a falling edge of a HIGH pulse that 
 // is more than 60 microseconds in duration.
 // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
        digitalWrite(TRIGGER_PIN, LOW);
        delayMicroseconds(5);
        digitalWrite(TRIGGER_PIN, HIGH);
        delayMicroseconds(100);
        digitalWrite(TRIGGER_PIN, LOW); 
 // Read the signal from the sensor: a HIGH pulse whose
 // duration is the time (in microseconds) from the sending
 // of the ping to the reception of its echo off of an object.
 // If no object detected, fixed pulse width of 35ms is sent
 // by the sensor.
        pinMode(PWM_OUTPUT_PIN, INPUT);
        duration = pulseIn(PWM_OUTPUT_PIN, HIGH);
 // Convert the pulse width duration into a distance
        distance = duration;
        distance = (distance / 58)/2.54; 
        Volume_Current = (Distance_Bottom - distance) * Gallons_Per_Inch;
        client.print(distance);
        client.println(" in");     
        client.print(Volume_Current);
        client.println(" gal");  
        client.print(Temperature);
        client.println(" F");
        client.println("Empty");
        client.println("Empty");
        client.println("Empty");
        client.println("Empty");
        client.println("Empty");
        client.println("Empty");
         }
        break;
          
       }
     }

      
   client.stop(); 
 if (millis() > 86400000) resetFunc(); //call reset when it's been up for over 24 hours to renew DHCP and maintain stability make this shorter if your DHCP leases < 24H or use ethernet.maintain()
 if (millis() > (DHT22_Check_Time + 300000)) {  // Make sure we donly do this every 5 min because it takes along time
  Temperature = (dht.readTemperature(true));  // read temperature. The true makes it F
  DHT22_Check_Time = millis();  // Reset our read time to the current time since we just checked it
 }

}

Remove your call to what you name resetFunc(). This isn't actually doing a reset but restarts the program which is not the same. As you don't do any dynamic memory allocation the problem of memory fragmentation shouldn't occur.

Ping are handled by the Wiznet5100 hardware.

What do you get if the problem starts? A timeout or a connection refused?

Timeout on port 80.

I went back to the basics, updated IDE and all packages on my machine.
Cleaned up all old versions of all the libraries I am using in my libraries folders.
I went in and added serial.write commands everywhere it does something that tells what it is doing, and have one module connected to my machine with Tera Term monitoring it and logging everything to a file so I can tell where it crashed to know which direction to go in...
Then I reloaded the modules.
So far one of the devices has been up for 29 hours continuously, and the other has been up for 21 hours continuously with no problems. Once we get out to a few days, I'll mark it resolved if that is the case.

I've played with disconnecting power to each sensor while it is running to see if that causes a crash, which didn't.

Things have been running cleanly for days now. Updating all things and cleaning out old versions of relevant libraries in IDE seems to have resolved this problem.

It's back...

It seems that sometimes I get a good upload, and sometimes I don't.

The device will ping, but you can't connect to port 80 for the server. This is happening on multiple Arduinos

Interestingly enough, one of them came back from the dead. I issue a reset after millis = 24h, and one came back without having to be rebooted...

Fresh install of IDE. All packages are at the latest version.

The device will ping, but you can't connect to port 80 for the server. This is happening on multiple Arduinos

What are the clients? The W5100 has 4 sockets available, so after 4 connections it won't open another one. If one client opens several of them and keeps them open for whatever reason it will block the complete device. An Arduino is not suited to handle end user browser requests (other than for debugging).

That's a huge piece of info. Thank you.

Would the client.stop(); command close the connection, so it is available again?

Is there any other way to close that, or all connections that I could do on some interval?

Would the client.stop(); command close the connection, so it is available again?

As I understood it that closes the connection but the chip will wait for some minutes for the other side to acknowledge the end of the connection. During this state the socket will not be available for reuse.

Is there any other way to close that, or all connections that I could do on some interval?

Reset the chip. Not all modules offer that signal externally.

Do these questions mean you don't have control over the clients accessing the device?

Yes, I do. One of them is my phone, which is just Chrome. The other is also an arduino with this code:

void PollSensor(IPAddress server, byte index) {
  // Lets get some variables.  Putting them here frees up dynamic memory and reduces fragmentation
  String Line_1 = "";  // String used for creating floats
  String Line_2 = "";  // String used for creating floats
  String Line_3 = "";  // String used for creating floats
  String Line_4 = "";  // String used for creating floats
  String Line_5 = "";  // String used for creating floats
  String Line_6 = "";  // String used for creating floats
  String Line_7 = "";  // String used for creating floats
  String Line_8 = "";  // String used for creating floats
  String Line_9 = "";  // String used for creating floats
  String Line_10 = "";  // String used for creating floats
  
  client.stop();    // close any connection before send a new request.
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    if (Verbose_Debugging) Serial.print("connecting to ");
    if (Verbose_Debugging) Serial.println(server);
    // send the HTTP GET request:
    client.println("GET /latest.txt HTTP/1.1");
    client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println();
    Line_1 = client.readStringUntil('\n');  //Read the line untill you get to a End of line
    Line_2 = client.readStringUntil('\n');  //Read the line untill you get to a End of line
    Line_3 = client.readStringUntil('\n');  //Read the line untill you get to a End of line
    Line_4 = client.readStringUntil('\n');  //Read the line untill you get to a End of line
    Line_5 = client.readStringUntil('\n');  //Read the line untill you get to a End of line
    Line_6 = client.readStringUntil('\n');  //Read the line untill you get to a End of line
    Line_7 = client.readStringUntil('\n');  //Read the line untill you get to a End of line
    Line_8 = client.readStringUntil('\n');  //Read the line untill you get to a End of line
    Line_9 = client.readStringUntil('\n');  //Read the line untill you get to a End of line
    Line_10 = client.readStringUntil('\n');  //Read the line untill you get to a End of line
//Each index decides which GLOBAL variable the answers get stored in
    if (index == 1){  // - Irrigation Cistern
      if (Verbose_Debugging) Serial.println("Index 1");
      Irrigation_Uptime = (Line_1.toFloat());
      Irrigation_Distance = (Line_2.toFloat());
      Irrigation_Gallons = (Line_3.toFloat());
      Irrigation_Temperature = (Line_4.toFloat());
    }
//End of index.  Copy between this note and the earlier note to make another.
//Each index decides which GLOBAL variable the answers get stored in
    if (index == 2){  // - Fresh Cistern
      if (Verbose_Debugging) Serial.println("Index 2");
      Fresh_Uptime = (Line_1.toFloat());
      Fresh_Distance = (Line_2.toFloat());
      Fresh_Gallons = (Line_3.toFloat());
      Fresh_Temperature = (Line_4.toFloat());
    }
//End of index.  Copy between this note and the earlier note to make another.
  } else {
    // if you couldn't make a connection:
    Serial.print("connection failed to ");
    Serial.println(server);
  }

I didn’t include the entirety, as the whole sketch is over 500 lines.

Chrome is pesky as it tries to connect again after an initial request to get an .ico file from the server. This might cause an issue. Have you tried operating on another port instead of port 80?

Yes, I do. One of them is my phone, which is just Chrome.

So you don't as you don't have control over Chrome.

An Arduino with a W5100 board isn't suited to handle browser client requests. Modern browser tend to open a lot of other connections and requests to the same server (as zoomcat already noted) which the Arduino isn't able to handle correctly. Put a real webserver in-between, for example a Raspberry Pi with an Apache on it (or something similar). That way you can check the request on that machine and send controlled requests to the Arduino.

"An Arduino with a W5100 board isn't suited to handle browser client requests."

Well, you might need to couch that in a "IMHO" classification. I've never had issues with Internet Explorer accessing an arduino with a w5100 ethernet board. Chrome might settle down if it is fed some type of .ico file to chew on.

Well, you might need to couch that in a "IMHO" classification. I've never had issues with Internet Explorer accessing an arduino with a w5100 ethernet board. Chrome might settle down if it is fed some type of .ico file to chew on.

I don't write that it cannot handle such requests but you shouldn't plan your project the way that the Arduino handles browser requests itself. Even if the browser don't open too many sockets to the board you don't know if multiple browsers access the device at the same time or if someone uses another browser than you developed with. To make it short: an Arduino is not a web server although it may handle HTTP requests.