Arduino Router reset with Http

Hi, trying to make a Arduino to reset the router plus having it store a website where it shows temp off the room.

But i having some problems understanding "Ethernetserver" "Ethernetclient" what the difference?

This is the Router reset part. Not my code just copy past.

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



byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress ip(192,168,0,22);


char server[] = "www.google.com";
unsigned long lastConnectionTime = 0;
#define postingInterval 10000
boolean canConnect = false;
boolean canConnect_prev = false;



#define redLed 3
#define greenLed 5
#define yellowLed 6
#define routerPin1 8
#define routerPin2 9
#define resetRouterTime 30000

EthernetClient client;

void setup() {
  
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // 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:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  // 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(server, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /search?q=arduino HTTP/1.1");
    client.println("Host: www.google.com");
    client.println("Connection: close");
    client.println();
  } 
  else {
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
  }
// Initial LEDs
pinMode(redLed, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
pinMode(routerPin1, OUTPUT);
pinMode(routerPin2, OUTPUT);
digitalWrite(routerPin1, HIGH);
digitalWrite(routerPin2, HIGH);
}


void loop() {
// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
client.stop();
}
if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
digitalWrite(yellowLed, HIGH);
delay(1000); 
connect_to_server();
digitalWrite(yellowLed, LOW);
}
if(canConnect) {
digitalWrite(greenLed, HIGH);
digitalWrite(redLed, LOW);
}
else {
digitalWrite(greenLed, LOW);
digitalWrite(redLed, HIGH);
resetRouter();
}
}

void connect_to_server(void) {
if (client.connect(server, 80)) {
canConnect = true;
client.println("GET /search?q=arduino HTTP/1.1");
client.println("Host: www.google.com");
client.println("Connection: close");
client.println();
}
else {
client.stop();
canConnect = false;
}
lastConnectionTime=millis();
}

void resetRouter(void) {
digitalWrite(routerPin1, LOW);
digitalWrite(routerPin2, LOW);
delay(resetRouterTime);
digitalWrite(routerPin1, HIGH);
digitalWrite(routerPin2, HIGH);
delay(resetRouterTime);
}
void loop() {
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {   
      if (client.available()) {
        char c = client.read();
     
        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string
          readString += c;
          //Serial.print(c);
         }

         //if HTTP request has ended
         if (c == '\n') {          
           Serial.println(readString); //print to serial monitor for debuging
     
           client.println("HTTP/1.1 200 OK"); //send new page
           client.println("Content-Type: text/html");
           client.println();     
           client.println("<HTML>");
           client.println("<HEAD>");

Where should i put this code so it fit the other one? :confused:

Thanks.

// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
client.stop();
}

That is NOT what that code does!

How is the router connected to the Arduino? Resetting the router because the Arduino does something stupid is the wrong solution 99.999999999% of the time (that's NOT an Arduino double, so the number of digits IS correct).

plus having it store a website where it shows temp off the room.

The Arduino doesn't "store a website". If it is a server, it responds to GET requests. One of those GET request responses MIGHT be a stream of data that a web browser can comprehend.

If it is a client, it MAKES GET requests, as your "reset the router" code does.

Which role do you want the Arduino to play?

PaulS:

// if there are incoming bytes available

// from the server, read them and print them:
while (client.available()) {
client.stop();
}



That is NOT what that code does!

How is the router connected to the Arduino? Resetting the router because the Arduino does something stupid is the wrong solution 99.999999999% of the time (that's NOT an Arduino double, so the number of digits IS correct).

Well it's not resetting the arduino but instead resetting the router because the up time/reliability is bad.
So if i put a relay on the power cord for the router, shut it off 30sec and then back on when it lock it self. will solve the problem.

The arduino is connected with a Ethernet cable to the router.

What's the difference between client and server?

Like

EthernetClient client = server.available();
while (client.available()) {

Well it's not resetting the arduino but instead resetting the router because the up time/reliability is bad.

Do you mean the router or the ethernet shield?

sadsad:
What's the difference between client and server?

A client sends requests to a server and waits for an answer.
So it's the client who drives the communication.

A server just sits and waits for requests from clients.

As far as I can see you want to create a HTTP server and a HTTP client at the same time.

Let me make a guess:

The HTTP server is the intended use for your sketch?

And the HTTP client is just there to find out whether an Internet connection is available or not, and if the Internet is not available, you assume your router is hanging and want to reset the router with a power-off and power-on cycle?

Is this what you want?

Hi,

A client connects to a server. This is a bool that evaluates to true if the server has data available for reading to a persistent client object.

The Ethernet Server part handles http requests and servers back html or javascript syntax.

Stephen

jurs:
A client sends requests to a server and waits for an answer.
So it's the client who drives the communication.

A server just sits and waits for requests from clients.

As far as I can see you want to create a HTTP server and a HTTP client at the same time.

Let me make a guess:

The HTTP server is the intended use for your sketch?

And the HTTP client is just there to find out whether an Internet connection is available or not, and if the Internet is not available, you assume your router is hanging and want to reset the router with a power-off and power-on cycle?

Is this what you want?

Correct :slight_smile:

So i Wonder how is it possible to have Client and a server who i could graph off a temp transmitter and reset the router when is not available.

Why do you assume the router is at fault? It appears to me your client code is faulty.

Zoomkat has some code around that has a client and server on the same shield. Do a search for it, or maybe he will show up and post it here for you. :wink:

But in the mean time, this won't work. If there are characters in the rx buffer, the w5100 will not close the connection or free up the socket correctly.

// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
client.stop();
}

This is the "Perfect World" way to read the response from the server. No timeout here, so if the server stalls or connection breaks, the program will appear to freeze because the "while(client.connected())" loop becomes an endless loop.

while (client.connected()) {
  while (client.available()) {
    char ch = client.read();
    Serial.write(ch);
  }
}
client.stop();

sadsad:
Correct :slight_smile:

If nothing else helps, Google helps you out?

I have modified the Ethernet "WebServer" example sketch a bit:

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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,2,177);

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

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

boolean checkIfGoogleIsAlive()
{
  EthernetClient googleClient;
  char server[] = "www.google.com";    // name address for Google (using DNS)
  if (googleClient.connect(server, 80))
  {
    Serial.println("Google connect - OK");
    googleClient.stop();
    return true;
  }
  else
  {
    Serial.println("Google connect - FAIL");
    return false;
  }
}


unsigned long lastGoogleCheck;
void loop() {
  if (millis()-lastGoogleCheck>60000)
  {
    lastGoogleCheck=millis();
    if (!checkIfGoogleIsAlive())
    {
      Serial.println("OMG, I'm lost! Google is DEAD!");
    }
  }
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(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
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
  client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.println("
");       
          }
          client.println("</html>");
          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);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

The function "checkIfGoogleIsAlive()" has been added and included in the loop.

Please adjust the ip of your server accordingly to your home network settings.
The interval is currently set to 60 seconds checking if Google is still on the Internet.
But I think you can set the interval to a higher value.

At least, you will be one of the first to know, when Google is no longer available on the Internet: Your router will then start with an endless loop of power-off and power-on cycles.

BTW: The "connect()" timeout time is around 45 seconds or so. So if you pull out the cable from your Internet connection, be prepared that the runtime of the "checkIfGoogleIsAlive()" function may be up to 45 seconds if things are going wrong with Google.

Nice, jurs! Make a connection, don't send a request, then close the connection. That way nothing ends up in the rx buffer. I didn't think of that.

jurs:
The "connect()" timeout time is around 45 seconds or so.

edit: Actually it is 1.6 seconds if you are not using dns to resolve the domain to an IP. And I can reduce that to 200ms.

SurferTim:
edit: Actually it is 1.6 seconds if you are not using dns to resolve the domain to an IP. And I can reduce that to 200ms.

Yes, "connect()" is relatively quick, if everything is fine with the Internet.

But "connect()" tries/retries for 45 seconds, if the connection is down, before it times out.

jurs:
If nothing else helps, Google helps you out?

I have modified the Ethernet "WebServer" example sketch a bit:

#include <SPI.h>

#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,2,177);

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

void setup() {
// Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

// start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

boolean checkIfGoogleIsAlive()
{
  EthernetClient googleClient;
  char server[] = "www.google.com";    // name address for Google (using DNS)
  if (googleClient.connect(server, 80))
  {
    Serial.println("Google connect - OK");
    googleClient.stop();
    return true;
  }
  else
  {
    Serial.println("Google connect - FAIL");
    return false;
  }
}

unsigned long lastGoogleCheck;
void loop() {
  if (millis()-lastGoogleCheck>60000)
  {
    lastGoogleCheck=millis();
    if (!checkIfGoogleIsAlive())
    {
      Serial.println("OMG, I'm lost! Google is DEAD!");
    }
  }
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(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
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
  client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("");
          client.println("");
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.println("
");     
          }
          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);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}




The function "checkIfGoogleIsAlive()" has been added and included in the loop.

Please adjust the ip of your server accordingly to your home network settings.
The interval is currently set to 60 seconds checking if Google is still on the Internet.
But I think you can set the interval to a higher value.

At least, you will be one of the first to know, when Google is no longer available on the Internet: Your router will then start with an endless loop of power-off and power-on cycles.

BTW: The "connect()" timeout time is around 45 seconds or so. So if you pull out the cable from your Internet connection, be prepared that the runtime of the "checkIfGoogleIsAlive()" function may be up to 45 seconds if things are going wrong with Google.

Thanks i added the LED pin and Relay to it. Seems fine :slight_smile:

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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,98);


#define redLed 3
#define greenLed 5
#define yellowLed 6
#define routerPin1 8

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

void setup() {
  
pinMode(redLed, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
pinMode(routerPin1, OUTPUT);
digitalWrite(routerPin1, HIGH);


 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

boolean checkIfGoogleIsAlive()
{
  EthernetClient googleClient;
  char server[] = "www.google.com";    // name address for Google (using DNS)
  digitalWrite(yellowLed, HIGH);
  delay(1000);
  digitalWrite(yellowLed, LOW); 
  if (googleClient.connect(server, 80))
  {
    Serial.println("Google connect - OK");
    digitalWrite(greenLed, HIGH);
    digitalWrite(redLed, LOW);
    googleClient.stop();
    return true;
  }
  else
  {
    Serial.println("Google connect - FAIL");
    return false;
  }
}


unsigned long lastGoogleCheck;
void loop() {
  if (millis()-lastGoogleCheck>30000)
  {
    lastGoogleCheck=millis();
    if (!checkIfGoogleIsAlive())
    {
      Serial.println("OMG, I'm lost! Google is DEAD!");
      digitalWrite(greenLed, LOW);
      digitalWrite (redLed, HIGH);
      resetRouter();
    }
  }
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(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
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
  client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.println("
");       
          }
          client.println("</html>");
          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);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}  


void resetRouter(void) {
digitalWrite(routerPin1, LOW);
delay(lastGoogleCheck);
digitalWrite(routerPin1, HIGH);
delay(lastGoogleCheck);
}

sadsad:
Thanks i added the LED pin and Relay to it. Seems fine :slight_smile:

Please make sure that the interval between two checks is surely longer than the power-on and boot-up time of your router!

Otherwise the next check after a power-down and power-up may take place while your router is still initializing your home network and Internet and you might end up in an endless power-down/power-up loop, even if everything would be OK if you waited long enough after a power-on to establish all network connections.

jurs:
Please make sure that the interval between two checks is surely longer than the power-on and boot-up time of your router!

Otherwise the next check after a power-down and power-up may take place while your router is still initializing your home network and Internet and you might end up in an endless power-down/power-up loop, even if everything would be OK if you waited long enough after a power-on to establish all network connections.

Thanks. Did not though about that.. Wow, that had been funny :slight_smile:
This is cool

client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          // output the value of each analog input pin
          for (int pinMode = 1; pinMode < 20; pinMode++) {
            int sensorReading = digitalRead(pinMode);
            client.print("Digital output ");
            client.print(pinMode);
            client.print(" is ");
            client.print(sensorReading);
            client.println("
");

now i can see the state off the Digital Pins on the website :slight_smile:

next will be to graph it.

Well after 1 hour +- the arduino stops the loop and it do not attempt to re log if it loose connection..

sadsad:
Well after 1 hour +- the arduino stops the loop and it do not attempt to re log if it loose connection..

Do you think my additional function makes your sketch hanging?

Or do you think your application runs out of RAM memory with the additional function?

Here is a new version of my function, I changed the programming logic a bit and use the F-macro for saving RAM by sending string constants from flash instead of putting them to RAM:

boolean checkIfGoogleIsAlive()
{
  EthernetClient googleClient;
  boolean result;
  char server[] = "www.google.com";    // name address for Google (using DNS)
  Serial.print(F("Connecting to "));
  Serial.print(server);
  Serial.print(F(" ... "));
  if (googleClient.connect(server, 80) && googleClient.connected())
  {
    Serial.println(F("OK"));
    result=true;
  }
  else
  {
    Serial.println(F("FAIL"));
    result=false;
  }
  googleClient.stop();
  return result;
}

If your code contains a lot of "print" and "println" with string constants as a parameter, please use the F-macro for all print and println function calls that send a string constant.

sadsad:
Well after 1 hour +- the arduino stops the loop and it do not attempt to re log if it loose connection..

Are you accessing the server during this 1 hour? Sounds like you may be running out of sockets. Does the server quit responding or is it just the google check that fails?

@jurs: I checked your claim that it takes 45 seconds for the connection to fail if the ethernet cable is removed, and that is false. It is about 1.6 seconds.

jurs:
Do you think my additional function makes your sketch hanging?

Or do you think your application runs out of RAM memory with the additional function?

Here is a new version of my function, I changed the programming logic a bit and use the F-macro for saving RAM by sending string constants from flash instead of putting them to RAM:

boolean checkIfGoogleIsAlive()

{
  EthernetClient googleClient;
  boolean result;
  char server[] = "www.google.com";    // name address for Google (using DNS)
  Serial.print(F("Connecting to "));
  Serial.print(server);
  Serial.print(F(" ... "));
  if (googleClient.connect(server, 80) && googleClient.connected())
  {
    Serial.println(F("OK"));
    result=true;
  }
  else
  {
    Serial.println(F("FAIL"));
    result=false;
  }
  googleClient.stop();
  return result;
}




If your code contains a lot of "print" and "println" with string constants as a parameter, please use the F-macro for **all** print and println function calls that send a string constant.

Thanks

I left the computer and arduino running when i went out. When i was back around a hour later computer was in sleep mode and arduino was running. When i unplugged the Ethernet cable from arduino it when into reconnecting mode.
But it never recover after i plugged the Ethernet cable back in.

But it never recover after i plugged the Ethernet cable back in.

What does that mean? Does it give you the "OMG, I'm lost" message? Does the server quit responding? Both? Or just fails to do anything with no message at all?

edit: This section of code will end up being an incredibly long delay.

void resetRouter(void) {
digitalWrite(routerPin1, LOW);
delay(lastGoogleCheck);
digitalWrite(routerPin1, HIGH);
delay(lastGoogleCheck);
}

I am trying this. Two seconds off should reset any router.

void resetRouter(void) {
digitalWrite(routerPin1, LOW);
delay(2000);
digitalWrite(routerPin1, HIGH);
}