Very deep sleep – part 4, subscribing to MQTT messages

In a previous article, I presented a deepsleep program for the ESP8266 that would publish mqtt messages when it woke up from deepsleep.

In that article I wrote that receiving MQTT messages in a deepsleep-wake cycle is possible, but that it came with some issues of its own.  In the present article lets what we need to do to receive MQTT messsages while on a deepsleep wake cycle.

First however ask yourselves if it is really a good idea to incorporate receiving MQTT messages in a deepsleep project: It will cost time and whatever you plan to regulate via MQTT will be practically null and void when the ESP goes into deepsleep.
The only reason I can come up with is  using MQTT to instruct the ESP to not go to deepsleep yet, but do a firmware update first.

Anyway, here we go. There are two hurdles to overcome:

  1. When did broker send the MQTT message?
    If your program sleeps for 3 hrs and the broker sent a message 2 hrs earlier, we need to make sure it is still there when the ESP8266 wakes up. Therefore we need to retain or persist the messages coming from the broker. Remember that when you retain a message, the broker will keep offering it on every wake up.
  2. How long do we need to wait for the messages to come in and how many messages are expected?
    Normally it is the ‘client.loop‘ instruction in void loop(){} that will gather the incoming messages, but with deepsleep we never get to the void loop(). But if we put the client.loop instruction in the setup, then it will run only once, which will likely not be enough to receive and process any incoming MQTT messages. So we need to build our own ‘loop’ in the setup.
    That loop should last long enough to process incoming messages, but still as short as possible to save battery-life.The most efficient way is to set a flag holding up the deepsleep and clear that flag when a message is received. But that means if no message received, the ESP does not go to sleep, so that’s not really an option (it can work with retained messages). That means we have to do it differently. Will get to that later.

We will make a simple MQTT command to light the LED on a Wemos board. In the verydeepsleepMQTT.ino from the previous article, go to void reconnect, find:

client.publish("home/sleep/stat/connection", "OK");

and add right under that, the following line:


Then, at the end of the program, add the following routine

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

Serial.print("Message arrived in topic: ");

for (int i = 0; i < length; i++) {

In the program find the line:


and uncomment that

In the declaration section of the program, add the instruction:


find the section ‘//Go do stuff’ and add:

pinMode(ledPin, OUTPUT); // initialize digital ledPin as an output.

then go to the setup() and find the line:


and add right under that:

if (!client.connected()) {
for(int i=0;i<10; i++)
client.loop(); //Ensure we've sent & received everything

This adds 1 sec to our wake time. You could try with less, depending on speed of yr connection and the amount of messages you expect.

Now add an LED with 560 ohm-1k seriesresistor between 3.3V and the ‘ledPin’ and send the MQTT message “home/sleep/cmd/led” with payload “ON”. The next time the ESP8266 wakes up, the LED will light up for a short time and the serial monitor -if connected- will show the message that was received.

To be fair……. this program will react to any payload, whether it is ON or OFF or anything else, as  I do not check for that, but you can easily do that yourself. My goal was just to show how to receive MQTT messages.
Also, in the loop I created, I use short (100ms) delays. I do that because it is easy to follow. In real life though it is better to avoid delays.

Full code download here. Beware. The sensor and ledPin are slightly different in that program.

Part 1 General – DeepSleep
Part 2 Http requests – DeepSleep
Part 3 MQTT publish – DeepSleep
Part 4 MQTT subscribe – DeepSleep
Part 5 ESP-NOW -DeepSleep