Automated router restarting

Some time ago I posted about my ISP replacing my old fiber modem, with a new one, with a build in router. A quite buggy router, even. I have been calling them a few times, and they are now monitoring the problem, because now it just completely stops, about once daily. Most of the times, just after I have left the house, so my server can’t be reached, and it can’t reach out to anything either. So now, I am going to fix a problem that should not even exist, until I get my ISP to replace my router-fiber box, with just a fiber box. Then I will use my own Mikrotik router, and hopefully everything will then run smoothly again.

Before making this, I actually had another system in place, to do the same, just with some cheap 433Mhz wireless modules instead. The problem with those modules was that the connection to them was not as stable as anyone would have hoped, and they then sometimes failed to turn the modem off, or back on again. With everything in the same unit, and with the code being a bit smarter, it will hopefully work a lot better.

The hardware I am going to use for this, is one of the Smart Sockets from ITEAD I received yesterday, by flashing it with another firmware.

In the tests I have done so far, it does exactly what I expect it to do, and hopefully it will continue to do so next time the router decides to take a break.

Here is an example of a cold boot, where the power is turned on, and the relay inside the Smart Socket is turning the router on and starts connecting, while waiting for the router to get a connection.

In earlier projects, I have been using NodeMCU, but this time I am going to try flashing the ESP8266 inside the Smart Socket with Arduino instead.

Jumping right into the code, and here it is…

// WiFi info
const char* ssid = "SSID";
const char* password = "WPAKEY";


// Startup variables
#define startDelay 120000 // Giving the router 2 minutes to start up


// Pin configuration
#define relayPin 12
#define ledPin 13


// Server to open a connection to
char serverAdr[] = "www.google.com";
#define serverPort 80
#define interval 300000 // Try to connect every 5 minutes


// Library
#include <ESP8266WiFi.h>


WiFiClient wifiClient;

unsigned long prevTime = 0;
unsigned long healthLed = 0;
unsigned long routerReset = 0;

void setup()
{
  pinMode(relayPin, OUTPUT);
  pinMode(ledPin, OUTPUT);

  // Turn the relay on
  digitalWrite(relayPin, HIGH);
  
  Serial.begin(9600);
  Serial.println("");
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(250);
    Serial.print(".");
    
    digitalWrite(ledPin, !digitalRead(ledPin)); // Rapid flashing of the led to show we are trying to connect

    if(millis() > startDelay && routerReset == 0) // Wait 120 seconds for the router to start up and hand out an ip
    {
      Serial.println("WiFi connection failed, restarting.");
      routerReset = 1;
    }

    routerResetRoutine();
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}


void loop()
{
  // WiFi connection lost while running, reset to get back to the startup routine
  if (WiFi.status() != WL_CONNECTED)
  {
    Serial.println("WiFi connection lost, restarting.");
    ESP.restart();
  }
  
  if (millis() - prevTime >= interval) // Try to contact the server when time has run out
  {
    prevTime = millis();
    httpGET();
  }

  if (millis() - healthLed >= 2000) // Slow flashing of the led to show we are connected and monitoring
  {
    healthLed = millis();
    digitalWrite(ledPin, !digitalRead(ledPin));
  }

  routerResetRoutine();
}

void httpGET()
{
  Serial.println("\nStarting connection to server.");

  Serial.print("Connection: ");  
  if (wifiClient.connect(serverAdr, serverPort))
  {
    Serial.println("OK");
    wifiClient.stop();
  }
  else
  {
    Serial.println("FAILED");
    routerReset = 1;
  }
}

void routerResetRoutine()
{
  if (routerReset == 1)
  {
    Serial.println("Switching router off");
    routerReset = millis();
    digitalWrite(relayPin, LOW);
  }

  if (millis() - routerReset >= 10000 && routerReset > 1)
  {
    Serial.println("Restarting...");
    ESP.restart();
  }
}

All that should be needed to configure to adapt this to another setup, should be the SSID and code for it.

12 comments

  • I run OpenHAB on a Raspberry Pi 2 connected to my router with a LAN cable. Sometimes the connection gets dropped and the Raspberry Pi doesnt reconnect to the router, the only way to get it to work again is to restart both the Pi and the router with a hard reset. Could this code be modified to ping the Pi at set intervals, and if there is no response it will reset them both?

    • Yes, I just updated the code so it is now even easier to change.

      To ping that, you just put it’s ip into serverAdr, and set serverPort to 8080

      • Brilliant, Thank you. Ill give that a try.

        • Ok so i gave it a try, and although this code will work well for a router which keeps going down (such as in your problem), currently its not good for another device connected to the router (such as my raspberry Pi running OpenHAB).

          The reason is because at the start of the code you are waiting for the router to start up, although in my project the router is already on and working.
          while (WiFi.status() != WL_CONNECTED)

          So what happens with me when openhab is down, the ESP starts, turns on the relay, connects to the wifi network then, cannot connect to server so it turns the relay off again

          • I don’t understand the problem. In most cases my wifi is up and running too when the code starts. All it does then is to connect, and to straight down to the loop where it starts to monitor the server.

            And what you describe is exactly what it is supposed to do too. When it goes into the loop it waits 5 minutes, then tries to connect to the server, if it can’t connect to the server, it turns the relay off, waits for 10 seconds, and restarts itself. Then the first thing it does, is to turn the relay on again.

            Update: AAAAAAAAAAAAH! Now I finally understood what you said… Making a patch for it. 😉

          • Code updated, it will now wait until “interval” has run out, then check if the server can be connected to.

  • Sorry, i think i have confused myself. To make myself clear I have taken a video of my issue. In the video the server is down, I would expect the relay to be turned on for a longer time to allow for the server to boot and start the webserver. Forgive me, I only have a basic knowledge of programming but willing to learn.
    https://youtu.be/C_I3X9TSjWo

Leave a Reply