Go Down

Topic: Ethernet Shield going to sleep?? (Read 4 times) previous topic - next topic

Cruelkix

Sep 27, 2011, 03:26 am Last Edit: Oct 27, 2011, 05:01 am by Coding Badly Reason: 1
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!

Code: [Select]

/*
 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><br /><br /> ");
         
         // output the value of each analog input pin
         client.print("<font size=32>Temperature of Fermenter 1 is ");client.print(TempSensor1);client.println("</font><br />");
         client.print("<font size=32>Temperature of Fermenter 2 is ");client.print(TempSensor2);client.println("</font><br />");
         client.print("<font size=32>Temperature of Fermenter 3 is ");client.print(TempSensor3);client.println("</font><br />");
         client.print("<font size=32>Temperature of Fermenter 4 is ");client.print(TempSensor4);client.println("</font><br />");
         
         client.print("<br /><br /><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("<br />");
         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("<br />");
         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("<br />");
         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("<br />");
         client.println("<br />");
         client.print("<input type=submit value=Update-Temps style=height:6em; width:24em />");
         client.print("</font></form>");
         client.println("<br />");
         
         
         
         
         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();
 }  


adis

#1
Sep 27, 2011, 02:08 pm Last Edit: Oct 27, 2011, 05:04 am by Coding Badly Reason: 1
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

Cruelkix


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?

Arrch

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

Cruelkix


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?

bubulindo

This is not the problem... but why not using something like this
Code: [Select]

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.
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Cruelkix

#6
Sep 27, 2011, 11:17 pm Last Edit: Sep 27, 2011, 11:20 pm by Cruelkix Reason: 1

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 ;P

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...

bubulindo

Can you at least ping the shield when you don't receive a reply with the browser?
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Cruelkix


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?

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.

Cruelkix




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:

Code: [Select]

#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><br /><br /> ");
         
          // 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><br />");
          }
                           
          client.print("<br /><br /><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("<br />");
          }
         
          client.print("<br /><br />");
          client.print("<input type=submit value=Update-Temps style=height:6em; width:24em />");
          client.print("</font></form>");
          client.println("<br />");
                   
          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;
      } 
    }
}


Arrch


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?

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.


Cruelkix

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.

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.
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Go Up