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 ...
}
}
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
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.
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
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
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?
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.
#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
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 );
}
////
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.