I've got a program that reads information off the web trying to update information, like the current temperature. I'd like to make it more robust, such that if it loses connection (such as the ethernet cable being unplugged) it can re-establish connection automatically and move on. Right now the program seems to hang if I unplug the ethernet. Any idea how to do this?
I don't know if you are using client or server, but this client code downloads google every 10 seconds. It does ok if you unplug the cable, wait a few fails, then plug it in again.
Don't do that to Google too long. Change it to your server ip.
Thanks for the reply. It does indeed reconnect if you unplug it, but only when it's unplugged between requests.
The problem I have is that the code hangs if you unplug the ethernet when it is in the "while" loop and reading the client. Any thoughts on how to avoid this? I need the code to be robust enough that if it loses internet connection, it can pick up where it left off or start over when it reconnects. Thanks.
Haha, I don't think my reaction time is that fast. But I have the same problem with both my code and yours.
Using google's server, the page has enough data to load that it takes an appreciable amount of time. Try unplugging the cable while you see the characters scrolling across the serial monitor. Perhaps I'm not describing this well...
I tried it with the Google home page, and I see what you mean. It took a while to see if it was going to time out, but it hasn't yet. I've waited a few minutes and it is still locked up.
It appears that client.connected() is returning true when it shouldn't be. I'll take a look at the w5100 code when I have time.
That's a good idea, I'll give it a go. Any idea if the false positive is just a nature of the ethernet functionality? My only thought is that client.connected() returns true if the connection closed but there is unread data. This should return a TRUE value for client.available() afterwards to trigger the client.read(), right?
I tested it on IDE v1.0.1-rc1. It closes the connection and then will resume the downloads as soon as the cable is reconnected. Let the while() loops exit normally. The client.stop() call will do that.
I think my issue may be related to what's previously described in this forum post.
I have connected the ethernet board (not the PoE version) to my Arduino, along with a PIR sensor. So, as you may have surmised, I'm asking it to watch for motion and if it detects motion, request a script that I have out there on a server. This script then shoots me a text message letting me know that my sensor was tripped.
It detects motion reliably, but it only successfully fetches the php script that sends the text message the first time.
Could the failed subsequent connections be because it's holding open that original, successful HTTP connection open too long, preventing the arduino from reaching out again with subsequent GET requests for the script?
Here's my sketch:
//this comes directly matt williamson's work
#include <SPI.h>
#include <Ethernet.h>
// Declare Constants
const int sensorPin = 2; // PIR Sensor is attached to digital pin 2
const int ledPin = 13; // Built-in LED
const int ledBlinkTime = 500; // Blink one for half a second while calibrating
// Wait for the seonsor to calibrate (20 - 60 seconds according to datasheet)
// 60 Seconds in milliseconds
const unsigned int calibrationTime = 60000;
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
char serverName[] = "example.com";
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
void setup() {
Serial.begin(115200);
pinMode(sensorPin, INPUT);
pinMode(ledPin, OUTPUT);
// We need to wait one minute for the sensor to calibrate
// Get out of view of the sensor for this duration!
// Blink the LED while calibrating
for (unsigned int i=0; i<calibrationTime; i+=ledBlinkTime*2) {
digitalWrite(ledPin, HIGH);
Serial.println("Warming up... HIGH");
Serial.println(i);
delay(ledBlinkTime);
Serial.println("Warming up... LOW");
digitalWrite(ledPin, LOW);
delay(ledBlinkTime);
}
}
void loop() {
// Constantly check the state of pin 2
// If it is HIGH the sensor is detecting motion
if (digitalRead(sensorPin) == HIGH) {
// Turn the LED on
digitalWrite(ledPin, HIGH);
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
while(true);
}
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.println("connecting...");
// if you get a connection, report back via serial:
if (client.connect(serverName, 80)) {
Serial.println("connected");
client.println();
Serial.println(" we detected motion, we're going to try to call the file which sends the SMS now");
// Make a HTTP request:
// client.println("GET / HTTP/1.0"); original line
client.println("GET /sms-script.php HTTP/1.0");
client.println("host:example.com");
client.println();
}
else {
// kf you didn't get a connection to the server:
Serial.println("connection failed");
}
// Sleep for a second to prevent flooding the serial
delay(5000);
} else {
// Turn the LED off
digitalWrite(ledPin, LOW);
Serial.println(" we DIDN'T detect motion!");
delay(2000);
}
}
I'm quite new to Arduino (and enjoying it!) so if I've made any silly beginner mistakes, be gentle with me!
Every server I've ever heard of sends SOME kind of response when you request a page. The client connection is not closed until you've read the entire response. Make 4 requests, and don't read any responses, and those 4 client connections are going to remain open, and unavailable for reuse.
PaulS:
Every server I've ever heard of sends SOME kind of response when you request a page. The client connection is not closed until you've read the entire response. Make 4 requests, and don't read any responses, and those 4 client connections are going to remain open, and unavailable for reuse.
Thanks for the response. So just to be clear, you're confirming the suspicion that I need to include a snippet of code that explicitly closes the connection after every GET request, right?
So just to be clear, you're confirming the suspicion that I need to include a snippet of code that explicitly closes the connection after every GET request, right?
Not at all. If you plan on only 4 connections total, then you can leave them all open. Otherwise you will need to close them. But they won't close correctly until you empty the socket rx buffer. All that is included in my example code above.
SurferTim:
Not at all. If you plan on only 4 connections total, then you can leave them all open. Otherwise you will need to close them. But they won't close correctly until you empty the socket rx buffer. All that is included in my example code above.
The 10 second timeout example above shows how to close a connection from the client end. Note there is no break after the timeout client.stop(). Allow the "while(client.connected()) { while(client.available())" loops to exit normally. That insures the connection is closed.
I (believe that I) successfully integrated SurferTim's code which adds a 10 second timeout. That is to say, when watching the output in the serial monitor scroll by, it reports back that it closes the initial connection to my server after requesting my php script out there.
However, all subsequent requests for that file after the first one continue to be unsuccessful, just as described before. I guess that suggests that something else was preventing all GET requests for the script after the first one from being successful.
Here's a screenshot of the serial monitor output showing the sequence of events.
If you guys recommend that this deserves a separate thread because the root cause is not the same doubledaffy's , I'm happy to open a new one.