Nodemcu WIFi Disonnect Issue

Hello There, I am a newbie here, but i have a very unique issue which i cannot seem to resolve.

I have NodeMCU with following program loaded in it. Issue is that after certain idle time its wifi is behaving weird in a sense that i can no longer call it from browser UNTIL i ping the ip from command line, after ping it comes back alive and now i can call it from browser, again after certain time i can no longer call it from browser until i re-ping it. God know whats wrong in my program. Can some guru please guide me through to solve this issue.

Things i have already tried - using different power supplies - different nodemcu thinking its a hadware issue - but on all three kits other program works fine except this one.

Someone please help/guide.

PROGRAM:-

#include <LiquidCrystal.h>

/**********************************************************************************
    TITLE: Alexa control 4 channel Relay Module using NodeMCU or ESP32
    Click on the following links to learn more.
    YouTube Video: https://youtu.be/tIFEtHVLexw
    Related Blog : https://easyelectronicsproject.com/esp32-projects/
    by Subhajit (Tech StudyCell)

    Download the libraries:
    https://github.com/Aircoookie/Espalexa

    Preferences--> Aditional boards Manager URLs :
    https://dl.espressif.com/dl/package_esp32_index.json, http://arduino.esp8266.com/stable/package_esp8266com_index.json

    Download Board:
    For ESP8266 NodeMCU (2.5.1): https://github.com/esp8266/Arduino
    For ESP32                  : https://github.com/espressif/arduino-esp32
 **********************************************************************************/
/*
   This sketch demonstrates how to set up a simple HTTP-like server.
   The server will set a GPIO pin depending on the request
     http://server_ip/Relay01=0 will set the GPIO4 low,
     http://server_ip/Relay01=1 will set the GPIO4 high

     http://server_ip/Relay02=0 will set the GPIO0 low,
     http://server_ip/Relay02=1 will set the GPIO0 high

     http://server_ip/Relay03=0 will set the GPIO2 low,
     http://server_ip/Relay03=1 will set the GPIO2 high

     http://server_ip/Relay04=0 will set the GPIO14 low,
     http://server_ip/Relay04=1 will set the GPIO14 high

   server_ip is the IP address of the ESP8266 module, will be
   printed to Serial when the module is connected.

   TO WORK OK, WE RECOMENDED DON'T CHANGE THE CODE!!!!!!!!
   IF YOU HAVE PROBLEMS WITH THIS CODE OR NEED SUPPORT, WRITE US: mirelewifi@gmail.com
*/
/*
   SXXX 17 Aug 2022 - have combined both the above
   HIGH means relay is OFF and LOW means relay is ON - ulta hai bhai...
*/
#include <ESPAsyncWebServer.h>
#include <ArduinoJson.h>
#include <Ticker.h>
#include <UniversalTelegramBot.h>

#define ESPALEXA_ASYNC  //it is important to define this before #include <Espalexa.h>!
#include <Espalexa.h>

#ifdef ARDUINO_ARCH_ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#else
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif

Ticker ToggleNow;

// define the GPIO connected with Relays
#define AlexaRelay01 4   //D2
#define AlexaRelay02 0   //D3
#define AlexaRelay03 2   //D4
#define AlexaRelay04 14  //D5

#define WiFiStatus D0

// Initialize Telegram BOT
#define BOTtoken "XXXXXXXXXX:YYYYYYYYYYYYYYYYYYYYYYYYYYY"  // your Bot Token (Get from Botfather)
// Use @myidbot to find out the chat ID of an individual or a group
// Also note that you need to click "start" on a bot before it can
// message you
#define CHAT_ID "xxxxxxxxxx"

X509List cert(TELEGRAM_CERTIFICATE_ROOT);
WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);

int TogglePin;
int ToggleState;

//following are for telegram messaging
String STMsg = "";
boolean SendTMsg = false;

//callback functions
void ChangeState() {
  digitalWrite(TogglePin, ToggleState);
}

void firstSwitchChanged(EspalexaDevice* dev);
void secondSwitchChanged(EspalexaDevice* dev);

// WiFi Credentials
const char* ssid = "xxxx_IoT";
const char* password = "xxxxxxx";
int WifiLEDBlink = 0;
const char* PARAM_MESSAGE = "message";
boolean SendResponse = false;

// device names
String Device_1_Name = "Waterpump";
String Device_2_Name = "Waterpump System Restart";

boolean wifiConnected = false;

// These are for storing relaystates and not relaypin numbers, relay pin numbers are stored in AlexaRelay variables
int Relay01 = 0;
int Relay02 = 0;

Espalexa espalexa;
AsyncWebServer server(80);

// Set your Static IP address
IPAddress local_IP(192, 168, 150, 112);
// Set your Gateway IP address
IPAddress gateway(192, 168, 150, 1);

IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8);           // optional
IPAddress secondaryDNS(208, 67, 222, 222);  // optional

void setup() {
  Serial.begin(115200);
  client.setInsecure();
  delay(10);

  //Prepare and Initialize GPIO4,0,2,14 PINS D2,D3,D4,D5 NodeMcu
  pinMode(AlexaRelay01, OUTPUT);
  digitalWrite(AlexaRelay01, HIGH);  //HIGH means RELAY is OFF


  pinMode(AlexaRelay02, OUTPUT);
  digitalWrite(AlexaRelay02, HIGH);  //HIGH means RELAY is OFF


  pinMode(AlexaRelay03, OUTPUT);
  digitalWrite(AlexaRelay03, HIGH);  //HIGH means RELAY is OFF


  pinMode(AlexaRelay04, OUTPUT);
  digitalWrite(AlexaRelay04, HIGH);  //HIGH means RELAY is OFF

  //WiFi Status Blue Onboard LED
  pinMode(WiFiStatus, OUTPUT);

  //Initialize RelayStates to OFF
  Relay01 = HIGH;
  Relay02 = HIGH;

  // Configures static IP address
  if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
    Serial.println("WARNING....STA Failed to configure static ip 192.168.150.112..");
  }
  WiFi.setSleepMode(WIFI_NONE_SLEEP);

  // Connect to WiFi network
  Serial.println();
  Serial.print("Conecting to  ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    if (WifiLEDBlink == 1) {
      digitalWrite(WiFiStatus, HIGH);  // Turn Off OnBoard Blue LED
      WifiLEDBlink = 0;                //Toggle switch for led blink
      delay(500);
    } else if (WifiLEDBlink == 0) {
      digitalWrite(WiFiStatus, LOW);  // Turn Off OnBoard Blue LED
      WifiLEDBlink = 1;               //Toggle switch for led blink
      delay(500);
    }
    Serial.print(".");
  }
  digitalWrite(WiFiStatus, LOW);  // Turn On OnBoard Blue LED

  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address is : ");
  Serial.println(WiFi.localIP());

  //configTime(0, 0, "pool.ntp.org");      // get UTC time via NTP
  configTime(5.5 * 3600, 0, "pool.ntp.org");  //For India
  client.setTrustAnchors(&cert);              // Add root certificate for api.telegram.org

  if (WiFi.status() == WL_CONNECTED) {
    server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) {
      //request->send(200, "text/plain", "Shuk ba this is where you will return the relay states");

      // Read the first line of the request
      String req = request->url().c_str();

      // Prepare the json response
      AsyncResponseStream* response = request->beginResponseStream("application/json");
      DynamicJsonDocument json(1024);
      json["REL01"] = "" + String(Relay01) + "";
      json["REL02"] = "" + String(Relay02) + "";
      //json["REL03"] = "" + String(Relay03) + "";
      //json["REL04"] = "" + String(Relay04) + "";
      json["IP"] = WiFi.localIP().toString();
      serializeJson(json, *response);
      request->send(response);

      //For Telegram messaging
      STMsg = "REL01 = " + String(Relay01) + " REL02 = " + String(Relay02) + " System IP = " + WiFi.localIP().toString() + "; Call made from IP = " + request->client()->remoteIP().toString();
      SendTMsg = true;
      Serial.println(STMsg);
    });

    server.on("/test", HTTP_GET, [](AsyncWebServerRequest* request) {
      request->send(200, "text/plain", "This is an answer for test call made from IP = " + request->client()->remoteIP().toString() + ", System is Up and Running fine.. :)");

      //For Telegram messaging
      STMsg = "This is an answer for test call made from IP = " + request->client()->remoteIP().toString() + ", System is Up and Running fine.. :)";
      SendTMsg = true;
      Serial.println(STMsg);
    });

    // Send a GET request to <IP>/get?message=<message>
    server.on("/get", HTTP_GET, [](AsyncWebServerRequest* request) {
      String message;
      if (request->hasParam(PARAM_MESSAGE)) {
        message = request->getParam(PARAM_MESSAGE)->value();
      } else {
        message = "No message sent";
      }
      request->send(200, "text/plain", "Hello, GET: " + message);
    });

    server.onNotFound([](AsyncWebServerRequest* request) {
      if (!espalexa.handleAlexaApiCall(request))  //if you don't know the URI, ask espalexa whether it is an Alexa control request
      {
        // Read the first line of the request
        String req = request->url().c_str();

        if (req.indexOf("Relay01=0") != -1) {
          digitalWrite(AlexaRelay01, LOW);
          //We do ON and OFF for creating momentary mode
          TogglePin = AlexaRelay01;
          ToggleState = HIGH;  //HIGH means RELAY is OFF
          ToggleNow.once(2, ChangeState);
          SendResponse = true;

          //For Telegram messaging
          STMsg = "xxxxx  Bore Switched ON from IP = " + request->client()->remoteIP().toString() + " :)";
          SendTMsg = true;
          Serial.println(STMsg);
        } else if (req.indexOf("Relay02=0") != -1) {
          //We have to reverse the call because for bore control off is NC
          digitalWrite(AlexaRelay02, LOW);
          //We do ON and OFF for creating momentary mode
          TogglePin = AlexaRelay02;
          ToggleState = HIGH;  //HIGH means RELAY is OFF
          ToggleNow.once(2, ChangeState);
          SendResponse = true;
          
          //For Telegram messaging
          STMsg = "xxxxx  Bore Switched OFF from IP = " + request->client()->remoteIP().toString() + " :)";
          SendTMsg = true;
          Serial.println(STMsg);
        } else if (req.indexOf("Reboot") != -1) {
          //March 03, 2022 added code snippet to restart the module
          Serial.println("Rebooting xxxxx  Bore now... CALL From IP =  " + request->client()->remoteIP().toString());
          ESP.restart();
        } else {
          //whatever you want to do with 404s
          request->send(404, "text/plain", "Not found");
        }
        if (SendResponse) {
          AsyncResponseStream* response = request->beginResponseStream("application/json");
          DynamicJsonDocument json(1024);
          json["REL01"] = "" + String(Relay01) + "";
          json["REL02"] = "" + String(Relay02) + "";
          json["IP"] = WiFi.localIP().toString();
          serializeJson(json, *response);
          request->send(response);
          SendResponse = false;
        }
      }
    });

    // Define your devices here.
    espalexa.addDevice(Device_1_Name, firstSwitchChanged, EspalexaDeviceType::onoff);   //simplest definition, default state off
    espalexa.addDevice(Device_2_Name, secondSwitchChanged, EspalexaDeviceType::onoff);  //simplest definition, default state off

    //give espalexa a pointer to your server object so it can use your server instead of creating its own
    espalexa.begin(&server);
    Serial.println("System is Now Alexa Enabled");
    bot.sendMessage(CHAT_ID, "xxxxx Bore Control System is Now Alexa Enabled, UP and Running, System IP = "+ WiFi.localIP().toString(), "");
  }
}

void loop() {
  espalexa.loop();
  delay(1);

  if (SendTMsg) {
    //Serial.println("From void loop STMsg = " + STMsg);
    bot.sendMessage(CHAT_ID, STMsg, "");
    STMsg = "";
    SendTMsg = false;
  }
}

//our callback functions
void firstSwitchChanged(EspalexaDevice* d) {
  if (d == nullptr) return;  //this is good practice, but not required
  //Control the device
  if (d->getValue()) {
    digitalWrite(AlexaRelay01, LOW);
    //We do ON and OFF for creating momentary mode
    TogglePin = AlexaRelay01;
    ToggleState = HIGH;  //HIGH means RELAY is OFF
    ToggleNow.once(2, ChangeState);

    //For Telegram messaging
    STMsg = "xxxxx  Bore Waterpump Switched ON using Alexa. :)";
    SendTMsg = true;
    Serial.println(STMsg);

    //Serial.println("Waterpump switched on using Alexa.");

  } else {
    digitalWrite(AlexaRelay02, LOW);
    //We do ON and OFF for creating momentary mode
    TogglePin = AlexaRelay02;
    ToggleState = HIGH;  //HIGH means RELAY is OFF
    ToggleNow.once(2, ChangeState);

    //For Telegram messaging
    STMsg = "xxxxx  Bore Waterpump Switched OFF using Alexa. :)";
    SendTMsg = true;
    Serial.println(STMsg);

    //Serial.println("Waterpump switched off using Alexa.");
  }
}

void secondSwitchChanged(EspalexaDevice* d) {
  if (d == nullptr) return;  //this is good practice, but not required
  //Control the device
  if (d->getValue()) {
    Serial.println("Alexa is Rebooting xxxxx  Bore Control System now... :)");
    ESP.restart();
  } else {
    Serial.println("Alexa is Rebooting xxxxx  Bore Control System now... :)");
    ESP.restart();
  }
}

Thank you very much for your time, and any help is very highly appreciated !!

Lots of useful stuff here.
I find wifievents very relaible.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.