Jump to content

IPDL - 14: Temperature Publishing Using MQTT / RESTful APIs

From cognifront

ESP32 DHT11 MQTT Temperature Publishing

Objective

To develop a basic IoT system in which an ESP32 reads ambient temperature and humidity from a DHT11 sensor and publishes the sensor data to an MQTT broker over Wi-Fi.

The experiment uses the public Eclipse Mosquitto MQTT broker test.mosquitto.org. The ESP32 publishes the sensor readings to a specific MQTT topic, and a computer can receive the published data using the Mosquitto subscriber command-line tool.

The same MQTT-based system can be extended to publish data from other sensors supported by the ESP32.

What is MQTT?

MQTT (Message Queuing Telemetry Transport) is a lightweight messaging protocol commonly used in IoT systems for exchanging data between devices over a network.

MQTT uses a publish-subscribe model.

In this model:

  • The publisher sends data to an MQTT topic.
  • The broker receives the published data.
  • The subscriber subscribes to a topic and receives the messages published to that topic.

In this experiment:

  • ESP32 = MQTT Publisher
  • DHT11 = Temperature and humidity sensor
  • Mosquitto broker = MQTT Broker
  • Laptop/PC = MQTT Subscriber
  • Wi-Fi/Internet = Network

The ESP32 reads the DHT11 sensor and publishes the readings to the MQTT broker. A computer connected to the Internet can subscribe to the same MQTT topic and receive the sensor data.

The basic operation is:

ESP32 → MQTT Broker → MQTT Subscriber

MQTT is particularly useful in IoT applications because the publisher and subscriber do not need to communicate directly with each other. The MQTT broker manages the exchange of messages.

Working of MQTT Protocol
Working of MQTT Protocol

What is Eclipse Mosquitto?

Eclipse Mosquitto is an open-source MQTT broker and MQTT client software developed as part of the Eclipse Foundation projects.

Mosquitto supports MQTT communication and provides command-line utilities that can be used to publish and subscribe to MQTT topics.

Two useful command-line programs are:

  • mosquitto_pub – publishes a message to an MQTT broker.
  • mosquitto_sub – subscribes to an MQTT topic and displays received messages.

In this experiment, mosquitto_sub is used on the PC to receive the temperature and humidity data published by the ESP32.

The experiment uses the public MQTT broker:

test.mosquitto.org

The MQTT port used in this experiment is:

1883

Port 1883 is used for standard MQTT communication without TLS encryption. The public test broker is intended for experimentation and testing. Do not publish sensitive or private information to a public MQTT broker.

MQTT Topic

An MQTT topic is a named channel through which MQTT messages are published and received.

The ESP32 in this experiment publishes data to:

cognifront/esp32/temperature/dht11

The PC subscribes to exactly the same topic.

The topic can be organized hierarchically using forward slashes. This makes it possible to create separate topics for different devices and sensors.

For example:

cognifront/esp32/temperature/dht11
cognifront/esp32/temperature/esp32_01
cognifront/esp32/humidity/dht11

When using a public MQTT broker, it is recommended to use a sufficiently unique topic so that messages from other users do not interfere with the experiment.

How Will It Work?

The ESP32 first connects to a Wi-Fi network using the configured Wi-Fi credentials.

After the Wi-Fi connection is established, the ESP32 configures the MQTT server as:

MQTT Broker : test.mosquitto.org
MQTT Port   : 1883

The ESP32 then establishes an MQTT connection with the broker.

Once connected, the ESP32 reads:

  • Ambient temperature from the DHT11.
  • Relative humidity from the DHT11.

The readings are converted into a JSON formatted message:

{"temperature":28.50,"humidity":62.00}

The message is then published to:

cognifront/esp32/temperature/dht11

A computer running the Mosquitto subscriber can subscribe to this topic and display the received messages.

The complete communication process is:

DHT11 → ESP32 → Wi-Fi → MQTT Broker → PC

The ESP32 publishes the sensor data every 5 seconds.

Hardware Requirements

  • ESP32 development board
  • DHT11 temperature and humidity sensor
  • USB cable
  • Wi-Fi network
  • Computer with Internet connection

DHT11 Connections

The DHT11 can be connected to the ESP32 as follows:

DHT11 Pin ESP32
VCC 3.3V
DATA GPIO 4
GND GND

If a DHT11 sensor module is used, the module generally includes the required pull-up resistor.

Software Requirements

The following software is required:

  • Arduino IDE
  • ESP32 board package for Arduino IDE
  • DHT sensor library
  • Adafruit Unified Sensor library
  • PubSubClient library
  • Eclipse Mosquitto command-line tools

The ESP32 uses the PubSubClient library for MQTT communication.

Installing the Required Arduino Libraries

Open Arduino IDE.

Go to:

Sketch → Include Library → Manage Libraries

Search for and install:

DHT sensor library
Adafruit Unified Sensor
PubSubClient

The Wi-Fi library is provided by the ESP32 Arduino board package and does not need to be installed separately.

Installing Eclipse Mosquitto on Windows

Eclipse Mosquitto provides MQTT broker and client software for Windows.

Download the Windows installer from the official Mosquitto website:

Eclipse Mosquitto Downloads

Download the Windows installer and run the installation program.

During installation, install the Mosquitto components including the command-line client utilities.

After installation, Mosquitto is commonly installed in:

C:\Program Files\mosquitto

The directory should contain programs such as:

mosquitto.exe
mosquitto_pub.exe
mosquitto_sub.exe

For this experiment, a local Mosquitto broker does not need to be started because the ESP32 is using the public broker test.mosquitto.org.

The mosquitto_sub program is only being used as an MQTT client to receive the ESP32 messages.

Checking the Mosquitto Installation

Open Command Prompt.

Move to the Mosquitto installation directory:

cd "C:\Program Files\mosquitto"

Check the subscriber program:

mosquitto_sub --help

If the installation is successful, the command displays the available options for mosquitto_sub.

ESP32 MQTT Publisher

The ESP32 program performs the following tasks:

  1. Connects the ESP32 to Wi-Fi.
  2. Configures the MQTT broker.
  3. Connects to the MQTT broker.
  4. Reads temperature and humidity from the DHT11.
  5. Creates a JSON formatted sensor message.
  6. Publishes the message to the MQTT topic.
  7. Reconnects to the MQTT broker if the connection is lost.
  8. Repeats the process every 5 seconds.

ESP32 Code

Put the following program into the ESP32 using Arduino IDE.

/*
  ESP32 + DHT11 + MQTT : Ambient Temperature Publishing

  MQTT Broker : test.mosquitto.org
  MQTT Port   : 1883
  MQTT Topic  : cognifront/esp32/temperature/dht11
*/

#include <WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"

// Replace the credentials of your WIFI here
const char* WIFI_SSID = "YOUR_WIFI_NAME";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";

// MQTT Server details
const char* MQTT_SERVER = "test.mosquitto.org";
const int MQTT_PORT = 1883;

const char* MQTT_TOPIC =
  "cognifront/esp32/temperature/dht11";

#define DHT_PIN 4
#define DHT_TYPE DHT11

DHT dht(DHT_PIN, DHT_TYPE);

WiFiClient espClient;
PubSubClient mqttClient(espClient);

// Publish every 5 seconds
unsigned long lastPublish = 0;
const unsigned long publishInterval = 5000;

void connectWiFi()
{
  Serial.println();
  Serial.print("Connecting to Wi-Fi");

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.println("Wi-Fi connected!");

  Serial.print("ESP32 IP Address: ");
  Serial.println(WiFi.localIP());
}

void connectMQTT()
{
  while (!mqttClient.connected())
  {
    Serial.println();
    Serial.print("Connecting to MQTT broker...");

    // Create unique MQTT client ID
    String clientID = "ESP32-DHT11-";
    clientID += String((uint32_t)ESP.getEfuseMac(), HEX);

    if (mqttClient.connect(clientID.c_str()))
    {
      Serial.println("CONNECTED!");

      Serial.print("MQTT Broker: ");
      Serial.println(MQTT_SERVER);

      Serial.print("MQTT Topic: ");
      Serial.println(MQTT_TOPIC);
    }
    else
    {
      Serial.print("FAILED, MQTT state = ");
      Serial.println(mqttClient.state());

      Serial.println("Retrying in 5 seconds...");

      delay(5000);
    }
  }
}

void setup()
{
  Serial.begin(115200);
  delay(1000);

  Serial.println();
  Serial.println("========================================");
  Serial.println(" ESP32 DHT11 MQTT Temperature Monitor");
  Serial.println("========================================");

  dht.begin();
  connectWiFi();

  // Configure MQTT
  mqttClient.setServer(MQTT_SERVER, MQTT_PORT);

  // Connect MQTT
  connectMQTT();
}

void loop()
{
  // Reconnect if MQTT connection is lost
  if (!mqttClient.connected())
  {
    connectMQTT();
  }

  mqttClient.loop();

  // Publish every 5 seconds
  if (millis() - lastPublish >= publishInterval)
  {
    lastPublish = millis();
    float temperature = dht.readTemperature();
    float humidity = dht.readHumidity();

    if (isnan(temperature) || isnan(humidity))
    {
      Serial.println("ERROR: Failed to read DHT11!");
      return;
    }

    char payload[100];
    snprintf(
      payload,
      sizeof(payload),
      "{\"temperature\":%.2f,\"humidity\":%.2f}",
      temperature,
      humidity
    );

    // Publish to MQTT broker
    bool success = mqttClient.publish(
      MQTT_TOPIC,
      payload
    );

    Serial.println();
    Serial.println("----------------------------------------");

    Serial.print("Temperature : ");
    Serial.print(temperature);
    Serial.println(" °C");

    Serial.print("Humidity    : ");
    Serial.print(humidity);
    Serial.println(" %");

    Serial.print("Topic       : ");
    Serial.println(MQTT_TOPIC);

    Serial.print("Data        : ");
    Serial.println(payload);

    if (success)
    {
      Serial.println("MQTT Publish: SUCCESS");
    }
    else
    {
      Serial.println("MQTT Publish: FAILED");
    }
    Serial.println("----------------------------------------");
  }
}

ESP32 Code Explanation

Including the Libraries

The program uses three libraries.

#include <WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"

The WiFi library provides Wi-Fi connectivity for the ESP32.

The PubSubClient library provides MQTT client functionality.

The DHT library is used to communicate with the DHT11 sensor.

Wi-Fi Configuration

The Wi-Fi network name and password are stored in:

const char* WIFI_SSID = "YOUR_WIFI_NAME";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";

Replace these values with the credentials of the Wi-Fi network that the ESP32 will use.

MQTT Configuration

The MQTT broker is configured using:

const char* MQTT_SERVER = "test.mosquitto.org";
const int MQTT_PORT = 1883;

The MQTT topic is:

const char* MQTT_TOPIC =
  "cognifront/esp32/temperature/dht11";

The ESP32 publishes all sensor messages to this topic.

DHT11 Configuration

The DHT11 data pin is connected to GPIO 4:

#define DHT_PIN 4
#define DHT_TYPE DHT11

The DHT object is created using the selected pin and sensor type.

DHT dht(DHT_PIN, DHT_TYPE);

Wi-Fi Connection

The connectWiFi() function starts the Wi-Fi connection using WiFi.begin().

The program waits until the ESP32 is connected to the Wi-Fi network.

After connection, the ESP32 IP address is displayed using WiFi.localIP().

MQTT Connection

The connectMQTT() function establishes a connection between the ESP32 and the MQTT broker.

A unique MQTT client ID is generated using the ESP32 hardware identifier.

The MQTT connection is established using mqttClient.connect().

If the connection fails, the program displays the MQTT connection state and retries after 5 seconds.

MQTT Server Configuration

The MQTT server and port are configured using:

mqttClient.setServer(MQTT_SERVER, MQTT_PORT);

This tells the MQTT client where the MQTT broker is located.

Reading DHT11 Data

The temperature is read using:

float temperature = dht.readTemperature();

Humidity is read using:

float humidity = dht.readHumidity();

The program checks whether either reading is invalid.

If the sensor reading fails, the program displays:

ERROR: Failed to read DHT11!

Creating the MQTT Message

The temperature and humidity values are combined into a JSON formatted message.

For example:

{"temperature":28.50,"humidity":62.00}

The JSON message makes the sensor data easy to process using other IoT applications and software.

Publishing the Data

The sensor data is published using:

mqttClient.publish(MQTT_TOPIC, payload);

The MQTT broker receives the message and makes it available to clients subscribed to the same topic.

The program checks whether the message was successfully published and displays either:

MQTT Publish: SUCCESS

or:

MQTT Publish: FAILED

Publishing Interval

The program publishes sensor data every 5 seconds.

The interval is defined using:

const unsigned long publishInterval = 5000;

The value is specified in milliseconds, so 5000 milliseconds corresponds to 5 seconds.

Running the MQTT Subscriber on the PC

After uploading the ESP32 program, open the Arduino Serial Monitor.

Set the baud rate to:

115200

The ESP32 should connect to Wi-Fi and then connect to the MQTT broker.

The Serial Monitor should display information similar to:

========================================
 ESP32 DHT11 MQTT Temperature Monitor
========================================

Connecting to Wi-Fi....
Wi-Fi connected!
ESP32 IP Address: 192.168.1.10

Connecting to MQTT broker...CONNECTED!
MQTT Broker: test.mosquitto.org
MQTT Topic: cognifront/esp32/temperature/dht11

The actual IP address will depend on the Wi-Fi network.

Subscribing to the ESP32 Data Using Mosquitto

Open Command Prompt on the PC.

Move to the Mosquitto installation directory:

cd "C:\Program Files\mosquitto"

Run the following command:

mosquitto_sub -h test.mosquitto.org -p 1883 -t "cognifront/esp32/temperature/dht11" -v

The options used in this command are:

  • -h specifies the MQTT broker hostname.
  • -p specifies the MQTT port.
  • -t specifies the MQTT topic.
  • -v displays both the topic and the received message.

The subscriber will remain active and wait for messages from the MQTT broker.

When the ESP32 publishes sensor data, the PC will display the received message.

Example Output

The Mosquitto subscriber may display:

cognifront/esp32/temperature/dht11 {"temperature":28.50,"humidity":62.00}
cognifront/esp32/temperature/dht11 {"temperature":28.50,"humidity":62.00}
cognifront/esp32/temperature/dht11 {"temperature":28.60,"humidity":61.00}

The Arduino Serial Monitor will display:

----------------------------------------
Temperature : 28.50 °C
Humidity    : 62.00 %
Topic       : cognifront/esp32/temperature/dht11
Data        : {"temperature":28.50,"humidity":62.00}
MQTT Publish: SUCCESS
----------------------------------------

The ESP32 continues publishing new readings every 5 seconds. The Mosquitto subscriber displays the sensor data published by the ESP32.

MQTT Subscriber Output: Temperature and humidity data received from the ESP32
MQTT Subscriber Output: Temperature and humidity data received from the ESP32

The subscriber displays the MQTT topic along with the received sensor data.

Testing the MQTT Communication

The MQTT connection can also be tested without the ESP32 by using the Mosquitto publisher.

Open another Command Prompt and move to the Mosquitto directory:

cd "C:\Program Files\mosquitto"

Publish a test message:

mosquitto_pub -h test.mosquitto.org -p 1883 -t "cognifront/esp32/temperature/dht11" -m "{\"temperature\":28.5,\"humidity\":60}"

If the subscriber is running, it will display the test message.

This confirms that the MQTT publisher and subscriber are communicating through the public MQTT broker.

MQTT Communication Test: Test message published using the Mosquitto MQTT publisher and received by the subscriber
MQTT Communication Test: Test message published using the Mosquitto MQTT publisher and received by the subscriber

Troubleshooting

mosquitto_sub is not recognized

If Windows displays:

'mosquitto_sub' is not recognized as an internal or external command

change to the Mosquitto installation directory:

cd "C:\Program Files\mosquitto"

Then run the subscriber command again.

If required, the Mosquitto installation directory can also be added to the Windows PATH environment variable.

MQTT Connection Failed

If the ESP32 cannot connect to the MQTT broker, check:

  • The ESP32 has a working Wi-Fi connection.
  • The Wi-Fi credentials are correct.
  • The MQTT server is set to test.mosquitto.org.
  • The MQTT port is set to 1883.
  • The ESP32 has Internet access.

DHT11 Read Failed

If the Serial Monitor displays:

ERROR: Failed to read DHT11!

check:

  • DHT11 VCC connection.
  • DHT11 GND connection.
  • DHT11 DATA connection.
  • GPIO number in the program.
  • DHT11 sensor type selected in the program.

The DATA connection used in this experiment is GPIO 4.

Extending the Project

The DHT11 is used as an example sensor in this experiment.

The same MQTT architecture can be extended to other sensors supported by the ESP32.

For example, additional topics can be created for:

cognifront/esp32/light/ldr
cognifront/esp32/temperature/dht11
cognifront/esp32/airquality/sensor

Additional ESP32 boards can also publish data to separate topics.

For example:

cognifront/esp32/01/temperature
cognifront/esp32/02/temperature
cognifront/esp32/03/temperature

This allows multiple ESP32 devices to publish their sensor data through the same MQTT broker.

Conclusion

This experiment demonstrates how an ESP32 can measure ambient temperature and humidity using a DHT11 sensor and publish the sensor data using MQTT.

The experiment uses the public Eclipse Mosquitto MQTT broker test.mosquitto.org and the Mosquitto subscriber utility to receive the published data on a PC.

The project combines:

ESP32 + DHT11 + Wi-Fi + MQTT + Mosquitto

The MQTT publish-subscribe architecture provides a simple foundation for developing IoT systems in which multiple devices can publish and receive sensor data through an MQTT broker.