Ethernet fails connecting after a while

The EtherTen combines an Uno-equivalent Arduino-compatible board and Wiznet-based Ethernet support, along with a microSD card slot and Power-over-Ethernet support. [Product page]

Re: Ethernet fails connecting after a while

Postby Sleurhutje » Fri Apr 06, 2012 5:40 pm

Yes, D4 is the Chip Select line for the SD-card connection. Avoid using D4 and D10 to D13 since these are used for SPI and select lines.
Sleurhutje
 
Posts: 28
Joined: Thu Mar 01, 2012 9:18 am

Re: Ethernet fails connecting after a while

Postby Alkarex » Sun Apr 15, 2012 2:12 pm

Hello,
I write here to report that I have the same problem with an official Arduino Uno R3 + Arduino Ethernet Shield R3.
On the software side, it is tested with Arduino-1.0.1-rc2 on Windows 7, but there is a similar behaviour with Arduino-1.0. I have tried to include the tricks mentioned earlier in this thread without significant effect.

In addition to the crash / freeze documented in this thread, there is a bug that occurs systematically in the little program below, which makes an Internet GET request, waits 10 minutes, and repeat.

The first HTTP request is fine, but as soon as the second request, 2 attempts are always needed to establish the connexion, resulting in the debug string "Arduino bug with connection!" being sent to Serial.

I have tried with and without Ethernet.maintain(), as well as with Ethernet.begin() in the loop or in the setup, without any clear difference. Note that the problem will not appear if the delay is much shorter than 10 minutes, so please give it a try as-is.

As I have only one single Arduino, I cannot tell if this bug is due to a possible hardware problem on my side. I would appreciate if someone could confirm / infirm this behaviour, also with an EtherTen.

Code: Select all
#include <SPI.h>   //It should not be necessary to manually include this one
#include <Ethernet.h>

const unsigned long UpdateDelay = 1000UL * 60 * 10;   //Time between Internet updates

const byte NbConnectionAttempts = 8;   //Internet attempts in case of problem

const byte EthernetPin = 10;
const byte SDPin = 4;
byte Mac[] = {0x90, 0xA2, 0xDA, 0xE0D, 0x08, 0x6A};   //Unique Ethernet MAC address
IPAddress Ip(192, 168, 1, 112);   //Fallback manual IP if no DHCP
const char Server[] = "ntp.alapetite.fr";
const char Url[] = "/gmdate.txt.php";
EthernetClient client;

void setup()
{
   delay(1000);

   Serial.begin(9600);   //Start serial port
   delay(200);
   Serial.println("Starting...");

   {//Is this still necessary?
      pinMode(SDPin, OUTPUT);
      digitalWrite(SDPin, HIGH);   //Disable SD card
      pinMode(EthernetPin, OUTPUT);
      digitalWrite(EthernetPin, LOW);   //Enable Ethernet
   }

   delay(1000);

   if (Ethernet.begin(Mac) == 0)
   {
      Serial.println("DHCP failed!");
      Ethernet.begin(Mac, Ip);
   }
}

void loop()
{
   int status = Ethernet.maintain();
   Serial.print("Ethernet.maintain: ");
   Serial.println(status);
   Serial.print("Local IP: ");
   Serial.println(Ethernet.localIP());

   byte nbAttempts;
   for (nbAttempts = 1; nbAttempts <= NbConnectionAttempts; nbAttempts++)
   {//Attempt to connect several times in case of problem
      Serial.println("Connecting to " + String(Server) + "...");
      if (client.connect(Server, 80))
      {
         if (client.connected()) break;   //Ok
         else Serial.println("Arduino bug with connection!");
      }
      else Serial.println("Connection error!");
      client.stop();
      delay(1000);
   }
   if (client.connected())
   {
      Serial.println("Sending request...");
      client.println("GET " + String(Url) + " HTTP/1.1");
      client.println("Host: " + String(Server));
      client.println("User-Agent: Arduino Ethernet Shield/R3");
      client.println("Connection: close");
      client.println();
      Serial.println("Waiting response...");

      byte maxReads = 10;   //Seconds
      while ((maxReads-- > 0) && client.connected())
      {//Read response
         delay(1000);
         while (client.available())
         {
            char response = client.read();
            Serial.print(response);
         }
      }
      delay(10);
      client.flush();
      delay(10);
      client.stop();
      Serial.println("Done.");
   }
   else Serial.println("Connection failed!");
   Serial.println();

   //How to save power here? I.E. how to stop the Ethernet shield / w5100?
   //The WizNet is still able to respond to ping during a long delay()

   delay(UpdateDelay);
}


Serial output:

Code: Select all
Starting...
Ethernet.maintain: 0
Local IP: 192.168.1.34
Connecting to ntp.alapetite.fr...
Sending request...
Waiting response...
HTTP/1.1 200 OK
Date: Sat, 14 Apr 2012 14:38:47 GMT
Server: Apache/2.2.11 (Ubuntu)
X-Powered-By: PHP/5.2.6-3ubuntu4.6
Content-Disposition: inline; filename="gmdate.txt"
Cache-Control: private, no-cache, no-store, must-revalidate
Pragma: no-cache
Vary: Accept-Encoding
Connection: close
Transfer-Encoding: chunked
Content-Type: text/plain; charset=UTF-8

19
2012-04-14T14:38:47+00:00
0

Done.

Ethernet.maintain: 0
Local IP: 192.168.1.34
Connecting to ntp.alapetite.fr...
Arduino bug with connection!!!!!!!!
Connecting to ntp.alapetite.fr...
Sending request...
Waiting response...
HTTP/1.1 200 OK
Date: Sat, 14 Apr 2012 14:49:04 GMT
Server: Apache/2.2.11 (Ubuntu)
X-Powered-By: PHP/5.2.6-3ubuntu4.6
Content-Disposition: inline; filename="gmdate.txt"
Cache-Control: private, no-cache, no-store, must-revalidate
Pragma: no-cache
Vary: Accept-Encoding
Connection: close
Transfer-Encoding: chunked
Content-Type: text/plain; charset=UTF-8

19
2012-04-14T14:49:05+00:00
0

Done.


Best regards,
Alexandre
User avatar
Alkarex
 
Posts: 2
Joined: Sun Apr 15, 2012 12:56 pm

Re: Ethernet fails connecting after a while

Postby Sleurhutje » Mon Apr 16, 2012 1:50 pm

This is how I made my sketch working (and removing all interrupt related stuff). There are some features like DHCP vs. fixed IP included and the server URL and NTP processing is removed (however, the time is set to 12:00:00 01/01/2000 since the time processing is used). My server returns about 600 bytes raw data. E.g. including the response to process after submitting using a URL (like $$x=2/y=238/z=blahblah$$).

Each 90 seconds the data is submitted. Each 300 seconds there's a check if the network connection is still valid and if not, it's reinitialized (also DHCP is update, which is overkill but hey, it works).

Main sketch:
Code: Select all
#include <SPI.h>         
#include <Ethernet.h>
#include <Time.h>
#define updateweb 90
#define updateinet 300

byte mac[] = {0x00, 0xca, 0xfe, 0x41, 0x42, 0x43};
byte ip[] = {172, 16, 20, 100};   
byte mask[] = {255, 255, 255, 0};   
byte gateway[] = {172, 16, 20, 20};   
byte dns[] = {172, 16, 20, 10};   
boolean usefixedip = true;
boolean inetOK;
char logserver[] = "www.yourdomain.com";
unsigned long lastwebupdate;
unsigned long lastinetupdate;
int avgTempCur = 0;
int avgHumCur = 0;

time_t t;

void setup()
{
  Serial.begin(115200);
  delay(1500);

  setTime(12, 00, 00, 01, 01, 2000);

  Serial.print("Init Ethernet/DHCP...");
  inetInit();

  lastwebupdate = now();
  lastinetupdate = now();
}


void loop()
{
  t = now();
 
  if(t - lastwebupdate >= updateweb)
  {
    lastwebupdate = t;
    if(inetOK)
    {
      inetConnectURL();
    }
  }

  if(t - lastinetupdate >= updateinet)
  {
    lastinetupdate = t;
    if(!inetOK)
    {
      inetInit();
    }
  }

  if(inetOK)
  {
    inetCloseURL();
  }
}


Subroutine for initializing the internet connection:
Code: Select all
void inetInit()
{
  if(usefixedip)
  {
    Ethernet.begin(mac, ip, dns, gateway, mask);
    inetOK = true;
  } else {
    if (Ethernet.begin(mac) == 0) {
      inetOK = false;
    } else {
      inetOK = true;
    }
  }
  delay(50);
  httpget = false;
}


Start submitting data:
Code: Select all
void inetConnectURL()
{
  if(!httpget)
    {
    String myURL = "GET logme.php?time=";
    myURL += now();
    myURL += "&temp=";
    myURL += avgTempCur;
    myURL += "&hum=";
    myURL += avgHumCur;
    myURL += " HTTP/1.0";
   
    Serial.print("URL  :  ");
    httpget = false;
    httpbufcount = 0;
    if (client.connect(logserver, 80))
    {
      client.println(myURL);
      client.print("Host: ");
      client.println(logserver);
      client.println("User-Agent: Arduino-Monitor");
      client.println();
      httpget = true;
    }
    else
    {
       Serial.print("Failed connection");
    }
  }
}


The loop called from the loop() part of the main sketch to flush the buffer:
Code: Select all
void inetCloseURL()
{
  int c;
 
  if(httpget)
  {
    if (client.available())
    {
      c = client.read();
      Serial.print((char) c);
      httpbufcount += 1;
    }
    if (!client.connected())
    {
      Serial.println(" ");
      Serial.print(httpbufcount);
      Serial.println(" bytes received");
      client.stop();
      httpget = false;
    }
  }
}



Three things I've learned the hard way the last few weeks: Never use Flush() but make sure the buffer is read in full until the connection is closed. Use a MAC-address with the last 3 digits as readable ASCII. Some DNS systems can't handle the WIZxxx name where xxx is non-ASCII garbage (see earlier post about loosing the gateway address all of a sudden). Don't use interrupts, neither on pins nor on timers.


-edit-
I'll try my sketch with a 15 or 20 minutes delay between each call. Does your sketch crashes directly on/after the second try?
Last edited by Sleurhutje on Tue Apr 17, 2012 10:10 am, edited 1 time in total.
Sleurhutje
 
Posts: 28
Joined: Thu Mar 01, 2012 9:18 am

Re: Ethernet fails connecting after a while

Postby Sleurhutje » Tue Apr 17, 2012 5:28 am

I ran my sketch with 15 minute intervals for submitting data and 20 minute intervals for checking the connection. Everything works fine. There was one hick-up in the connection due to a problem in my DSL connection (third last line) but the unit recovered automatically.

Image
Sleurhutje
 
Posts: 28
Joined: Thu Mar 01, 2012 9:18 am

Re: Ethernet fails connecting after a while

Postby Scargill » Tue Apr 17, 2012 12:33 pm

Iv'e implemented your code... to explain - I'm using the client code to request a simple PHP web page with nothing more than a line of text in it... which works every time in a browser... In Arduino it works most of the time but then starts to slow down and eventually it's down to responding after maybe 30 seconds..

I implemented your code and it seemed to help, but then things started slowing down - so I put Serial.println all over the client library and it seems that every time, the name is being resolved instantly, which is good, socket zero is being used - which means it's not running out of socket, the usual place it stops for a while (sometimes less than a second and it works, sometimes umpreen seconds and it fails) - is after connecting with the raw address...

So in EthernetClient.cpp (serial.println is mine)

Serial.println("Connected with raw adddress");
while (status() != SnSR::ESTABLISHED) {
delay(1);
if (status() == SnSR::CLOSED) {
_sock = MAX_SOCK_NUM;
return 0;
}
}
Serial.println("Returning at the end");
return 1;

What actually happens is that I see "connected with raw address" - but "returning at the end" never happens - so it is sitting in that while loop and eventually returning 0

So it APPEARS that it is this part of the code that is having trouble..
Scargill
 
Posts: 8
Joined: Tue Apr 17, 2012 12:26 pm

Re: Ethernet fails connecting after a while

Postby Scargill » Tue Apr 17, 2012 4:38 pm

Having discovered the code was slowing down after the address is resolved - so into the routine that uses an IP address... I had a hunch... in the past with issues I've changed the MAC address if the whole lot begins to lock up. Sure enough changes of mac address seemed to help so I did something silly.

I started incrementing one of the mac address bytes and sure enough I got 200 packages perfectly - then of course my router had a fit as it ran out of addresses ... so I thought I'd try rotating 4 mac addresses... ie just changing one of the bytes 0,1,2,3,0,1,2,3

It DEFINITELY now takes longer before the thing slows down to a halt, but it still does eventually maybe after half an hour or so, eventually coming to a halt. It's not the service provider of the PHP page as I've tried a local server as well (uniform server).... anyone any ideas, I can't seem to move on from this.. it's as if the router is just getting sick of sending requests from the same mac address. I know, silly but that's how it appears.
Scargill
 
Posts: 8
Joined: Tue Apr 17, 2012 12:26 pm

Re: Ethernet fails connecting after a while

Postby Sleurhutje » Tue Apr 17, 2012 11:13 pm

Okay, two things:
- Use readable characters for the last three bytes of the MAC address (i.e. 0x30 to 0x39, 0x41 to 0x5b and/or 0x65 to 0x7b);
- Before each connection to the webserver reuse the Ethernet.begin() to make sure the socket is initiated.
Sleurhutje
 
Posts: 28
Joined: Thu Mar 01, 2012 9:18 am

Re: Ethernet fails connecting after a while

Postby Alkarex » Tue Apr 17, 2012 11:31 pm

Dear Sleurhutje and Scargill,
Thank you for your answers.
Sleurhutje: Yes, on my platform, the second call to client.connect() fails. Actually, it returns true but this is wrong. So I soon get “0 bytes received”.
I had to modify your code quite a bit to make it to compible due to missing variables, and variables conflicting with some in the libraries, lack of now(), etc., as visible below:
Code: Select all
#include <SPI.h>
#include <Ethernet.h>
#include <Time.h>
#define updateweb 600000L
#define updateinet 1000000L

byte mac[] = {0x00, 0xca, 0xfe, 0x41, 0x42, 0x43};
byte ip[] = {192, 168, 1, 34};
byte mask[] = {255, 255, 255, 0};
byte gateway[] = {192, 168, 1, 1};
byte myDns[] = {8, 8, 8, 8};
boolean usefixedip = false;
boolean inetOK;
char logserver[] = "ntp.alapetite.fr";
long lastwebupdate = -updateweb;
long lastinetupdate = 0;
int avgTempCur = 0;
int avgHumCur = 0;
bool httpget = false;
long httpbufcount = 0;
EthernetClient client;

long t;

void setup()
{
   Serial.begin(9600);
   delay(1500);

   Serial.println("Init Ethernet/DHCP...");
   inetInit();
}

void loop()
{
   t = millis();

   if (t - lastwebupdate >= updateweb)
   {
      lastwebupdate = t;
      if (inetOK)
         inetConnectURL();
   }

   if (t - lastinetupdate >= updateinet)
   {
      lastinetupdate = t;
      if (!inetOK)
         inetInit();
   }

   if (inetOK)
      inetCloseURL();
}

void inetInit()
{
   if (usefixedip)
   {
      Ethernet.begin(mac, ip, myDns, gateway, mask);
      inetOK = true;
   }
   else inetOK = (Ethernet.begin(mac) != 0);
   Serial.print("Local IP: ");
   Serial.println(Ethernet.localIP());
   delay(50);
   httpget = false;
}

void inetConnectURL()
{
   if (!httpget)
   {
      String myURL = "GET /gmdate.txt.php HTTP/1.1";
      httpget = false;
      httpbufcount = 0;
      if (client.connect(logserver, 80))
      {
         Serial.print("client.connected(): ");
         Serial.println(client.connected());
         Serial.println(myURL);
         client.println(myURL);
         client.print("Host: ");
         client.println(logserver);
         client.println("User-Agent: Arduino-Monitor");
         client.println();
         httpget = true;
      }
      else Serial.print("Failed connection");
   }
}

void inetCloseURL()
{
   int c;

   if (httpget)
   {
      if (client.available())
      {
         c = client.read();
         Serial.print((char) c);
         httpbufcount += 1;
      }
      else if (!client.connected())
      {
         Serial.println(" ");
         Serial.print(httpbufcount);
         Serial.println(" bytes received");
         client.stop();
         httpget = false;
      }
   }
}

I will soon do some more debugging.
Best regards,
Alexandre
User avatar
Alkarex
 
Posts: 2
Joined: Sun Apr 15, 2012 12:56 pm

Re: Ethernet fails connecting after a while

Postby Scargill » Wed Apr 18, 2012 10:04 am

Sleurhutje wrote:Okay, two things:
- Use readable characters for the last three bytes of the MAC address (i.e. 0x30 to 0x39, 0x41 to 0x5b and/or 0x65 to 0x7b);
- Before each connection to the webserver reuse the Ethernet.begin() to make sure the socket is initiated.


OK, I've not idea why the printable characters, could you explain? I've modified my code to do that and to rotate 4 of them on the second last digit for each call. Last night I managed to get 5,000 packages out - then it packed in - so it takes a while to test at one packet every 2 seconds: I'll leave that running. And yes, since yesterday I've been running the BEGIN in the main loop every time..

I was pondering narrowing down where it eventually slows and stops and trying reset on the board - but that REALLY is not the solution.... the solution is to find out why it's slowing down and stopping..

Up to package 65, running every 2 secs but already I'm seeing some slow down... 20 seconds for one of them... if only I could figure out WHY...
Scargill
 
Posts: 8
Joined: Tue Apr 17, 2012 12:26 pm

Re: Ethernet fails connecting after a while

Postby Scargill » Wed Apr 18, 2012 10:06 am

Whatever you come up with do let us know.. this is most frustrating...
Scargill
 
Posts: 8
Joined: Tue Apr 17, 2012 12:26 pm

PreviousNext

Return to EtherTen

Who is online

Users browsing this forum: No registered users and 1 guest

cron