How to publish queued mqtt messages when device comes back online

I'm using an esp32 and this library. GitHub - 256dpi/arduino-mqtt: MQTT library for Arduino

To save power, I put the esp in light sleep mode at regular intervals with a timer and touch wake up. During this time, the mqtt messages don't get published because Wi-Fi gets turned off.

I use
bool publish(const String &topic, const String &payload, bool retained, int qos);

with retained=false and QoS=1

Should that ensure that older pending messages get cached and then published once the device comes back online? That does not happen.

I'm interested to know if this is how the protocol is supposed to work or whether this is a library limitation and I'm supposed to implement offline message queuing myself.

When the ESP32 is asleep how is the ESP32 collecting thingies to be published when the ESP32 wakes?

I had to read the post twice to make sure I understand the question:
"My ESP doesn't publish when asleep"?
Do I have that right?

Then, how are you supposed to que anything when the ESP is asleep?

This is what I have:


void WiFiStationDisconnected(WiFiEvent_t event, WiFiEventInfo_t info)
{
  connectToWiFi();
}

void setup()
{
  esp_sleep_enable_timer_wakeup(5000* 1000);
  esp_sleep_enable_touchpad_wakeup();
  WiFi.onEvent(WiFiStationDisconnected, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
}

void loop()
{
  mqttClient.loop();

  if (millis() - pollAllSensorsTime > 5000)
  {
    connectToMqtt();
    pollSensorsAndPublish(); // All of them are environmental I2C sensors
    printToLcd();
    pollAllSensorsTime = millis();
    esp_light_sleep_start();
  }
}

If loop() stops during light sleep then it is not collecting data during that time. The LCD does update every 5 seconds, so it is reading the sensors. However, I receive the mqtt messages only once a while, probably because Wifi may not have reconnected in time right after a wakeup.

I guess this does not do what I want to do. I may need to use modem sleep as well, to do something like:

  • wake up in modem sleep
  • poll sensors
  • light sleep for 5 seconds, go to 1
  • disable modem sleep once every 60 seconds, publish mqtt data
  • enable modem sleep again

In any case I need a way to queue the offline messages, which was my original question and I thought that using qos=1 would do it.

No. When the ESP32 is sleeping it is NOT running the program you wrote. How do you expect loop() to run when the ESP32 is sleeping?

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/sleep_modes.html?highlight=sleep%20modes

You might be able to write a program for the ULP to read the sensors when the main processor is sleeping but, to me, your lack of understanding of what the ESP32 is doing casts doubt.

You could do this in lightsleep

  • wake up from light sleep, count wakeups
  • poll sensors, store info in a queue
  • light sleep for 5 seconds.
  • every x wakeups publish mqtt data
  • back to light sleep again

Have you heard about the OS that the ESP32 has,built-in? freeRTOS. FreeRTOS Overview - ESP32 - — ESP-IDF Programming Guide latest documentation. Look at Queues.

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