Esp32 w5500 Mqtt Reconnect Problem

Good day, i am trying to send something to mqtt using esp32 and w5500 ethernet module. but I'm getting the mqtt part constantly connecting error. What do you think is the problem?

Note: I printed the debug steps to the code.

Loop of error generating code...............

Rebooting...

mqttA !client.connected() IN
CONNECT FUNC IN
MQTTkeepalive IN
MQTTkeepalive for(;;) IN
MQTTkeepalive for(;;) !net.connected() IN
setup_eth() IN
!client.connected() IN
fmqttWatchDog RUN
fmqttWatchDog for(;;) IN
!client.connected() IN
!client.connected() IN
setup_eth() OUT
MQTTkeepalive for(;;) net.connected() OUT
else connect in
CONNECT FUNC IN
!client.connected() IN
!client.connected() IN
!client.connected() IN
!client.connected() IN
!client.connected() IN
!client.connected() IN
E (11701) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (11701) task_wdt:  - IDLE0 (CPU 0)
E (11701) task_wdt: Tasks currently running:
E (11701) task_wdt: CPU 0: fparseMQTT
E (11701) task_wdt: CPU 1: loopTask
E (11701) task_wdt: Aborting.
abort() was called at PC 0x400e68eb on core 0

ELF file SHA256: 0000000000000000

Backtrace: 0x40084fe4:0x3ffbe5f0 0x40085259:0x3ffbe610 0x400e68eb:0x3ffbe630 0x40083975:0x3ffbe650 0x400d561f:0x3ffb3e50 0x400d4b5f:0x3ffb3e80 0x400d4b7a:0x3ffb3ea0 0x400d392b:0x3ffb3ec0 0x400d2939:0x3ffb3ef0 0x400d2e91:0x3ffb3f10 0x400d33cf:0x3ffb3f40 0x400d27e3:0x3ffb3f70 0x400d4024:0x3ffb3f90 0x400d40a5:0x3ffb3fd0 0x400d1546:0x3ffb4000 0x400d17db:0x3ffb4050 0x40086269:0x3ffb46f0

Rebooting..

/////////////////////////////////////////GLOBAL LİB/////////////////////////////////////

#include <Ethernet.h>
#include <ArduinoJson.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <WiFi.h>
#include <ESP32Time.h>
#include <SPI.h>

/////////////////////////////////////ESP LİB////////////////////////////////////////////

#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/event_groups.h"

//////////////////////// FREERTOS CONFİG ///////////////////////////////////////////////

#define evtDoMQTTwd          ( 1 << 1 )
EventGroupHandle_t eg;
SemaphoreHandle_t sema_MQTT_KeepAlive;
SemaphoreHandle_t sema_mqttOK;
QueueHandle_t xQ_Message;
const int     payloadSize = 300;
bool          TimeSet = false;
struct        stu_message
{
  char        payload [payloadSize] = {'\0'};
  String      topic ;
} x_message;

int mqttOK = 0;

////////////////////////DHT22 CONFİG ///////////////////////////////////////////////////

byte temp = 15;
#define DHTTYPE DHT22
DHT dht = DHT(temp, DHTTYPE);

/////////////////////////////////////Client/////////////////////////////////////////////

EthernetClient net;
PubSubClient client("xxxxxxxxxxxxxx", 1883, net);

/////////////////////////////////////MQTT Callback//////////////////////////////////////

void IRAM_ATTR mqttCallback(char* topic, byte * payload, unsigned int length)
{
  // clear locations
  memset( x_message.payload, '\0', payloadSize );
  x_message.topic = ""; //clear string buffer
  x_message.topic = topic;
  int i = 0;
  for ( i; i < length; i++)
  {
    x_message.payload[i] = ((char)payload[i]);
  }
  x_message.payload[i] = '\0';
  xQueueOverwrite( xQ_Message, (void *) &x_message );// send data to queue
}

/////////////////////////////////////Setup//////////////////////////////////////////////

void setup() {
  Serial.begin(57600);
  dht.begin();
  Ethernet.init(5);
  x_message.topic.reserve( payloadSize );
  xQ_Message  = xQueueCreate( 1, sizeof(stu_message) );
  sema_mqttOK = xSemaphoreCreateBinary();
  xSemaphoreGive( sema_mqttOK );
  eg = xEventGroupCreate();

  xTaskCreatePinnedToCore( mqttA, "fparseMQTT", 10000, NULL, 4, NULL, 0 );
  xTaskCreatePinnedToCore( fmqttWatchDog, "fmqttWatchDog", 3000, NULL, 3, NULL, 0 );
  xTaskCreatePinnedToCore( MQTTkeepalive, "MQTTkeepalive", 20000, NULL, 5, NULL, 0 );

  //client.setClient(net);
  // client.setBufferSize(256);
  //client.setServer("46.101.178.236", 1883);

}

/////////////////////////////////////WatchDog///////////////////////////////////////////

void fmqttWatchDog( void * paramater )
{
  Serial.println("fmqttWatchDog RUN");
  int UpdateImeTrigger = 86400;
  int UpdateTimeInterval = 85000;
  int maxNonMQTTresponse = 3;
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 60000;
  for (;;)
  {
    Serial.println("fmqttWatchDog for(;;) IN");
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
    xSemaphoreTake( sema_mqttOK, portMAX_DELAY ); // update mqttOK
    mqttOK++;
    xSemaphoreGive( sema_mqttOK );
    if ( mqttOK >= maxNonMQTTresponse )
    {
      Serial.println("mqttOK IN");
      vTaskDelay( 200 );
      ESP.restart();
    }
    UpdateTimeInterval++;

    if ( UpdateTimeInterval >= UpdateImeTrigger )
    {
      Serial.println("UpdateTimeInterval IN");
      TimeSet = false;
      UpdateTimeInterval = 0;
    }
  }
  Serial.println("fmqttWatchDog for(;;) OUT");
  vTaskDelete( NULL );
}

/////////////////////////////////////MQTT Connect///////////////////////////////////////

void connect() {
  Serial.println("CONNECT FUNC IN");
  client.setKeepAlive( 90 );
  String clientId = "ESP32Client-";
  clientId += String(random(0xffff), HEX);
  while (!client.connected()) {
    Serial.println("!client.connected() IN");
    client.connect(clientId.c_str(), "public", "public", NULL , 1, true, NULL );
    vTaskDelay( 250 );

  }
  Serial.println("!client.connected() OUT");
  client.setCallback( mqttCallback );
  Serial.println("\nconnected!");
}

/////////////////////////////////////MQTT PUBLISH///////////////////////////////////////

void mqttA(void * parameter) {
  Serial.println("mqttA IN");
  TickType_t xLastWakeTime    = xTaskGetTickCount();
  const TickType_t xFrequency = 1000 * 15;

  if (!client.connected()) {
    Serial.println("mqttA !client.connected() IN");
    connect();
    vTaskDelay( 250 );
  }
  Serial.println("mqttA !client.connected() OUT");
  for (;;) {
    Serial.println("mqttA for(;;) IN");
    StaticJsonBuffer<800> JSON;
    JsonObject& JSONencoder = JSON.createObject();

    JSONencoder["DEVICE = "] = WiFi.macAddress();
    JSONencoder["TEMP = "] = dht.readTemperature();
    JSONencoder["HUMD = "] = dht.readHumidity();
    JSONencoder["STATE = "] = true;
    JSONencoder["RAM = "] = esp_get_free_heap_size();
    JSONencoder["RAM2 = "] = uxTaskGetStackHighWaterMark(NULL);
    JSONencoder["RAM3 = "] = ESP.getFreeHeap();
    JSONencoder["RAM4 = "] = xPortGetFreeHeapSize();

    char JSONmessageBuffer[800];
    JSONencoder.printTo(JSONmessageBuffer, sizeof(JSONmessageBuffer));


    xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY );
    client.publish("/PUB/data", JSONmessageBuffer);

    xSemaphoreGive( sema_MQTT_KeepAlive );

    xEventGroupSetBits( eg, evtDoMQTTwd );

    // vTaskDelay(5000 / portTICK_PERIOD_MS);
  }
  Serial.println("mqttA for(;;) OUT");
  vTaskDelete ( NULL );
}

/////////////////////////////////////MQTT KeepAlive/////////////////////////////////////

void MQTTkeepalive( void *pvParameters )
{
  Serial.println("MQTTkeepalive IN");
  sema_MQTT_KeepAlive   = xSemaphoreCreateBinary();
  xSemaphoreGive( sema_MQTT_KeepAlive );
  client.setKeepAlive( 90 );
  for (;;)
  {
    Serial.println("MQTTkeepalive for(;;) IN");
    if ( (net.connected()) && (Ethernet.linkStatus() == LinkON) )
    {
      Serial.println("MQTTkeepalive for(;;) net.connected() IN");
      xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY );
      client.loop();
      xSemaphoreGive( sema_MQTT_KeepAlive );
      Serial.println("MQTTkeepalive for(;;) net.connected() OUT");
    }


    else {

      if ( !(net.connected()) || (Ethernet.linkStatus() == LinkOFF) )
      { Serial.println("MQTTkeepalive for(;;) !net.connected() IN");
        setup_eth();
      }
      Serial.println("MQTTkeepalive for(;;) net.connected() OUT");
      Serial.println("else connect in");
      connect();
    }
    vTaskDelay( 250 );
  }
  Serial.println("MQTTkeepalive for(;;) OUT");
  vTaskDelete ( NULL );
}

/////////////////////////////////////Ethernet Connect///////////////////////////////////

void setup_eth() {
  Serial.println("setup_eth() IN");
  byte mac[] = {0x9C, 0x9C, 0x1F, 0xCB, 0x14, 0x9C};

  Ethernet.init(5);
  byte TryCount = 0;
  while (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("setup_eth() Ethernet.linkStatus() == LinkOFF IN");

    Serial.println("Failed to configure Ethernet using DHCP");

    TryCount++;
    net.stop();
    Ethernet.begin(mac);
    vTaskDelay( 1000 );
    if ( TryCount == 5 )
    {
      Serial.println("ESP Restart IN");
      ESP.restart();
    }
    Serial.println("setup_eth() Ethernet.linkStatus() == LinkOFF OUT");
  }
  Serial.println("setup_eth() OUT");
}

void loop() {}

The Ethernet library isn't thread safe. So don't use the multi-threading capabilities of the ESP FreeRTOS system if you use standard Arduino libraries (most of them are not thread safe).

Do I need to run Freertos only with mqtt?

I don't know what you mean by this sentence. You shouldn't not use multiple threads (tasks) inside your sketch if you use Arduino libraries (PubSubClient and Ethernet in your case).

Just design your sketch as a standard Arduino program, so no xTaskCreatePinnedCore() calls (no other thread calls too of course).

Will compiling in esp32 framework using PlatformIO fix this issue?

No, at least not unless you replace the Arduino libraries by other thread compliant libraries. I don't know if PlatformIO also has corresponding libraries that are thread-safe.

Why do you think you need multiple threads?

I want to make a gateway for my master thesis. In order for me to analyze with artificial intelligence, it needs to work for months without any problems and data loss. In my previous software, esp32 was freezing after 1-2 days. I suspected a memory leak, my research I wanted to use freertos for a more stable gateway. Thank you for your attention.

If you have a memory leak in your code why do you think using the FreeRTOS features (especially threads) would make your sketch more reliable? Adding complexity seldom results in more stable outcomes.

Given all the buzzwords you use in the description of your master thesis, are you sure you did the right hardware selection? Don't you think a Raspberry Pi (Zero) would be a better choice?

I chose esp32 as hardware, it is not possible to change it.

Memory results of my code that I created by using standard PubSubClient and Ethernet libraries in Arduino and not using FreeRtos.
Note: There is a 12 hour difference between before and after.

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