Occasional error in esp8266

Hello
Sometimes when the program is running, this error appears in Serial Monitor and esp is reset. It seems to be a memory filling problem
Thank you for your help
Program code:


//Rev 1.5
//Uptime added
//Web OTA Added
//Ni read bug fix
//The reset operation was not performed when it was turned on without a sensor fixed
//Github SelfUpdate 

#include <SoftwareSerial.h>
#include <WiFiUdp.h>
#include <ESP8266mDNS.h>
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoOTA.h>
#include <ESPAsyncTCP.h>
//#include <ESPAsyncWebServer.h>
//#include <AsyncElegantOTA.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>
#include <WiFiClientSecure.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>


const String FirmwareVer={"1.0.4"}; 
#define URL_fw_Version "https://raw.githubusercontent.com/navid-h/AirHumidityTempNode/main/bin_version.txt"
#define URL_fw_Bin "https://raw.githubusercontent.com/navid-h/AirHumidityTempNode/main/firmware.bin"
const char* host = "raw.githubusercontent.com";
const int httpsPort = 443;


#define WIFI_SSID "SSID"
#define WIFI_PASS "PASSWORD"
#define AP_SSID "ESP8266"
#define AP_PASS "magicword"
const char* ssid = WIFI_SSID;
const char* passphrase = WIFI_PASS;
const char* mqttServerName = "mqtt";
const int   mqttport = 1883;         
const char* mqttuser = "user";
const char* mqttpass = "pass";
String prefix= "topic" ;
const char* clientID = "Ang-NPK1";

IPAddress local_IP(192,168,43,10);
IPAddress gateway(192,168,43,1);
IPAddress subnet(255,255,255,0);
IPAddress primaryDNS(8,8,8,8);
IPAddress secondaryDNS(8,8,4,4);

//AsyncWebServer server(80);

WiFiClient wclient;                        
PubSubClient client(wclient);

#define RE 5
#define DE 4
#define PUB_DELAY 50


const byte ph[] = {0x02, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x38}; // Soil PH Sensor
byte ph_values[11];


const byte ni[] = {0x02, 0x03, 0x00, 0x1F, 0x00, 0x01, 0xB5, 0xFF}; // Multi Sensor: Nitrogen
const byte phos[] = {0x02, 0x03, 0x00, 0x1E, 0x00, 0x01, 0xE4, 0x3F};
const byte pot[] = {0x02, 0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xF3};
//const byte pot[] = {0x01, 0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xC0};
const byte moist[] = {0x02, 0x03, 0x00, 0x12, 0x00, 0x01, 0x24, 0x3C};
const byte temp[] = {0x02, 0x03, 0x00, 0x13, 0x00, 0x01, 0x75, 0xFC};
const byte ec[] = {0x02, 0x03, 0x00, 0x15, 0x00, 0x01, 0x95, 0xFD};

byte pot_values[11];
byte moist_values[11];
byte phos_values[11];
byte ni_values[11];
byte ec_values[11];
byte temp_values[11];

String topic = "";
String message = "";
int cnt=10;
int cnt2=60;

int i = 0;
int statusCode;
long Day=0;
int Hour =0;
int Minute=0;
int Second=0;
int HighMillis=0;
int Rollover=0;

String st;
String content;
String esid;
String epass = "";
static unsigned long timer = millis();

bool testWifi(void);
void launchWeb(void);
void setupAP(void);
ESP8266WebServer server(80);


SoftwareSerial mod;

 
void setup()
{
  Serial.begin(115200); 
  mod.begin(9600, SWSERIAL_8N1, 14, 12, false, 256);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
   EEPROM.begin(512);
   delay(10);
   Serial.println("Startup");
 //config wifi with optional settings
  
//  if(!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS))
//  {
//    Serial.println("STA Failed to configure");
//  }
  // Read eeprom for ssid and password
   Serial.println("Reading EEPROM ssid");
 
 
  for (int i = 0; i < 32; ++i)
  {
    esid += char(EEPROM.read(i));
  }
  Serial.println();
  Serial.print("SSID: ");
  Serial.println(esid);
  Serial.println("Reading EEPROM pass");
 
  
  for (int i = 32; i < 96; ++i)
  {
    epass += char(EEPROM.read(i));
  }
  Serial.print("PASS: ");
  Serial.println(epass);
 
 
  WiFi.begin(esid.c_str(), epass.c_str());
  if (testWifi())
  {
    Serial.println("Succesfully Connected!!!");
    mqttconnect();
    return;
  }
  else
  {
    Serial.println("Turning the HotSpot On");
    launchWeb();
    setupAP();// Setup HotSpot
  }
 
  Serial.println();
  Serial.println("Waiting.");
  
  while ((WiFi.status() != WL_CONNECTED))
  {
    server.handleClient();
    if (millis() - timer > 600000){
      timer = millis();
       ESP.wdtEnable(0);
    while(1);
    }
  }
  mqttconnect();


//  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
//    request->send(200, "text/plain", "Hi! I am ESP8266.");
//  });
//
//  AsyncElegantOTA.begin(&server);    // Start ElegantOTA
//  server.begin();
//  Serial.println("HTTP server started");

  Serial.println('\n');
  Serial.println("Connection established!");  
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());         //192.168.43.215

  
  
  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_FS
      type = "filesystem";
    }

    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      Serial.println("Auth Failed");
    } else if (error == OTA_BEGIN_ERROR) {
      Serial.println("Begin Failed");
    } else if (error == OTA_CONNECT_ERROR) {
      Serial.println("Connect Failed");
    } else if (error == OTA_RECEIVE_ERROR) {
      Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  
  
}
 
void loop()
{  
  Serial.println(ESP.getFreeHeap());
   if ((WiFi.status() == WL_CONNECTED))
  {
uptime(); //Runs the uptime script located below the main loop and reenters the main loop
print_Uptime();
repeatedCall();    
ESP.wdtEnable(5000);
if (!client.connected()) {
 
  reconnect();
  } else {
   ArduinoOTA.handle();
  client.loop();
 String IP = WiFi.localIP().toString() ;
client.publish(toCharArray("/angizeh/security_system/24/1/IP:"), toCharArray(String(clientID) +"/"+WiFi.localIP().toString()));
client.publish(toCharArray("/angizeh/security_system/24/1/Uptime:"), toCharArray("Uptime:"+String(Day)+":"+String(Hour)+":"+String(Minute)+":"+String(Second)));
Serial.println("IP: " +IP);

multi_sensor_ph_detect();
multi_sensor_ni_detect();
multi_sensor_phos_detect();
multi_sensor_pot_detect();
multi_sensor_moist_detect();
multi_sensor_temp_detect();
multi_sensor_ec_detect();

  }

 }
  else
  {
      Serial.println("no connection");
      checkWifi();

  }
}

  
void multi_sensor_ph_detect(){
  while (true){
    digitalWrite(DE, HIGH);
    digitalWrite(RE, HIGH);
    delay(100);
    if (mod.write(ph, sizeof(ph)) == 8)
    {
      mod.flush();
      digitalWrite(DE, LOW);
      digitalWrite(RE, LOW);
      mod.readBytes(ph_values, 7);
     // Serial.print("Multi PH Values : ");
      for (byte i = 0; i < 7; i++)
      {
      // Serial.print(ph_values[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }
    if (ph_values[0] == 0x02 && ph_values[1] == 0x03 && ph_values[2] == 0x02){
      float ph_reg3and4 = ((ph_values[3] << 8) + ph_values[4]);
      ph_reg3and4 = ph_reg3and4/100;
      if (ph_reg3and4 > -1 && ph_reg3and4 < 15){
        Serial.print("PH : "+(String)ph_reg3and4+"");
        Serial.println();
        delay(1000);
        client.publish(toCharArray("/angizeh/security_system/24/1/PH"), toCharArray(String(ph_reg3and4)));
        Serial.println("Published");
        break;
      }
    }else{
      Serial.print("PH cant measure");
    break;
    }
  }
}


void multi_sensor_phos_detect(){
  while (true){
    digitalWrite(DE, HIGH);
    digitalWrite(RE, HIGH);
    delay(100);
    if (mod.write(phos, sizeof(phos)) == 8)
    {
      mod.flush();
      digitalWrite(DE, LOW);
      digitalWrite(RE, LOW);
      mod.readBytes(phos_values, 7);
     // Serial.print("Multi PHOS Values : ");
      for (byte i = 0; i < 7; i++)
      {
       // Serial.print(phos_values[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }
    if (phos_values[0] == 0x02 && phos_values[1] == 0x03 && phos_values[2] == 0x02){
      float phos_reg3and4 = ((phos_values[3] << 8) + phos_values[4]);
      if (phos_reg3and4 > -1 && phos_reg3and4 < 1000){
        Serial.print("PHOS : "+(String)phos_reg3and4+" mg/kg");
        Serial.println();
        delay(1000);
        client.publish(toCharArray("/angizeh/security_system/24/1/PHOS"), toCharArray(String(phos_reg3and4)));
        Serial.println("Published");
        break;
      }
    }else{
      Serial.print("PHOS cant measure");
    break;
    }
  }
}

void multi_sensor_pot_detect(){
  while (true){
    digitalWrite(DE, HIGH);
    digitalWrite(RE, HIGH);
    delay(100);
    if (mod.write(pot, sizeof(pot)) == 8)
    {
      mod.flush();
      digitalWrite(DE, LOW);
      digitalWrite(RE, LOW);
      mod.readBytes(pot_values, 7);
      //Serial.print("Multi POT Values : ");
      for (byte i = 0; i < 7; i++)
      {
       // Serial.print(pot_values[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }
    if (pot_values[0] == 0x02 && pot_values[1] == 0x03 && pot_values[2] == 0x02){
      float pot_reg3and4 = ((pot_values[3] << 8) + pot_values[4]);
      if (pot_reg3and4 > -1 && pot_reg3and4 < 10000){
        Serial.print("POT : "+(String)pot_reg3and4+" mg/kg");
        Serial.println();
        delay(1000);
        client.publish(toCharArray("/angizeh/security_system/24/1/POT"), toCharArray(String(pot_reg3and4)));
        Serial.println("Published");
        break;
      }
    }else{
      Serial.print("POT cant measure");
    break;
    }
  }
}

void multi_sensor_ec_detect(){
  while (true){
    digitalWrite(DE, HIGH);
    digitalWrite(RE, HIGH);
    delay(100);
    if (mod.write(ec, sizeof(ec)) == 8)
    {
      mod.flush();
      digitalWrite(DE, LOW);
      digitalWrite(RE, LOW);
      mod.readBytes(ec_values, 7);
     // Serial.print("Multi EC Values : ");
      for (byte i = 0; i < 7; i++)
      {
      //  Serial.print(ec_values[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }
    if (ec_values[0] == 0x02 && ec_values[1] == 0x03 && ec_values[2] == 0x02){
      float ec_reg3and4 = ((ec_values[3] << 8) + ec_values[4]);
      if (ec_reg3and4 > -1 && ec_reg3and4 < 10000){
        Serial.print("EC : "+(String)ec_reg3and4+" us/cm");
        Serial.println();
        delay(1000);
        client.publish(toCharArray("/angizeh/security_system/24/1/EC"), toCharArray(String(ec_reg3and4)));
        Serial.println("Published");
        break;
      }
    }else{
      Serial.println("EC cant measure");
    break;
    }
  }
}


void multi_sensor_moist_detect(){
  while (true){
    digitalWrite(DE, HIGH);
    digitalWrite(RE, HIGH);
    delay(100);
    if (mod.write(moist, sizeof(moist)) == 8)
    {
      mod.flush();
      digitalWrite(DE, LOW);
      digitalWrite(RE, LOW);
      mod.readBytes(moist_values, 7);
      //Serial.print("Multi MOIST Values : ");
      for (byte i = 0; i < 7; i++)
      {
       // Serial.print(moist_values[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }
    if (moist_values[0] == 0x02 && moist_values[1] == 0x03 && moist_values[2] == 0x02){
      float moist_reg3and4 = ((moist_values[3] << 8) + moist_values[4]);
      moist_reg3and4 = moist_reg3and4/10;
      if (moist_reg3and4 > -1 && moist_reg3and4 < 105){
        Serial.print("MOIST : "+(String)moist_reg3and4+"%");
        Serial.println();
        delay(1000);
        client.publish(toCharArray("/angizeh/security_system/24/1/MOIST"), toCharArray(String(moist_reg3and4)));
        Serial.println("Published");
        break;
      }
    }else{
      Serial.print("MOIST cant measure");
    break;
    }
  }
}

void multi_sensor_temp_detect(){
  while (true){
    digitalWrite(DE, HIGH);
    digitalWrite(RE, HIGH);
    delay(100);
    if (mod.write(temp, sizeof(temp)) == 8)
    {
      mod.flush();
      digitalWrite(DE, LOW);
      digitalWrite(RE, LOW);
      mod.readBytes(temp_values, 7);
       //Serial.print("Multi TEMP Values : ");
      for (byte i = 0; i < 7; i++)
      {
      // Serial.print(temp_values[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }
    if (temp_values[0] == 0x02 && temp_values[1] == 0x03 && temp_values[2] == 0x02){
      float temp_reg3and4 = ((temp_values[3] << 8) + temp_values[4]);
      temp_reg3and4 = temp_reg3and4/10;
      if (temp_reg3and4 > -1 && temp_reg3and4 < 100){
        Serial.print("TEMP : "+(String)temp_reg3and4+"°C");
        Serial.println();
        delay(1000);
        client.publish(toCharArray("/angizeh/security_system/24/1/Temperature"), toCharArray(String(temp_reg3and4)));
        Serial.println("Published");
        break;
      }
    }else{
      Serial.print("TEMP cant measure");
    break;
    }
  }
}

void multi_sensor_ni_detect(){
  while (true){
    digitalWrite(DE, HIGH);
    digitalWrite(RE, HIGH);
    delay(100);
    if (mod.write(ni, sizeof(ni)) == 8)
    {
      mod.flush();
      digitalWrite(DE, LOW);
      digitalWrite(RE, LOW);
      mod.readBytes(ni_values, 7);
       //Serial.print("Multi NI Values : ");
      for (byte i = 0; i < 7; i++)
      {
       //Serial.print(ni_values[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }
    if (ni_values[0] == 0x02 && ni_values[1] == 0x03 && ni_values[2] == 0x02){
       float ni_reg3and4 =((ni_values[3] << 8) + ni_values[4]);
        Serial.print("NI : "+(String)ni_reg3and4+" mg/kg");
        Serial.println();
        delay(1000);
        client.publish(toCharArray("/angizeh/security_system/24/1/NI"), toCharArray(String(ni_reg3and4)));
        Serial.println("Published");
        break;
      
    }else{
      Serial.print("NI cant measure");
    break;
    }
  }
}


boolean reconnect() {
   while (WiFi.status() != WL_CONNECTED){
    ESP.wdtFeed();            
    ESP.wdtDisable();                     
    delay(500);
    Serial.print(".");
    delay(500);
    cnt--;
  if (client.connect(clientID, mqttuser, mqttpass, toCharArray(prefix + "/Will"), 1, true, toCharArray("Disconnected"), true)) {
    client.setCallback(onMessageArrived);
  return client.connected();
  }
   if(cnt==0){
    ESP.wdtDisable();
    #ifdef SOFT_WATCHDOG
    ESP.wdtEnable(0);
    #endif  
    while(1);
  }
  //delay(1000);

}
}



void uptime(){
  //** Making Note of an expected rollover *****//   
if(millis()>=3000000000){ 
HighMillis=1;

}
//** Making note of actual rollover **//
if(millis()<=100000&&HighMillis==1){
Rollover++;
HighMillis=0;
}

long secsUp = millis()/1000;

Second = secsUp%60;

Minute = (secsUp/60)%60;

Hour = (secsUp/(60*60))%24;

Day = (Rollover*50)+(secsUp/(60*60*24));  //First portion takes care of a rollover [around 50 days]
                       
}
void print_Uptime(){
  
  Serial.print(F("Uptime: ")); // The "F" Portion saves your SRam Space
  Serial.print(Day);
  Serial.print(F("  Days  "));
  Serial.print(Hour);
  Serial.print(F("  Hours  "));
  Serial.print(Minute);
  Serial.print(F("  Minutes  "));
  Serial.print(Second);
  Serial.println(F("  Seconds"));
}

void FirmwareUpdate()
{  
  WiFiClientSecure client;
   client.setInsecure();
  if (!client.connect(host, httpsPort)) {
    Serial.println("Connection failed");
    return;
  }
  client.print(String("GET ") + URL_fw_Version + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "User-Agent: BuildFailureDetectorESP8266\r\n" +
               "Connection: close\r\n\r\n");
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") {
      //Serial.println("Headers received");
      break;
    }
  }
  String payload = client.readStringUntil('\n');

  payload.trim();
  if(payload.equals(FirmwareVer) )
  {   
     Serial.println("Device already on latest firmware version "+FirmwareVer); 
  }
  else
  {
    Serial.println("New firmware detected");
    ESPhttpUpdate.setLedPin(LED_BUILTIN, LOW); 
    t_httpUpdate_return ret = ESPhttpUpdate.update(client, URL_fw_Bin);
        
    switch (ret) {
      case HTTP_UPDATE_FAILED:
        Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
        break;

      case HTTP_UPDATE_NO_UPDATES:
        Serial.println("HTTP_UPDATE_NO_UPDATES");
        break;

      case HTTP_UPDATE_OK:
        Serial.println("HTTP_UPDATE_OK");
        break;
    } 
  }
 }  
// will store last time LED was updated
 void repeatedCall(){
  
   static unsigned long Timer = millis();
    if (millis() - Timer > 10000) 
    {
      // save the last time you blinked the LED
      Timer = millis();
      FirmwareUpdate();
    }
 }


 bool testWifi(void)
{
  int c = 0;
  Serial.println("Waiting for Wifi to connect");
  while ( c < 20 ) {
    if (WiFi.status() == WL_CONNECTED)
    {
      return true;
    }
    delay(500);
    Serial.print("*");
    c++;
  }
  Serial.println("");
  Serial.println("Connect timed out, opening AP");
  return false;
}

void launchWeb()
{
  Serial.println("");
  if (WiFi.status() == WL_CONNECTED)
    Serial.println("WiFi connected");
  Serial.print("Local IP: ");
  Serial.println(WiFi.localIP());
  Serial.print("SoftAP IP: ");
  Serial.println(WiFi.softAPIP());
  createWebServer();
  // Start the server
  server.begin();
  Serial.println("Server started");
}
 
void setupAP(void)
{
   WiFi.mode(WIFI_AP_STA);
   // Begin WiFi
  WiFi.begin(esid.c_str(), epass.c_str());
  delay(100);
  int n = WiFi.scanNetworks();
  Serial.println("scan done");
  if (n == 0)
    Serial.println("no networks found");
  else
  {
    Serial.print(n);
    Serial.println(" networks found");
    for (int i = 0; i < n; ++i)
    {
      // Print SSID and RSSI for each network found
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");
      Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE) ? " " : "*");
      delay(10);
    }
  }
  Serial.println("");
  st = "<ol>";
  for (int i = 0; i < n; ++i)
  {
    // Print SSID and RSSI for each network found
    st += "<li>";
    st += WiFi.SSID(i);
    st += " (";
    st += WiFi.RSSI(i);
 
    st += ")";
    st += (WiFi.encryptionType(i) == ENC_TYPE_NONE) ? " " : "*";
    st += "</li>";
  }
  st += "</ol>";
  delay(100);
  WiFi.softAP(AP_SSID,AP_PASS);
  Serial.println("softap");
  launchWeb();
  Serial.println("over");
}
 
void createWebServer()
{
 {
    server.on("/", []() {
 
      IPAddress ip = WiFi.softAPIP();
      String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
      content = "<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 at ";
      content += "<form action=\"/scan\" method=\"POST\"><input type=\"submit\" value=\"scan\"></form>";
      content += ipStr;
      content += "<p>";
      content += st;
      content += "</p><form method='get' action='setting'><label>SSID: </label><input name='ssid' length=32><input name='pass' length=64><input type='submit'></form>";
      content += "</html>";
      server.send(200, "text/html", content);
    });
    server.on("/scan", []() {
      //setupAP();
      IPAddress ip = WiFi.softAPIP();
      String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
 
      content = "<!DOCTYPE HTML>\r\n<html>go back";
      server.send(200, "text/html", content);
    });
 
    server.on("/setting", []() {
      String qsid = server.arg("ssid");
      String qpass = server.arg("pass");
      if (qsid.length() > 0 && qpass.length() > 0) {
        Serial.println("clearing eeprom");
        for (int i = 0; i < 96; ++i) {
          EEPROM.write(i, 0);
        }
        Serial.println(qsid);
        Serial.println("");
        Serial.println(qpass);
        Serial.println("");
 
        Serial.println("writing eeprom ssid:");
        for (int i = 0; i < qsid.length(); ++i)
        {
          EEPROM.write(i, qsid[i]);
          Serial.print("Wrote: ");
          Serial.println(qsid[i]);
        }
        Serial.println("writing eeprom pass:");
        for (int i = 0; i < qpass.length(); ++i)
        {
          EEPROM.write(32 + i, qpass[i]);
          Serial.print("Wrote: ");
          Serial.println(qpass[i]);
        }
        EEPROM.commit();
 
        content = "{\"Success\":\"saved to eeprom... reset to boot into new wifi\"}";
        statusCode = 200;
        ESP.reset();
      } else {
        content = "{\"Error\":\"404 not found\"}";
        statusCode = 404;
        Serial.println("Sending 404");
      }
      server.sendHeader("Access-Control-Allow-Origin", "*");
      server.send(statusCode, "application/json", content);
 
    });
  } 
}

void mqttconnect(){
    Serial.print("///////////////");
  client.setServer(mqttServerName, mqttport);
  client.setCallback(onMessageArrived);

   while (!client.connected()){
    

    delay(1000);
    Serial.println("Connecting To Server ...");
    if (client.connect(clientID, mqttuser, mqttpass, toCharArray(prefix + "/Will"), 1, true, toCharArray("Bye"), true))
    {
      Serial.println("Connected To Server");
      
    }  
   
    else 
    {
      cnt--;
      Serial.print("failed with state ");
      Serial.print(client.state());
      delay(2000);
       if(cnt==0){
      ESP.wdtDisable();
      #ifdef SOFT_WATCHDOG
      ESP.wdtEnable(0);
      #endif  
      while(1);
  }
  delay(1000);
       
   }
}
}


void checkWifi (){
   while (WiFi.status() != WL_CONNECTED){
    ESP.wdtFeed();            
    ESP.wdtDisable();                     
    delay(500);
    Serial.print(".");
    delay(500);
    cnt--;
    if(cnt==0){
    ESP.wdtDisable();
    #ifdef SOFT_WATCHDOG
    ESP.wdtEnable(0);
    #endif  
    while(1);
  }
}
}

char* toCharArray(String str) {
  return &str[0];
}

void onMessageArrived(char* t, byte* m, unsigned int length) {
  topic = String(t);
  message = String((char*)m);
  message = message.substring(0, length);

  if (message == "HELLO") {
    Serial.println("Hello client");
    client.publish(toCharArray(prefix + "/server"), toCharArray("HELLO"));
    Serial.println("Hello server");
  }
}

Error:

09:50:59.376 -> User exception (panic/abort/assert)
09:50:59.376 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
09:50:59.376 -> 
09:50:59.376 -> Unhandled C++ exception: OOM
09:50:59.376 -> 
09:50:59.376 -> >>>stack>>>
09:50:59.376 -> 
09:50:59.376 -> ctx: cont
09:50:59.376 -> sp: 3ffffd00 end: 3fffffc0 offset: 0000
09:50:59.376 -> 3ffffd00:  402633fe 3fff00d8 3ffefdb4 00000000  
09:50:59.376 -> 3ffffd10:  000000fe 00000000 00000000 00000000  
09:50:59.376 -> 3ffffd20:  00000000 00000000 00000000 00000001  
09:50:59.376 -> 3ffffd30:  00007fff 00000000 c030c02c 00000000  
09:50:59.376 -> 3ffffd40:  00000000 4020832b 000005d8 4020fc96  
09:50:59.423 -> 3ffffd50:  00000000 4020832b 00000020 4020fcb5  
09:50:59.423 -> 3ffffd60:  c02ac026 c00ec004 000005d8 4020f230  
09:50:59.423 -> 3ffffd70:  c09dc09c 00000001 3fff4b24 4020832b  
09:50:59.423 -> 3ffffd80:  00000000 c00dc003 3fff000a 40207f9c  
09:50:59.423 -> 3ffffd90:  00000000 00000000 3ffffdc0 3ffe9104  
09:50:59.423 -> 3ffffda0:  00000000 3ffe9426 3fff4b24 40208791  
09:50:59.423 -> 3ffffdb0:  0000006e 3ffef91c 00000001 4020f418  
09:50:59.423 -> 3ffffdc0:  00000000 00000000 000001bb 4020fe46  
09:50:59.423 -> 3ffffdd0:  00000000 3fff690c 3fff4b24 40207786  
09:50:59.423 -> 3ffffde0:  3fff684c 00000002 00000000 3ffef808  
09:50:59.470 -> 3ffffdf0:  000001bb 3ffe9104 3fff4b24 3ffef808  
09:50:59.470 -> 3ffffe00:  000001bb 3ffe9104 3fff4b24 4020891d  
09:50:59.470 -> 3ffffe10:  40218e5c 856dc7b9 40218e5c 856dc7b9  
09:50:59.470 -> 3ffffe20:  3ffef3c8 00000001 3ffe85dc 4021773a  
09:50:59.470 -> 3ffffe30:  00000004 00000001 3fff4b24 40201d21  
09:50:59.470 -> 3ffffe40:  402189b4 00000000 00001388 4020d014  
09:50:59.470 -> 3ffffe50:  00000000 3ffef188 00000000 3fff4b24  
09:50:59.470 -> 3ffffe60:  3fff4b24 3fff4bfc 3ffe89fb 40210828  
09:50:59.470 -> 3ffffe70:  3ffe89fc 00000002 3ffe89fb 30210828  
09:50:59.470 -> 3ffffe80:  00000000 4bc6a7f0 8bc6a7ef 00ddebd1  
09:50:59.517 -> 3ffffe90:  00000000 00000000 4bc6a7f0 00000000  
09:50:59.517 -> 3ffffea0:  4020bdac 3ffe89fa 401007d1 00000000  
09:50:59.517 -> 3ffffeb0:  0000bfee 00000009 3ffef680 4020ced4  
09:50:59.517 -> 3ffffec0:  3ffef3c8 3ffef680 3ffef680 3ffef808  
09:50:59.517 -> 3ffffed0:  3ffef3c8 3ffef0e0 3ffef0e8 40201f56  
09:50:59.517 -> 3ffffee0:  3ffe9059 3ffef680 3ffef7f4 402054de  
09:50:59.517 -> 3ffffef0:  00000000 0013001f 00000000 00000000  
09:50:59.517 -> 3fffff00:  000f000f 00000000 00000000 000f000f  
09:50:59.517 -> 3fffff10:  00000000 00000000 000d000f 00000000  
09:50:59.517 -> 3fffff20:  00000000 0021002f 00000000 00000000  
09:50:59.517 -> 3fffff30:  000c000f 00000000 00000000 000b000f  
09:50:59.564 -> 3fffff40:  00000000 00000000 3a78a8c0 00000000  
09:50:59.564 -> 3fffff50:  00000000 303a656d 00000000 00000000  
09:50:59.564 -> 3fffff60:  007a1200 f2b2c0bd 00000000 303a656d  
09:50:59.564 -> 3fffff70:  00000000 00000000 0025002f 00000000  
09:50:59.564 -> 3fffff80:  00000000 00000000 00000001 401006bc  
09:50:59.564 -> 3fffff90:  3fffdad0 00000000 3ffef7f4 3ffef808  
09:50:59.564 -> 3fffffa0:  3fffdad0 00000000 3ffef7f4 4020f538  
09:50:59.564 -> 3fffffb0:  feefeffe feefeffe 3ffe85f0 401013dd  
09:50:59.564 -> <<<stack<<<
09:50:59.564 -> 

There are a few places where you could optimise and simplify your current code…

Change Strings to strings

Move things like this…

for (int i = 0; i < 32; ++i)
   {
     esid += char(EEPROM.read(i));
   }
  • into a struct{}, then, simply…
eeprom.put(struct,myaddress); and
live-struct = eeprom.get(myaddress);

There a few tricks like this that will radically simplify your code.

Things like that would make it easier to debug and modify in the future.

Hoe long does it take for this error to occur?
Maybe you have a memory leak.
There is functions that can print the size of heap and stack memory.
Find those functions (google) and make regular prints.
See if there is a trend towards no memory left...

Other reasons may be copying a string without '\0'.
You can prevent problems using strncopy.

Use of the String library can easily lead to memory leaks.

This often happens when I am testing the device. I checked the heap memory, when the program enters the void (loop), the heap memory does not decrease. This happens when the device is connected to the Internet if the data is interrupted. In the tests I did, this happens mostly when connecting to the Internet or wifi or mqtt server.

If you take a look at the issues in the library's GutHub repository, you will find many situations similar to yours.

I had similar problems with my AsyncTelegram2 library: when the WiFi client does not connect to the server for any reason (poor WiFi level, momentary absence of internet, etcetc) , sometimes the ESP8266 goes into exception and restarts. Unfortunately I have not been able to isolate the problem, but I believe that it is necessary to act at the Arduino core level in the WiFiClientSecure library.

Your issue is with the variable

String content;

as well as with the variables

String topic = "";
String message = "";

to a lesser extend.
You have declared these dynamic variables globally while you should have declared them locally to the function that uses them, assuring that they will be destroyed after use.
In fact also the variables

String esid;
String epass = "";

may as well be local (to setup() ) but since you never modify them afterwards, there is not this issue.
content in particular changes size and gets added onto a lot, and every time this happens when there is already another variable on the heap in the way, a new part of the heap will get used for storing the whole of it. The heap is used a lot by any conversion that you do with toCharArray("") which first creates a String. It is rather inefficient but will not be an issue as long as there are no global String objects that vary in size.
Basically the rule is
'Do not use global String objects, but use them only as local variables within functions'
In your case that means you should declare 'content' within every webserver callback function and remove the global declaration.

In the first step, I set variables String topic = ""; and String message = ""; I moved it to the void onMessageArrived() function. But I still have the reset problem. You know, it seems that the problem occurs when connecting to the Internet or wifi. I get this error when I connect and disconnect the internet connection several times, and when the internet connection is stable and the program is reading Void loop() codes, there is no problem. I had this problem on other devices and when connecting to the Internet.

Your problem is in the 'createWebserver()' function

void createWebServer()
{
 {
    server.on("/", []() {
      String content;
      IPAddress ip = WiFi.softAPIP();
      String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
      content = "<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 at ";
      content += "<form action=\"/scan\" method=\"POST\"><input type=\"submit\" value=\"scan\"></form>";
      content += ipStr;
      content += "<p>";
      content += st;
      content += "</p><form method='get' action='setting'><label>SSID: </label><input name='ssid' length=32><input name='pass' length=64><input type='submit'></form>";
      content += "</html>";
      server.send(200, "text/html", content);
    });
    server.on("/scan", []() {
      String content;
      //setupAP();
      IPAddress ip = WiFi.softAPIP();
      String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
 
      content = "<!DOCTYPE HTML>\r\n<html>go back";
      server.send(200, "text/html", content);
    });
 
    server.on("/setting", []() {
      String content;
      String qsid = server.arg("ssid");
      String qpass = server.arg("pass");
      if (qsid.length() > 0 && qpass.length() > 0) {
        Serial.println("clearing eeprom");
        for (int i = 0; i < 96; ++i) {
          EEPROM.write(i, 0);
        }
        Serial.println(qsid);
        Serial.println("");
        Serial.println(qpass);
        Serial.println("");
 
        Serial.println("writing eeprom ssid:");
        for (int i = 0; i < qsid.length(); ++i)
        {
          EEPROM.write(i, qsid[i]);
          Serial.print("Wrote: ");
          Serial.println(qsid[i]);
        }
        Serial.println("writing eeprom pass:");
        for (int i = 0; i < qpass.length(); ++i)
        {
          EEPROM.write(32 + i, qpass[i]);
          Serial.print("Wrote: ");
          Serial.println(qpass[i]);
        }
        EEPROM.commit();
 
        content = "{\"Success\":\"saved to eeprom... reset to boot into new wifi\"}";
        statusCode = 200;
        ESP.reset();    // when you call this nothing will be sent back to the browser afterwards
      } else {
        content = "{\"Error\":\"404 not found\"}";
        statusCode = 404;
        Serial.println("Sending 404");
      }
      server.sendHeader("Access-Control-Allow-Origin", "*");
      server.send(statusCode, "application/json", content);
 
    });
  } 
}

Try it like this (and remove 'String content;' from the global declarations)

I did with your code Deva but still the reset issue is not resolved. Code Serial.println(ESP.getFreeHeap()); I put it in all the functions so that I can monitor the memory. When I disconnect esp from wireless, after ten seconds wdt works and esp is reset. After the reset, during booting, when it does not find the new wifi, enter the line void launchWeb(void); and until the line Serial.println("Waiting."); is read. While esp is waiting for a new wifi connection, I connect the wireless. esp matches the wireless network with the ssid and pass stored in the eprom memory, and the wireless connection is established, and the program enters the void loop() line and starts working. While doing the above, after the time when wdt works until the time the wireless connection is established, the memory drops drastically.

The number you see in the program line in the images below is related to heap memory.


Well hmm i don't know. Actually exception 29 refers to a write to a prohibited part of memory.

That the heap size decreases significantly during the establishing of a connection is totally normal, but you do quite a few things in your sketch that i would never do.
First of all you disable and re-enable the wdt, but for a stable connection it is obviously better to just call yield() on a regular basis so the scheduled tasks can be executed.
There is absolutely no need for disabling the wdt or even to feed it manually.
Secondly i am wondering what the point is of this

char* toCharArray(String str) {
  return &str[0];
}

because that returns the pointer to the data part of the String object, but that data part is not null-terminated.
What is wrong with using the normal syntax for it, other than that it takes a separate declaration of the buffer on the stack first.
As long as there is a null somewhere on the heap, your method is probably ok, but you are passing those pointers as arguments to other functions. Chances are this is going to cause problems.
i use it like this

char apname[APname.length() + 1];
  APname.toCharArray(apname, APname.length() + 1);

where APname is a String, but there are other methods that work like c_str() but those should be handled with care.
In your method, i actually think that by the time the pointer gets passed to the function called, the object doesn't exist anymore

client.publish(toCharArray(prefix + "/server"), toCharArray("HELLO"));

The pointer that points to "HELLO" is pointing to a part of the heap that has already been freed, since the object that contains "HELLO", has already been destroyed. In case of a literal, you shouldn't even need the conversion to begin with. If 'publish()' takes a char * (or const char*) asn argument, you should just be able to use "HELLO"