Mqtt message to large - no error code? ESP32

Hey

Situation:
I'm learning MQTT with ESP32. I've visited the Assistant | ArduinoJson 6 and used the Assistent. I'm sending a JSON via Nodered to my ESP32. I inject the message manuelly just for training purpose. The JSON is valid and also the Assistant gives green light.

Szenario 1: I send 5 News via MQTT from Nodered - but ESP doesn't get a MQTT Message? NO Error code nothing

Szenario 2: I send only 2 News via MQTT - Everything works fine!

Has MQTT a limit in characters/filesize?

JSON:

{
  "itnews1": "LinkedIn Heimliches Experiment an 20 Millionen Nutzern",
  "itnews2": "Eclipse-Umfrage Community wartet auf Jakarta EE 10 und schnelleren Support",
  "itnews3": "Twitter patzt bei Passwort-Reset-Funktion",
  "itnews4": "Update fuer Audacity Echte Konkurrenz zu kommerzieller Audio-Software",
  "itnews5": "heise-Angebot iX-Workshop OWASP Top 10  Webanwendungen effektiv absichern",
  "itnews6": "Proteste im Iran Starlink angeblich aktiviert viele Hindernisse verbleiben",
  "itnews7": "Neuer Mac Pro wohl erst im kommenden Jahr  plus MacBook Air 15 und HomePod 2",
  "itnews8": "Chips aus Europa Intel-Werk soll in Norditalien entstehen",
  "itnews9": "Angebliche Hacktivisten von russischem Geheimdienst gelenkt",
  "itnews10": "heise-Angebot Security-Workshop Bedrohungsmodellierung fuer mobile Apps letzter Termin 2022"
}

How I get the Json: Implementation from Arduino JSON Assistant

void callback(char *topic, byte *message, unsigned int length)
{
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);

  String messageTemp;

  for (int i = 0; i < length; i++)
  {
    // Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  if (String(topic) == "news")
  {
    StaticJsonDocument<1536> doc;

DeserializationError error = deserializeJson(doc, input);

if (error) {
  Serial.print("deserializeJson() failed: ");
  Serial.println(error.c_str());
  return;
}

const char* itnews1 = doc["itnews1"]; // "LinkedIn Heimliches Experiment an 20 Millionen Nutzern"
const char* itnews2 = doc["itnews2"]; // "Eclipse-Umfrage Community wartet auf Jakarta EE 10 und ...
const char* itnews3 = doc["itnews3"]; // "Twitter patzt bei Passwort-Reset-Funktion"
const char* itnews4 = doc["itnews4"]; // "Update fuer Audacity Echte Konkurrenz zu kommerzieller ...
const char* itnews5 = doc["itnews5"]; // "heise-Angebot iX-Workshop OWASP Top 10  Webanwendungen ...
const char* itnews6 = doc["itnews6"]; // "Proteste im Iran Starlink angeblich aktiviert viele ...
const char* itnews7 = doc["itnews7"]; // "Neuer Mac Pro wohl erst im kommenden Jahr  plus MacBook Air 15 ...
const char* itnews8 = doc["itnews8"]; // "Chips aus Europa Intel-Werk soll in Norditalien entstehen"
const char* itnews9 = doc["itnews9"]; // "Angebliche Hacktivisten von russischem Geheimdienst gelenkt"
const char* itnews10 = doc["itnews10"]; // "heise-Angebot Security-Workshop Bedrohungsmodellierung fuer ...


  }
}

Thanks for your help

Yes, but it is 256 MB if I remember correctly, so that is not your problem

StaticJsonDocument<1536> doc;

What does this statement do ?

1 Like

I'm used the output from the Arduino Json Assistant. By giving the Assistant my JSON I get this output! I also tried StaticJsonDocument<2048> doc; - same results

message_size_limit limit

This option sets the maximum publish payload size that the broker will allow. Received messages that exceed this size will not be accepted by the broker. This means that the message will not be forwarded on to subscribing clients, but the QoS flow will be completed for QoS 1 or QoS 2 messages. MQTT v5 clients using QoS 1 or QoS 2 will receive a PUBACK or PUBREC with the "implementation specific error" reason code.

The default value is 0, which means that all valid MQTT messages are accepted. MQTT imposes a maximum payload size of 268435455 bytes.

This option applies globally.

Reloaded on reload signal.

1 Like

Thanks for the reply... but I think I'm not exceeding the limit from mosquitto

Were you able to come up with an answer for post#2?

1 Like

nope - note really

The MQTT Message is recieved, when I subscribe via linux mosquitto client to the topic

Question regarding the Callback:

void callback(char* topic, byte* payload, unsigned int length)

Does the byte* mean, that I only can recieve 256 charakters???

No.

1 Like

New Try - without the JSON processing - just MQTT recieving

When I subscribe with linux to the topic I will get the message - with my ESP32 not :frowning:

When I'm changing the Json with only 2 elements - the ESP32 also get`s the messge

#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include "credentials.h"

const char *mqtt_server = "myip";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

unsigned long previousMillis = 0;

void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT

  // If a message is received on the topic esp32/output, you check if the message is either "on" or "off". 
  // Changes the output state according to the message
  if (String(topic) == "itnews2") {

      Serial.println("itnews2");
      
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP32222client")) {
      Serial.println("connected");
      // Subscribe
      client.subscribe("itnews2");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void connectAP()
{

  Serial.println("Connecting to WiFi..");
  WiFi.begin(ssid, password);

  int cnt = 0;
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.print(".");
    cnt++;

    if (cnt > 20)
      break;
  }
  Serial.println(WiFi.localIP());
}

void setup()
{
  Serial.begin(115200);
  connectAP();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop()
{

   if (!client.connected()) {
    reconnect();
  }
  client.loop();

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= 10000)
  {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // client.publish("humValues", String(hum).c_str());
  }
}

MY Json

{"itnews1":"iOS 161 Neuer Schalter soll Wartezeiten beim Starten neuer Apps reduzieren","itnews2":"Intel-Chef verbreitet Zuversicht Fertigungstechnik CPUs und GPUs auf dem Weg","itnews3":"AirPods Pro 2 Keine Verbesserung bei Reparierbarkeit","itnews4":"Digitaler Zwilling Eclipse Ditto 3 spart Ressourcen und passt den Suchindex an","itnews5":"T-Systems betreibt Validator-Knoten fuer Ethereum und steigt bei Staking-DAO ein"}

I also tried to send this json from Linux and not directly from nodered - same result

Have you tried

void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
//  Serial.print(topic);
//  Serial.print(". Message: ");
//  String messageTemp;
  
 // for (int i = 0; i < length; i++) {
  //  Serial.print((char)message[i]);
  //  messageTemp += (char)message[i];
  //}
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT

  // If a message is received on the topic esp32/output, you check if the message is either "on" or "off". 
  // Changes the output state according to the message
 // if (String(topic) == "itnews2") {

  //    Serial.println("itnews2");
      
 // }
}

Dots it print each time a message is sent that it has received a message?

1 Like

Thanks for the idea.
I've gave it a try - same thing. Short message I got a message - longer message nothing. Linux Subscription got all messages...

I've already tried another ESP32... any other ideas what I can try?

The code from post#10 should be only printing "Message arrived on topic:". If your code is printing other things then you did not try the code from post#10. Post the code you tried.

post a screen shot of the messages you are getting.

1 Like

esp32 code

#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include "credentials.h"

const char *mqtt_server = "myip";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

unsigned long previousMillis = 0;

void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP32client")) {
      Serial.println("connected");
      // Subscribe
      client.subscribe("itnews2");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void connectAP()
{

  Serial.println("Connecting to WiFi..");
  WiFi.begin(ssid, password);

  int cnt = 0;
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.print(".");
    cnt++;

    if (cnt > 20)
      break;
  }
  Serial.println(WiFi.localIP());
}

void setup()
{
  Serial.begin(115200);
  connectAP();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop()
{

   if (!client.connected()) {
    reconnect();
  }
  client.loop();

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= 10000)
  {
    previousMillis = currentMillis;
    //nothing
  }
}

sending json via mosquitto_pub which DOESNT recieved

mosquitto_pub -h myip -t itnews2 -m '{"itnews1":"iOS 161 Neuer Schalter soll Wartezeiten beim Starten neuer Apps reduzieren","itnews2":"Intel-Chef verbreitet Zuversicht Fertigungstechnik CPUs und GPUs auf dem Weg","itnews3":"AirPods Pro 2 Keine Verbesserung bei Reparierbarkeit","itnews4":"Digitaler Zwilling Eclipse Ditto 3 spart Ressourcen und passt den Suchindex an","itnews5":"T-Systems betreibt Validator-Knoten fuer Ethereum und steigt bei Staking-DAO ein"}'

sending json via mosquitto_pub which is RECIEVED

mosquitto_pub -h myip -t itnews2 -m '{"itnews1":"iOS 161 Neuer Schalter soll Wartezeiten beim Starten neuer Apps reduzieren","itnews2":"Intel-Chef verbreitet Zuversicht Fertigungstechnik CPUs und GPUs auf dem Weg"}'

Screenshot Serial Monitor
image

Thank you for your help

ps.: Only one "Message arrived on topic" but I've send two messages

The problem could be client loop is not running fast enough to get the 2nd message.

The problem could be WiFi has disconnected between messages.

You do not check for a valid WiFi connection before running client loop. Assuming WiFi is connected is not a good thing.

Here is how I do a client loop() with an ESP32 using freeRTOS.

void MQTTkeepalive( void *pvParameters )
{
  sema_MQTT_KeepAlive   = xSemaphoreCreateBinary();
  xSemaphoreGive( sema_MQTT_KeepAlive ); // found keep alive can mess with a publish, stop keep alive during publish
  MQTTclient.setKeepAlive( 90 ); // setting keep alive to 90 seconds makes for a very reliable connection, must be set before the 1st connection is made.
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 250; //delay for ms
  for (;;)
  {
    //check for a is-connected and if the WiFi 'thinks' its connected, found checking on both is more realible than just a single check
    if ( (wifiClient.connected()) && (WiFi.status() == WL_CONNECTED) )
    {
      xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY ); // whiles MQTTlient.loop() is running no other mqtt operations should be in process
      MQTTclient.loop();
      xSemaphoreGive( sema_MQTT_KeepAlive );
    }
    else {
      log_i( "MQTT keep alive found MQTT status % s WiFi status % s", String(wifiClient.connected()), String(WiFi.status()) );
      if ( !(wifiClient.connected()) || !(WiFi.status() == WL_CONNECTED) )
      {
        connectToWiFi();
      }
      connectToMQTT();
    }
    //log_i( " high watermark % d",  uxTaskGetStackHighWaterMark( NULL ) );
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
  }
  vTaskDelete ( NULL );
}
////

1 Like

Thank you very much for your code. Also this try doesn't lead to success...
Also when I send immediatly two messages (different length) the short one will arrive.

I've tried now an ESP8266 - same results!

Have you tried verbose mode on the MQTT server? Might give you some clues.

1 Like

Good idea...

I've tried now a mosquitto broker on linux and raspi. Same thing
Verbose shows me the content from the message....

I've now switched to the Library: AsyncMqttClient by Marvin ROGER
and now everthing works fine

Thanks for you help...

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