Go Down

Topic: Ethernet, connect(), timeout (Read 4667 times) previous topic - next topic

qwertysimo

Hello,

based on WebClient example I am trying to connect to my web server. It works as expected, but standard behaviour does not meet my specific need.

Story: Arduino tries to connect to web server to get some data. If it cannot establish connection, it will use data stored in EEPROM or SD card instead.
In case of network/web server problem, client.connect() takes more than 30 seconds to return false. I need true or false within 2 seconds.

Question: Is it possible to set timeout period for connect() method?


Thank you


qwertysimo

PaulS

Have you looked at the source code for Client?

qwertysimo

I tracked it down to socket.cpp, function connect:

Quote
This function established  the connection for the channel in Active (client) mode. This function waits for the untill the connection is established.


Then down to :

Code: [Select]
void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd) {
 // Send command to socket
 writeSnCR(s, _cmd);
 // Wait for command to complete
 while (readSnCR(s))
   ;
}


but cannot find writeSnCR neither readSnCR.

robtillaart

you could patch this loop like:
Code: [Select]
unsigned long limit = to be determined;
unsigned long t = 0;
while (readSnCR(s) && (t < limit) ) t++;

not nice but it might do the trick ?
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Oily The Otter

#4
Dec 01, 2010, 11:13 pm Last Edit: Dec 01, 2010, 11:31 pm by oilytheotter Reason: 1
The troublesome code is not the execCmdSn; that returns instantly. The problem is back in Client::connect()

Code: [Select]
while (status() != SnSR::ESTABLISHED) {
   delay(1);
   if (status() == SnSR::CLOSED) {
     _sock = MAX_SOCK_NUM;
     return 0;
   }
 }


That is where you would put the patch suggested by robtillaart...but, it's so much easier than that!

The simple fix

arduino-0021\libraries\Ethernet\utility\w5100.cpp, add 2 lines to make the init function look like this

Code: [Select]
void W5100Class::init(void)
{
 delay(300);

 SPI.begin();
 initSS();
 
 writeMR(1<<RST);
 writeTMSR(0x55);
 writeRMSR(0x55);

 setRetransmissionTime(0x07D0);
 setRetransmissionCount(3);

 for (int i=0; i<MAX_SOCK_NUM; i++) {
   SBASE[i] = TXBUF_BASE + SSIZE * i;
   RBASE[i] = RXBUF_BASE + RSIZE * i;
 }
}


setRetransmissionTime sets the Wiznet's timeout period, where each unit is 100us, so 0x07D0 (decimal 2000) means 200ms.

setRetransmissionCount sets the Wiznet's retry count.

A retry count of 2 or 3 makes the connect function fail really quickly.

Hope that helps.

Ben

Edit:

The simpler fix

You don't even need to modify the library code. In your sketch, add this include:

Code: [Select]
#include <utility/w5100.h>

then, in your setup, after you call Ethernet.begin(), add the following two lines:

Code: [Select]
W5100.setRetransmissionTime(0x07D0);
W5100.setRetransmissionCount(3);


That gives me a 3 second timeout on a bad server connection.

qwertysimo

Thanks. I will try this solution soon.

Go Up