Ethernet Shield going to sleep??

So for some reason, my Ethernet shield stops responding after some random amount of time. When I try to access the IP address it works for a while. If I leave it for a long time and I try to access it I cant connect to it. If I open up the Arduino software and start the serial monitor, com 3, I can access the arduino again. Anyone have any ideas whats going on? Is the shield going to sleep or is my code crashing for some reason? There is a bit ore code than what is below, but it has no real effect on the web server side of things.

Thanks!

/*
  Web  Server
 
 A simple web server that shows the value of the analog input pins.
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 * Analog inputs attached to pins A0 through A5 (optional)
 
 created 18 Dec 2009
 by David A. Mellis
 modified 4 Sep 2010
 by Tom Igoe
 
 */

#include <SPI.h>
#include <Ethernet.h>



#define maxLength 60

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x5A, 0xFA };
byte ip[] = { 192,168,0, 177 };

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
Server server(80);

//define setpoints for fermenter temps
String inString = String(maxLength);
long previousMillis = 0;
int setferm1 = 300;
int setferm2 = 300;
int setferm3 = 300;
int setferm4 = 300;
int Posa = 0;
int Posb = 0;
int Posc = 0;
int Posd = 0;
int whichTank = -1;
int chillValue = 10;
char tempBuff[4];
int chill = 0;
int valveToOpenIdx = -1;
double volts = 0.486328125;
int TempSensor1 =0;
int TempSensor2 =0;
int TempSensor3 =0;
int TempSensor4 =0;


void setup()
{
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  // initialize serial communications at 9600 bps:
  Serial.begin(9600); 
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  
 
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, LOW);
  
 }

void loop()
{
  //Get Temps off sensors
  analogRead(1);
  delay(10);
  TempSensor1 = 0;
  for (int i = 0; i < 10; i++) {
    TempSensor1 = TempSensor1 + round(volts*analogRead(1)); 
  } 
  analogRead(2);
  delay(10);
  TempSensor2 = 0;
  for (int i = 0; i < 10; i++) {
    TempSensor2 = TempSensor2 + round(volts*analogRead(2)); 
  } 
  analogRead(3);
  delay(10);
  TempSensor3 = 0;
  for (int i = 0; i < 10; i++) {
    TempSensor3 = TempSensor3 + round(volts*analogRead(3)); 
  }
  analogRead(4);
  delay(10);
  TempSensor4 = 0;
  for (int i = 0; i < 10; i++) {
    TempSensor4 = TempSensor4 + round(volts*analogRead(4)); 
  }  
  TempSensor1 = round(TempSensor1/10);
  TempSensor2 = round(TempSensor2/10);
  TempSensor3 = round(TempSensor3/10);
  TempSensor4 = round(TempSensor4/10);
    
  
  // Web Interface
  int bufLength = 4;
  // listen for incoming clients
  Client client = server.available();
  if (client) {
    // an http request ends with a blank line
   // Serial.println(client.read());

    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (inString.length() < maxLength) {
          inString += c;
         }        
        // 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
          if (inString.indexOf("?") > -1) {
            Posa = inString.indexOf("a");
            Posb = inString.indexOf("b");
            Posc = inString.indexOf("c");
            Posd = inString.indexOf("d");
            
            inString.substring((Posa+2), (Posb-1)).toCharArray(tempBuff, bufLength);  //transfer substring to buffer
            setferm1 = atoi(tempBuff);
            inString.substring((Posb+2), (Posc-1)).toCharArray(tempBuff, bufLength);  //transfer substring to buffer
            setferm2 = atoi(tempBuff);
            inString.substring((Posc+2), (Posd-1)).toCharArray(tempBuff, bufLength);  //transfer substring to buffer
            setferm3 = atoi(tempBuff);
            inString.substring((Posd+2), (Posd+5)).toCharArray(tempBuff, bufLength);  //transfer substring to buffer
            setferm4 = atoi(tempBuff);
           
         }

          
          
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          
          client.print("<font size=32 color=CDAD00><b><u>HGB Fermenter Control</u></b></font>

 ");
          
          // output the value of each analog input pin
          client.print("<font size=32>Temperature of Fermenter 1 is ");client.print(TempSensor1);client.println("</font>
");
          client.print("<font size=32>Temperature of Fermenter 2 is ");client.print(TempSensor2);client.println("</font>
");
          client.print("<font size=32>Temperature of Fermenter 3 is ");client.print(TempSensor3);client.println("</font>
");
          client.print("<font size=32>Temperature of Fermenter 4 is ");client.print(TempSensor4);client.println("</font>
");
          
          client.print("

<form method=get><font size=32>");
          client.print("Setpoint Fermenter 1: <input type=text style=font-size:32pt size=3 name=a value="); client.print(setferm1);client.print(" />");
          if (valveToOpenIdx == 0) {
            client.print(" Open");
          }
          else {
            client.print(" Closed");
          }
          client.print("
");
          client.print("Setpoint Fermenter 2: <input type=text style=font-size:32pt size=3 name=b value="); client.print(setferm2);client.print(" />");
           if (valveToOpenIdx == 1) {
            client.print(" Open");
           }
           else {
            client.print(" Closed");
          }
          client.print("
");
          client.print("Setpoint Fermenter 3: <input type=text style=font-size:32pt size=3 name=c value="); client.print(setferm3);client.print(" />");
           if (valveToOpenIdx == 2) {
            client.print(" Open");
           }
          else {
            client.print(" Closed");
          }
          client.print("
");
          client.print("Setpoint Fermenter 4: <input type=text style=font-size:32pt size=3 name=d value="); client.print(setferm4);client.print(" />");
           if (valveToOpenIdx == 3) {
            client.print(" Open");
           }
          else {
            client.print(" Closed");
          }
          client.print("
");
          client.println("
");
          client.print("<input type=submit value=Update-Temps style=height:6em; width:24em />");
          client.print("</font></form>");
          client.println("
");
          
          
          
          
          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);
    inString = " ";
    // close the connection:
    client.stop();
  }

I had some trouble with the w5100 ethernet shield powered thru USB. To have a reliable power source I added a 12V power supply and a 9V rechargeable battery (charged with a 1K resistor from 12V and with a diode to power the board when external power is not available).

By default, when you open the serial monitor you apply a reset to arduino, but in some cases the ethernet might not start. My W5100 ethernet shield (the older version) have also a reset bug and the workaround was a small delay in the begining of setup function (delay(50)).

Hope it helps

adis:
I had some trouble with the w5100 ethernet shield powered thru USB. To have a reliable power source I added a 12V power supply and a 9V rechargeable battery (charged with a 1K resistor from 12V and with a diode to power the board when external power is not available).

By default, when you open the serial monitor you apply a reset to arduino, but in some cases the ethernet might not start. My W5100 ethernet shield (the older version) have also a reset bug and the workaround was a small delay in the begining of setup function (delay(50)).

Hope it helps

Thanks for the response. Unfortunatenly it will do this when powered off both the USB or a 12V plug in adapter.

I had not realized that opening the serial monitor applied a reset, so that is good to know.

I dont have the ethernet shield infront of me at the moment, but I just purchased it the other day, so I would assume its the most up to date version?

Any other ideas anyone?

Could be that it's running out of memory; This is especially possible if you have a lot of strings.

Arrch:
Could be that it's running out of memory; This is especially possible if you have a lot of strings.

I dont really have any strings in my code, but I do pull information fairly rapidly. Is there a line of code I can use to clear out the memory everytime it runs through the void loop?

This is not the problem... but why not using something like this

int TempSensor[4] = {0,0,0,0};

int j = 0;
void loop()
{

for (j = 0; j<4; j++)
{
  analogRead(j+1);
  delay(10);
  TempSensor[j] = 0;
  for (int i = 0; i < 10; i++) {
    TempSensor[j] = TempSensor[j] + round(volts*analogRead(j+1)); 
  }
TempSensor[j] = round(TempSensor[j]/10);
}

to get the temperature readings instead of the copy/paste code?

Do you think 1ms is enough for the webbrowser to receive the data?
Because, the problem is not really the web browser receiving the data, is the data being transferred from Arduino to the W5100. That's your bottleneck, and yes, you do have quite a bit of data to be sent. Since the W5100 works in a buffered way, chances are that you may be closing the connection before all the data is transferred. Give it a go in increasing this to 100 or so and see what you get.
With these things you start up and go down, not the other way around.

bubulindo:
This is not the problem... but why not using something like this to get the temperature readings instead of the copy/paste code?

Do you think 1ms is enough for the webbrowser to receive the data?
Because, the problem is not really the web browser receiving the data, is the data being transferred from Arduino to the W5100. That's your bottleneck, and yes, you do have quite a bit of data to be sent. Since the W5100 works in a buffered way, chances are that you may be closing the connection before all the data is transferred. Give it a go in increasing this to 100 or so and see what you get.
With these things you start up and go down, not the other way around.

Thanks! I knew that code was not optimized. I'm not the best code writer. I've been picking it up as I go along. I'm a mechanical engineer and have no good reason to be messing with things electrical :stuck_out_tongue_winking_eye:

My web page refreshes and looks fine and the data seems to be updating perfectly well? I'll change the time as suggested to 100 ms.

It's really only when I wait for a while inbetween requesting data from the Arudino. It may no tbe the ethernet sheild going to sleep, something else might be happening...

Can you at least ping the shield when you don't receive a reply with the browser?

bubulindo:
Can you at least ping the shield when you don't receive a reply with the browser?

Good question. I'll give that a try next time it freezes up. It's actually been running for like 24 hours without freezing up, so maybe some of the small fixes I made have helped?

Cruelkix:

Arrch:
Could be that it's running out of memory; This is especially possible if you have a lot of strings.

I dont really have any strings in my code, but I do pull information fairly rapidly. Is there a line of code I can use to clear out the memory everytime it runs through the void loop?

In the code you posted, you had plenty of strings. Maybe change all the client.prints to a single letter or something and give that a try. That should be a start.

Arrch:

Cruelkix:

Arrch:
Could be that it's running out of memory; This is especially possible if you have a lot of strings.

I dont really have any strings in my code, but I do pull information fairly rapidly. Is there a line of code I can use to clear out the memory everytime it runs through the void loop?

In the code you posted, you had plenty of strings. Maybe change all the client.prints to a single letter or something and give that a try. That should be a start.

Ahhh, by strings i thought you meant variables that were stored as strings, not lines of code that contain strings.

I changed the code up a good bit to be more efficient after the other guy showed me how bad my tempsensor code was as far as efficiency is concerned. My current code is as follows:

#include <SPI.h>
#include <Ethernet.h>



#define maxLength 60

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x5A, 0xFA };
byte ip[] = { 192,168,0, 177 };

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
Server server(80);

//define setpoints for fermenter temps
String inString = String(maxLength);
long previousMillis = 0;
int setferm[4] = {300,300,300,300};
int Posa = 0;
int Posb = 0;
int Posc = 0;
int Posd = 0;
String Whereto[4] = {"a","b","c","d"};
int whichTank = -1;
int chillValue = 10;
char tempBuff[4];
int chill = 0;
int valveToOpenIdx = -1;
double volts = 0.486328125;
int TempSensor[4] = {0,0,0,0};
int j = 0;
int curTankDiff;
int maxTankDiff = 0;
int checkvalve = -1;


void setup()
{
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  // initialize serial communications at 9600 bps:
  //Serial.begin(9600); 
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  
 
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, LOW);
  
 }

void loop()
{
  //Get Temps off sensors
  for (j = 0; j<4; j++)
{
  analogRead(j+1);
  delay(10);
  TempSensor[j] = 0;
  for (int i = 0; i < 10; i++) {
    TempSensor[j] = TempSensor[j] + round(volts*analogRead(j+1)); 
  }
TempSensor[j] = round(TempSensor[j]/10);
    
  
  // Web Interface
  int bufLength = 4;
  // listen for incoming clients
  Client client = server.available();
  if (client) {
    // an http request ends with a blank line
   // Serial.println(client.read());

    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (inString.length() < maxLength) {
          inString += c;
         }        
        // 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
          if (inString.indexOf("?") > -1) {
            Posa = inString.indexOf("a");
            Posb = inString.indexOf("b");
            Posc = inString.indexOf("c");
            Posd = inString.indexOf("d");
            
            inString.substring((Posa+2), (Posb-1)).toCharArray(tempBuff, bufLength);  //transfer substring to buffer
            setferm[0] = atoi(tempBuff);
            inString.substring((Posb+2), (Posc-1)).toCharArray(tempBuff, bufLength);  //transfer substring to buffer
            setferm[1] = atoi(tempBuff);
            inString.substring((Posc+2), (Posd-1)).toCharArray(tempBuff, bufLength);  //transfer substring to buffer
            setferm[2] = atoi(tempBuff);
            inString.substring((Posd+2), (Posd+5)).toCharArray(tempBuff, bufLength);  //transfer substring to buffer
            setferm[3] = atoi(tempBuff);
            
            maxTankDiff = 0;
            checkvalve = -1;      
            for (int i = 0; i < 4; i++) {
              curTankDiff = TempSensor[i] - setferm[i];
              if (curTankDiff > maxTankDiff) {
                checkvalve = i;
                maxTankDiff = curTankDiff;
              }
            }
            
            
         }

          
          
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          
          client.print("<font size=32 color=CDAD00><b><u>HGB Fermenter Control</u></b></font>

 ");
          
          // output the value of each analog input pin
          
          for (j = 0; j<4; j++)
          {
            client.print("<font size=32>Temperature of Fermenter ");client.print(j + 1);client.print(" is ");client.print(TempSensor[j]);client.println("</font>
");
          }
                            
          client.print("

<form method=get><font size=32>");
          
           for (j = 0; j<4; j++)
          {
            client.print("Setpoint Fermenter ");client.print(j + 1);client.print(": <input type=text style=font-size:32pt size=3 name=");client.print(Whereto[j]);client.print(" value="); client.print(setferm[j]);client.print(" />");
            if (checkvalve == j) {
              client.print(" Open");
            }
            else {
              client.print(" Closed");
            }
            client.print("
");
          }
          
          client.print("

");
          client.print("<input type=submit value=Update-Temps style=height:6em; width:24em />");
          client.print("</font></form>");
          client.println("
");
                   
          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(100);
    inString = " ";
    // close the connection:
    client.stop();
  }
}  
 
    switch ( whichTank ) {
      case 0: chillValue = TempSensor[0]-setferm[0];
              break;
      case 1: chillValue = TempSensor[1]-setferm[1];
              break;
      case 2: chillValue = TempSensor[2]-setferm[2];
              break;
      case 3: chillValue = TempSensor[3]-setferm[3];
              break;    
    }
    
    if (chillValue < -1 && valveToOpenIdx != -1) {
      digitalWrite(6, LOW);
      delay(1000);
      digitalWrite(2, HIGH);
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      //volts = 0.4443359375;
      delay(10);
       //Serial.println("Closed ");
      // Serial.println(valveToOpenIdx);
       chill = 0; 
    }
    
    
    if (chill == 0) {    
      int curTankDiff;
      int maxTankDiff = 0;
 
      valveToOpenIdx = -1;
      
      for (int i = 0; i < 4; i++) {
        curTankDiff = TempSensor[i] - setferm[i];
        if (curTankDiff > maxTankDiff) {
          valveToOpenIdx = i;
          whichTank = i;
          maxTankDiff = curTankDiff;
        }
      }
      
    if (valveToOpenIdx != -1) {  
        digitalWrite(valveToOpenIdx + 2, LOW);
        
        digitalWrite(6, HIGH);
        //volts = 0.4384765625;
       // Serial.println("Opened ");
       // Serial.println(valveToOpenIdx);
        chill = 1;
      }  
    }
}

Cruelkix:
Ahhh, by strings i thought you meant variables that were stored as strings, not lines of code that contain strings.

I changed the code up a good bit to be more efficient after the other guy showed me how bad my tempsensor code was as far as efficiency is concerned. My current code is as follows:

Did the change fix it or are you still having problems?

Arrch:

Cruelkix:
Ahhh, by strings i thought you meant variables that were stored as strings, not lines of code that contain strings.

I changed the code up a good bit to be more efficient after the other guy showed me how bad my tempsensor code was as far as efficiency is concerned. My current code is as follows:

Did the change fix it or are you still having problems?

I'm not sure. I have been messing with the code and the set up a lot, but I had it running for a few days and it was stable. So hopefully whatever the problem was has been fixed. I'm going to do a long term test with it. This thing needs to be rock stable.

I'm going to be using this set up to monitor and cool my fermenters in my Micro Brewery. So its for my business. If it is not rock solid stable I have the potential to ruin a batch of beer which will cost me lots of money.

Right now I'm waiting to get a router from my buddy that I am going to set up as an access point. Once I have that, I will be running a month long test to make sure that everything functions properly.

I'll let you know how the test goes.

So it locked up again today. A soft reset using the red button on the ethernet shield was all it took to get it up and running again. As I was running the test using an external power source, I did not have the USB hooked up. I was unable to access the arduino via the ethernet port. After the soft reset everything was fine.

The other troubleshooting tip is to remove parts of the code and test. Then if it doesn't fail, start adding bit by bit until it fails.

Or, create some sort of auto-reset (search the old forum, there is something there about it for the same type of application), that is triggered if the processor locks up.

bubulindo:
The other troubleshooting tip is to remove parts of the code and test. Then if it doesn't fail, start adding bit by bit until it fails.

Or, create some sort of auto-reset (search the old forum, there is something there about it for the same type of application), that is triggered if the processor locks up.

Thanks for the tip.

I'm not conviced its the code. I think it might be a hardware/power issue.

I can't do an auto reset becuase it will default the temperature set points back to their original state of 300.

Cruelkix:
I can't do an auto reset becuase it will default the temperature set points back to their original state of 300.

That's nothing some EEPROM space and careful programming can't fix...

bubulindo:

Cruelkix:
I can't do an auto reset becuase it will default the temperature set points back to their original state of 300.

That's nothing some EEPROM space and careful programming can't fix...

Interesting. I didn't know you could do that. Got a good place I can learn about it? I'm assuming EEPROM is some on board memory I can use that won't go away with a loss of power? Or is it only good for soft resets?

Nevermind, found it http://www.arduino.cc/en/Reference/EEPROM

Cruelkix:

bubulindo:

Cruelkix:
I can't do an auto reset becuase it will default the temperature set points back to their original state of 300.

That's nothing some EEPROM space and careful programming can't fix...

Interesting. I didn't know you could do that. Got a good place I can learn about it? I'm assuming EEPROM is some on board memory I can use that won't go away with a loss of power? Or is it only good for soft resets?

Nevermind, found it http://www.arduino.cc/en/Reference/EEPROM

Check here: http://arduino.cc/forum/index.php/topic,74236.0.html

Ok, So my arduino is locked up right now. All the lights are on and I am able to ping it, but when i try to access it both from an outside IP address and from an internal one, no luck! Any ideas on how I might be able to trouble shoot what is causing it to not respond while it is locked up? Everything I have tried to do before this has been to get it to stop locking up in the first place. Anything I can try while it is actually locked up other than pinging like was suggested?

Thanks!