ESP32 MQTT onMessage Callback never called

The example sketch works (sending and subscribing to the same topic).

I did log if the wifi connection fails. And it looks like the wifi connection is lost everytime i send data to a topic that I am not explicitly subsribed to.
COM output:

Attempting to connect to SSID: dehei.local...ok!
MQTT connecting connected!
Requesting Shadow [$aws/things/chicken-door/shadow/name/door/get]: Sending test to $aws/things/chicken-door/shadow/name/door/get/accepted: 
Checking WiFiok!
MQTT connecting connected!
Sending test to $aws/things/chicken-door/shadow/name/door/get/accepted: 
Sending test to $aws/things/chicken-door/shadow/name/door/get/accepted: 
Connection lostChecking WiFiok!
MQTT connecting connected!
Sending test to $aws/things/chicken-door/shadow/name/door/get/accepted: 
Connection lostChecking WiFiok!
MQTT connecting connected!
Sending test to $aws/things/chicken-door/shadow/name/door/get/accepted: 
Connection lostChecking WiFiok!
MQTT connecting connected!
Checking WiFiok!
MQTT connecting connected!
Sending test to $aws/things/chicken-door/shadow/name/door/get/accepted: 
Checking WiFiok!
MQTT connecting connected!
Sending test to $aws/things/chicken-door/shadow/name/door/get/accepted: 
Connection lostChecking WiFiok!
MQTT connecting connected!
Checking WiFiok!
MQTT connecting connected!
Sending test to $aws/things/chicken-door/shadow/name/door/get/accepted: 
Sending test to $aws/things/chicken-door/shadow/name/door/get/accepted: 
Connection lostChecking WiFiok!
MQTT connecting connected!
Checking WiFiok!
MQTT connecting connected!
Sending test to $aws/things/chicken-door/shadow/name/door/get/accepted: 
Sending test to $aws/things/chicken-door/shadow/name/door/get/accepted: 
Connection lostChecking WiFiok!

The current code:

#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <time.h>
#define emptyString String()

#include "secrets.h"

const int MQTT_PORT = 8883;
const char AWS_IOT_UPDATE[] = "$aws/things/chicken-door/shadow/name/door/update";
const char AWS_IOT_UPDATE_DELTA[] = "$aws/things/chicken-door/shadow/name/door/update/delta";
const char AWS_IOT_GET_SHADOW[] = "$aws/things/chicken-door/shadow/name/door/get";
const char AWS_IOT_SHADOW_ACCEPTED[] = "$aws/things/chicken-door/shadow/name/door/get/accepted";

WiFiClientSecure net;
PubSubClient client(net);

unsigned long lastMillis = 0;

void messageReceived(char *topic, byte *payload, unsigned int length)
{
  Serial.print("Received [");
  Serial.print(topic);
  Serial.print("]: ");
  for (int i = 0; i < length; i++)
  {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void pubSubErr(int8_t MQTTErr)
{
  if (MQTTErr == MQTT_CONNECTION_TIMEOUT)
    Serial.print("Connection tiemout");
  else if (MQTTErr == MQTT_CONNECTION_LOST)
    Serial.print("Connection lost");
  else if (MQTTErr == MQTT_CONNECT_FAILED)
    Serial.print("Connect failed");
  else if (MQTTErr == MQTT_DISCONNECTED)
    Serial.print("Disconnected");
  else if (MQTTErr == MQTT_CONNECTED)
    Serial.print("Connected");
  else if (MQTTErr == MQTT_CONNECT_BAD_PROTOCOL)
    Serial.print("Connect bad protocol");
  else if (MQTTErr == MQTT_CONNECT_BAD_CLIENT_ID)
    Serial.print("Connect bad Client-ID");
  else if (MQTTErr == MQTT_CONNECT_UNAVAILABLE)
    Serial.print("Connect unavailable");
  else if (MQTTErr == MQTT_CONNECT_BAD_CREDENTIALS)
    Serial.print("Connect bad credentials");
  else if (MQTTErr == MQTT_CONNECT_UNAUTHORIZED)
    Serial.print("Connect unauthorized");
}

void connectToMqtt(bool nonBlocking = false)
{
  Serial.print("MQTT connecting ");
  while (!client.connected())
  {
    if (client.connect(THINGNAME))
    {
//      if (!client.subscribe(AWS_IOT_SHADOW_ACCEPTED))
//        pubSubErr(client.state());
//      if (!client.subscribe(AWS_IOT_UPDATE_DELTA))
//        pubSubErr(client.state());
      if (!client.subscribe("$aws/things/chicken-door/shadow/name/door/#"))
        pubSubErr(client.state());
      Serial.println("connected!");
    }
    else
    {
      Serial.print("failed, reason -> ");
      pubSubErr(client.state());
      if (!nonBlocking)
      {
        Serial.println(" < try again in 5 seconds");
        delay(5000);
      }
      else
      {
        Serial.println(" <");
      }
    }
    if (nonBlocking)
      break;
  }
}

void connectToWiFi(String init_str)
{
  if (init_str != emptyString)
    Serial.print(init_str);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(1000);
  }
  if (init_str != emptyString)
    Serial.println("ok!");
}

void checkWiFiThenMQTT(void)
{
  connectToWiFi("Checking WiFi");
  connectToMqtt();
}

unsigned long previousMillis = 0;
const long interval = 5000;

void checkWiFiThenMQTTNonBlocking(void)
{
  connectToWiFi(emptyString);
  if (millis() - previousMillis >= interval && !client.connected()) {
    previousMillis = millis();
    connectToMqtt(true);
  }
}

void checkWiFiThenReboot(void)
{
  connectToWiFi("Checking WiFi");
  Serial.print("Rebooting");
  ESP.restart();
}

void sendData(String value) 
{
  DynamicJsonDocument jsonBuffer(JSON_OBJECT_SIZE(3) + 100);
  JsonObject root = jsonBuffer.to<JsonObject>();
  JsonObject state = root.createNestedObject("state");
  JsonObject state_reported = state.createNestedObject("reported");
  state_reported["value"] = value;
  Serial.printf("Sending test to %s: ", AWS_IOT_SHADOW_ACCEPTED);
  //serializeJson(root, Serial);
  Serial.println();
  char shadow[measureJson(root) + 1];
  serializeJson(root, shadow, sizeof(shadow));
  if (!client.publish(AWS_IOT_SHADOW_ACCEPTED, "test", false))
    pubSubErr(client.state());
}

void getShadow(void)
{
  Serial.printf("Requesting Shadow [%s]: ", AWS_IOT_GET_SHADOW);
  if (!client.publish(AWS_IOT_GET_SHADOW, "", false))
    pubSubErr(client.state());
}

void setup()
{
  Serial.begin(115200);
  delay(5000);
  Serial.println();
  Serial.println();

  WiFi.setHostname(THINGNAME);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  connectToWiFi(String("Attempting to connect to SSID: ") + String(WIFI_SSID));

  net.setCACert(AWS_CERT_CA);
  net.setCertificate(AWS_CERT_CRT);
  net.setPrivateKey(AWS_CERT_PRIVATE);

  client.setServer(AWS_IOT_ENDPOINT, MQTT_PORT);
  client.setCallback(messageReceived);

  connectToMqtt();
  getShadow();
}

void loop()
{
  if (!client.connected())
  {
    checkWiFiThenMQTT();
  }
  else
  {
    client.loop();
    if (millis() - lastMillis > 5000)
    {
      lastMillis = millis();
      sendData("closed");
    }
  }
}
"
type or paste code here

I tested the credentials by using them in the desktop tool "MQTT Explorer". There I can publish to the topics and also receive the updates in the get/accepted topic

1 Like