Possible intermittent connection loss with server

Hi,

The code below activates 5 relays via physical pins and reads 5 signals (ON/OFF) via virtual pins. Also, reads my DSL’s external IP displaying it on a LCD panel.

I have the code running on an ESP32-DEV board for months, but it hangs up at least every other week (sometimes runs fine for 2-3 weeks) - to regain control of the board I need to cycle the power. Previously, I had a similar code running on an Arduino Yun board but, because I had the same problem, I replaced the board with the ESP32 thinking of a possible defect within the Yun board.

Now that the hardware has been discarded, I can only think that the problem lays within the code. But why is it working most of the time?

Being an intermittent problem, I cannot see it with a serial connection, besides, I’m pretty sure that the sketch hangs up so, the serial connection would not help. Both, the Yun and the ESP32 boards connected to internet via WIFI.

Having said that, could it be that I’m losing the connection (sync) with the Blynk server and the code goes to la la land?

Any help is appreciated.
TIA.

//#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <WiFi.h>
#include <WiFiClient.h>
#include <TextFinder.h>
#include <BlynkSimpleEsp32.h>

#define DEBUG false
#define Serial if(DEBUG) Serial

/* used by Blynk */
BlynkTimer timer;

//DSL Blynk codes
char ssid[] = "SER12";
char pass[] = "01234";
char auth[] = "bee";

//check my IP routine
char serverName[] = "checkip.dyndns.org";
char externalIP[17];
char lastExternalIP[17];
String extIP = "";
WiFiClient client;
TextFinder finder( client);
IPAddress ip;

// hardware setup
#define relayL1 12 // GPIO 12
#define relayL2 13 // GPIO 13
#define relayL3 14 // GPIO 14
#define relayS1 15 // GPIO 15
#define relayS2 18 // GPIO 18
#define switchL1 21 // GPIO 21
#define switchL2 22 // GPIO 22
#define switchL3 23 // GPIO 23
#define switchS1 4 // GPIO 4
#define switchS2 27 // GPIO 27

//widgets displays
WidgetLED ledL1(V2);
WidgetLED ledL2(V3);
WidgetLED ledL3(V4);
WidgetLED ledS1(V5);
WidgetLED ledS2(V6);
WidgetLCD lcd(V1);

bool Connected2Blynk = false;

void setupWifi(void);
void checkConnection(void);

void setup() {
  Serial.begin(115200);
  Serial.println();
  delay(100);

  // Combined string in RAM
  //Serial.println("Show __DATE__  __TIME__  __VERSION__");
  Serial.println("Compiled: " __DATE__ ", " __TIME__ ", " __VERSION__);
  //Serial.println();
  Serial.print(F("Arduino IDE version: "));
  Serial.println(ARDUINO, DEC);
  Serial.println();

  Serial.println("Booting");
  //output lines
  pinMode(relayL1, OUTPUT);
  pinMode(relayL2, OUTPUT);
  pinMode(relayL3, OUTPUT);
  pinMode(relayS1, OUTPUT);
  pinMode(relayS2, OUTPUT);
  //input lines
  pinMode(switchL1, INPUT_PULLUP);
  pinMode(switchL2, INPUT_PULLUP);
  pinMode(switchL3, INPUT_PULLUP);
  pinMode(switchS1, INPUT_PULLUP);
  pinMode(switchS2, INPUT_PULLUP);

  //relays are active low!! turn 'em off at startup
  digitalWrite(relayL1, HIGH);
  digitalWrite(relayL2, HIGH);
  digitalWrite(relayL3, HIGH);
  digitalWrite(relayS1, HIGH);
  digitalWrite(relayS2, HIGH);

  Serial.println("Starting wifi...");
  Serial.println();

  setupWifi();

  lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "Local IP: ");
  lcd.print(0, 1, ip.toString());
  delay(500);

  timer.setInterval(3000L, switchL1Task);
  timer.setInterval(3000L, switchL2Task);
  timer.setInterval(3000L, switchL3Task);
  timer.setInterval(3000L, switchS1Task);
  timer.setInterval(3000L, switchS2Task);
  timer.setInterval(60000L, checkConnection); //60.0s check Blynk server frequency
  timer.setInterval(120000L, myTimerEvent);  //get IP from web

  Serial.println("End setup. Running...");
}

void loop() {
  //check internet connection, if not
  //no reason to proceed
  if (!Blynk.connected()) setupWifi();
  else {
    Blynk.run();
    timer.run();
  }
}

void switchL1Task() {
  bool pinState = (digitalRead(switchL1) == HIGH);

  if (pinState) {
    ledL1.off();
  }
  else {
    ledL1.on();
  }
}

void switchL2Task() {
  bool pinState = (digitalRead(switchL2) == HIGH);

  if (pinState) {
    ledL2.off();
  }
  else {
    ledL2.on();
  }
}

void switchL3Task() {
  bool pinState = (digitalRead(switchL3) == HIGH);

  if (pinState) {
    ledL3.off();
  }
  else {
    ledL3.on();
  }
}

void switchS1Task() {
  bool pinState = (digitalRead(switchS1) == HIGH);

  if (pinState) {
    ledS1.off();
  }
  else {
    ledS1.on();
  }
}

void switchS2Task() {
  bool pinState = (digitalRead(switchS2) == HIGH);

  if (pinState) {
    ledS2.off();
  }
  else {
    ledS2.on();
  }
}

void checkConnection() {
  Connected2Blynk = Blynk.connected();
  if (!Connected2Blynk) {
    Serial.println("Not connected to Blynk server");
    setupWifi();
  }
  else {
    Serial.println("Still connected to Blynk server");
  }
}

void myTimerEvent()  //borrowed code
{
  char c = ' ';

  Serial.print("connecting to... ");
  Serial.println(serverName);
  Serial.println();

  //if you get a connection, report back via serial:
  if (client.connect(serverName, 80))
  {
    Serial.println("connected");
    //make HTTP request
    client.println("GET /");
    client.println();
    delay(1000);
  }
  else
  { // you didn't get a connection to the server:
    Serial.println("connection failed");
  }

  while (client.available()) {
    char c = client.read();
    //Serial.print(c);
    if (client.available())
    { if (finder.find("IP Address: "))
      { for (char k = 0; k < 17; k++)
        { c = client.read();
          if (c != '<')
          {
            externalIP[k] = c;
          }
          else
            break;
        }
      }
    }

    client.flush();
    client.stop();

    for (char k = 0; k < 17; k++)
    { if (lastExternalIP[k] != externalIP[k]) //update ext ip variable
      {
        for (char j = 0; j < 17; j++)
        { //Serial.println(externalIP[j]);
          lastExternalIP[j] = externalIP[j]; //assign current extIP to last extIP
          extIP += lastExternalIP[j];
        }
        break;
      }
    }
    client.stop();
  }

  Serial.println();
  Serial.print("EXT IP: "); Serial.println(extIP);
  Serial.println("disconnecting from... checkip.dyndns.org");

  lcd.clear(); //Use it to clear the LCD Widget
  lcd.print(0, 0, "External IP: ");
  lcd.print(0, 1, extIP);
}

void setupWifi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);

  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }

  if (WiFi.status() == WL_CONNECTED) {
    Blynk.config(auth);
    delay(100);
    Blynk.connect();
    delay(100);

    Serial.println();
    Serial.println("WiFi connected...");
    Serial.println();
    printWifiStatus();
  }
  delay(100);
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI): ");
  Serial.print(rssi);
  Serial.println(" dBm");
  Serial.println();
}